summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_main.c11
-rw-r--r--drivers/block/loop.c4
-rw-r--r--drivers/block/nbd.c76
-rw-r--r--drivers/block/virtio_blk.c14
4 files changed, 50 insertions, 55 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index c7d530a95e53..92c60cbd04ee 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1847,7 +1847,7 @@ int drbd_send_out_of_sync(struct drbd_peer_device *peer_device, struct drbd_requ
int drbd_send(struct drbd_connection *connection, struct socket *sock,
void *buf, size_t size, unsigned msg_flags)
{
- struct kvec iov;
+ struct kvec iov = {.iov_base = buf, .iov_len = size};
struct msghdr msg;
int rv, sent = 0;
@@ -1856,15 +1856,14 @@ int drbd_send(struct drbd_connection *connection, struct socket *sock,
/* THINK if (signal_pending) return ... ? */
- iov.iov_base = buf;
- iov.iov_len = size;
-
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = msg_flags | MSG_NOSIGNAL;
+ iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iov, 1, size);
+
if (sock == connection->data.socket) {
rcu_read_lock();
connection->ko_count = rcu_dereference(connection->net_conf)->ko_count;
@@ -1872,7 +1871,7 @@ int drbd_send(struct drbd_connection *connection, struct socket *sock,
drbd_update_congested(connection);
}
do {
- rv = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+ rv = sock_sendmsg(sock, &msg);
if (rv == -EAGAIN) {
if (we_should_drop_the_connection(connection, sock))
break;
@@ -1886,8 +1885,6 @@ int drbd_send(struct drbd_connection *connection, struct socket *sock,
if (rv < 0)
break;
sent += rv;
- iov.iov_base += rv;
- iov.iov_len -= rv;
} while (sent < size);
if (sock == connection->data.socket)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 4b52a1690329..eeb1db73f44e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -501,9 +501,9 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
cmd->iocb.ki_flags = IOCB_DIRECT;
if (rw == WRITE)
- ret = file->f_op->write_iter(&cmd->iocb, &iter);
+ ret = call_write_iter(file, &cmd->iocb, &iter);
else
- ret = file->f_op->read_iter(&cmd->iocb, &iter);
+ ret = call_read_iter(file, &cmd->iocb, &iter);
if (ret != -EIOCBQUEUED)
cmd->iocb.ki_complete(&cmd->iocb, ret, 0);
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 0bf2b21a62cb..1541cb880744 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -201,13 +201,12 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
/*
* Send or receive packet.
*/
-static int sock_xmit(struct nbd_device *nbd, int index, int send, void *buf,
- int size, int msg_flags)
+static int sock_xmit(struct nbd_device *nbd, int index, int send,
+ struct iov_iter *iter, int msg_flags)
{
struct socket *sock = nbd->socks[index]->sock;
int result;
struct msghdr msg;
- struct kvec iov;
unsigned long pflags = current->flags;
if (unlikely(!sock)) {
@@ -217,11 +216,11 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send, void *buf,
return -EINVAL;
}
+ msg.msg_iter = *iter;
+
current->flags |= PF_MEMALLOC;
do {
sock->sk->sk_allocation = GFP_NOIO | __GFP_MEMALLOC;
- iov.iov_base = buf;
- iov.iov_len = size;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
@@ -229,47 +228,37 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send, void *buf,
msg.msg_flags = msg_flags | MSG_NOSIGNAL;
if (send)
- result = kernel_sendmsg(sock, &msg, &iov, 1, size);
+ result = sock_sendmsg(sock, &msg);
else
- result = kernel_recvmsg(sock, &msg, &iov, 1, size,
- msg.msg_flags);
+ result = sock_recvmsg(sock, &msg, msg.msg_flags);
if (result <= 0) {
if (result == 0)
result = -EPIPE; /* short read */
break;
}
- size -= result;
- buf += result;
- } while (size > 0);
+ } while (msg_data_left(&msg));
tsk_restore_flags(current, pflags, PF_MEMALLOC);
return result;
}
-static inline int sock_send_bvec(struct nbd_device *nbd, int index,
- struct bio_vec *bvec, int flags)
-{
- int result;
- void *kaddr = kmap(bvec->bv_page);
- result = sock_xmit(nbd, index, 1, kaddr + bvec->bv_offset,
- bvec->bv_len, flags);
- kunmap(bvec->bv_page);
- return result;
-}
-
/* always call with the tx_lock held */
static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
{
struct request *req = blk_mq_rq_from_pdu(cmd);
int result;
- struct nbd_request request;
+ struct nbd_request request = {.magic = htonl(NBD_REQUEST_MAGIC)};
+ struct kvec iov = {.iov_base = &request, .iov_len = sizeof(request)};
+ struct iov_iter from;
unsigned long size = blk_rq_bytes(req);
struct bio *bio;
u32 type;
u32 tag = blk_mq_unique_tag(req);
+ iov_iter_kvec(&from, WRITE | ITER_KVEC, &iov, 1, sizeof(request));
+
switch (req_op(req)) {
case REQ_OP_DISCARD:
type = NBD_CMD_TRIM;
@@ -294,8 +283,6 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
return -EIO;
}
- memset(&request, 0, sizeof(request));
- request.magic = htonl(NBD_REQUEST_MAGIC);
request.type = htonl(type);
if (type != NBD_CMD_FLUSH) {
request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
@@ -306,7 +293,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n",
cmd, nbdcmd_to_ascii(type),
(unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req));
- result = sock_xmit(nbd, index, 1, &request, sizeof(request),
+ result = sock_xmit(nbd, index, 1, &from,
(type == NBD_CMD_WRITE) ? MSG_MORE : 0);
if (result <= 0) {
dev_err_ratelimited(disk_to_dev(nbd->disk),
@@ -329,7 +316,9 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
dev_dbg(nbd_to_dev(nbd), "request %p: sending %d bytes data\n",
cmd, bvec.bv_len);
- result = sock_send_bvec(nbd, index, &bvec, flags);
+ iov_iter_bvec(&from, ITER_BVEC | WRITE,
+ &bvec, 1, bvec.bv_len);
+ result = sock_xmit(nbd, index, 1, &from, flags);
if (result <= 0) {
dev_err(disk_to_dev(nbd->disk),
"Send data failed (result %d)\n",
@@ -350,17 +339,6 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
return 0;
}
-static inline int sock_recv_bvec(struct nbd_device *nbd, int index,
- struct bio_vec *bvec)
-{
- int result;
- void *kaddr = kmap(bvec->bv_page);
- result = sock_xmit(nbd, index, 0, kaddr + bvec->bv_offset,
- bvec->bv_len, MSG_WAITALL);
- kunmap(bvec->bv_page);
- return result;
-}
-
/* NULL returned = something went wrong, inform userspace */
static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
{
@@ -370,9 +348,12 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
struct request *req = NULL;
u16 hwq;
u32 tag;
+ struct kvec iov = {.iov_base = &reply, .iov_len = sizeof(reply)};
+ struct iov_iter to;
reply.magic = 0;
- result = sock_xmit(nbd, index, 0, &reply, sizeof(reply), MSG_WAITALL);
+ iov_iter_kvec(&to, READ | ITER_KVEC, &iov, 1, sizeof(reply));
+ result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL);
if (result <= 0) {
if (!test_bit(NBD_DISCONNECTED, &nbd->runtime_flags) &&
!test_bit(NBD_DISCONNECT_REQUESTED, &nbd->runtime_flags))
@@ -412,7 +393,9 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
struct bio_vec bvec;
rq_for_each_segment(bvec, req, iter) {
- result = sock_recv_bvec(nbd, index, &bvec);
+ iov_iter_bvec(&to, ITER_BVEC | READ,
+ &bvec, 1, bvec.bv_len);
+ result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL);
if (result <= 0) {
dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n",
result);
@@ -641,14 +624,17 @@ static void nbd_parse_flags(struct nbd_device *nbd, struct block_device *bdev)
static void send_disconnects(struct nbd_device *nbd)
{
- struct nbd_request request = {};
+ struct nbd_request request = {
+ .magic = htonl(NBD_REQUEST_MAGIC),
+ .type = htonl(NBD_CMD_DISC),
+ };
+ struct kvec iov = {.iov_base = &request, .iov_len = sizeof(request)};
+ struct iov_iter from;
int i, ret;
- request.magic = htonl(NBD_REQUEST_MAGIC);
- request.type = htonl(NBD_CMD_DISC);
-
for (i = 0; i < nbd->num_connections; i++) {
- ret = sock_xmit(nbd, i, 1, &request, sizeof(request), 0);
+ iov_iter_kvec(&from, WRITE | ITER_KVEC, &iov, 1, sizeof(request));
+ ret = sock_xmit(nbd, i, 1, &from, 0);
if (ret <= 0)
dev_err(disk_to_dev(nbd->disk),
"Send disconnect failed %d\n", ret);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 024b473524c0..1d4c9f8bc1e1 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -5,6 +5,7 @@
#include <linux/hdreg.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/interrupt.h>
#include <linux/virtio.h>
#include <linux/virtio_blk.h>
#include <linux/scatterlist.h>
@@ -12,6 +13,7 @@
#include <scsi/scsi_cmnd.h>
#include <linux/idr.h>
#include <linux/blk-mq.h>
+#include <linux/blk-mq-virtio.h>
#include <linux/numa.h>
#define PART_BITS 4
@@ -426,6 +428,7 @@ static int init_vq(struct virtio_blk *vblk)
struct virtqueue **vqs;
unsigned short num_vqs;
struct virtio_device *vdev = vblk->vdev;
+ struct irq_affinity desc = { 0, };
err = virtio_cread_feature(vdev, VIRTIO_BLK_F_MQ,
struct virtio_blk_config, num_queues,
@@ -452,7 +455,8 @@ static int init_vq(struct virtio_blk *vblk)
}
/* Discover virtqueues and write information to configuration. */
- err = vdev->config->find_vqs(vdev, num_vqs, vqs, callbacks, names);
+ err = vdev->config->find_vqs(vdev, num_vqs, vqs, callbacks, names,
+ &desc);
if (err)
goto out;
@@ -586,10 +590,18 @@ static int virtblk_init_request(void *data, struct request *rq,
return 0;
}
+static int virtblk_map_queues(struct blk_mq_tag_set *set)
+{
+ struct virtio_blk *vblk = set->driver_data;
+
+ return blk_mq_virtio_map_queues(set, vblk->vdev, 0);
+}
+
static struct blk_mq_ops virtio_mq_ops = {
.queue_rq = virtio_queue_rq,
.complete = virtblk_request_done,
.init_request = virtblk_init_request,
+ .map_queues = virtblk_map_queues,
};
static unsigned int virtblk_queue_depth;