diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-01-27 16:13:12 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-02-04 13:55:35 -0500 |
commit | 79c14141a487211d1bb7840d3f607766f6115dd2 (patch) | |
tree | 97c32dff53ab137612047ccd5991530f959eb44e /drivers/vhost | |
parent | b44a2b6790b04621c14de176757a09193699bc37 (diff) |
vhost/scsi: Convert completion path to use copy_to_iter
Required for ANY_LAYOUT support when the incoming virtio-scsi response
header + fixed size sense buffer payload may span more than a single
iovec entry.
This changes existing code to save cmd->tvc_resp_iov instead of the
first single iovec base pointer from &vq->iov[out].
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/vhost')
-rw-r--r-- | drivers/vhost/scsi.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 01c01cb3933f..29dfdf66bbc5 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -72,6 +72,8 @@ struct tcm_vhost_cmd { | |||
72 | int tvc_vq_desc; | 72 | int tvc_vq_desc; |
73 | /* virtio-scsi initiator task attribute */ | 73 | /* virtio-scsi initiator task attribute */ |
74 | int tvc_task_attr; | 74 | int tvc_task_attr; |
75 | /* virtio-scsi response incoming iovecs */ | ||
76 | int tvc_in_iovs; | ||
75 | /* virtio-scsi initiator data direction */ | 77 | /* virtio-scsi initiator data direction */ |
76 | enum dma_data_direction tvc_data_direction; | 78 | enum dma_data_direction tvc_data_direction; |
77 | /* Expected data transfer length from virtio-scsi header */ | 79 | /* Expected data transfer length from virtio-scsi header */ |
@@ -87,8 +89,8 @@ struct tcm_vhost_cmd { | |||
87 | struct scatterlist *tvc_sgl; | 89 | struct scatterlist *tvc_sgl; |
88 | struct scatterlist *tvc_prot_sgl; | 90 | struct scatterlist *tvc_prot_sgl; |
89 | struct page **tvc_upages; | 91 | struct page **tvc_upages; |
90 | /* Pointer to response */ | 92 | /* Pointer to response header iovec */ |
91 | struct virtio_scsi_cmd_resp __user *tvc_resp; | 93 | struct iovec *tvc_resp_iov; |
92 | /* Pointer to vhost_scsi for our device */ | 94 | /* Pointer to vhost_scsi for our device */ |
93 | struct vhost_scsi *tvc_vhost; | 95 | struct vhost_scsi *tvc_vhost; |
94 | /* Pointer to vhost_virtqueue for the cmd */ | 96 | /* Pointer to vhost_virtqueue for the cmd */ |
@@ -682,6 +684,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | |||
682 | struct tcm_vhost_cmd *cmd; | 684 | struct tcm_vhost_cmd *cmd; |
683 | struct llist_node *llnode; | 685 | struct llist_node *llnode; |
684 | struct se_cmd *se_cmd; | 686 | struct se_cmd *se_cmd; |
687 | struct iov_iter iov_iter; | ||
685 | int ret, vq; | 688 | int ret, vq; |
686 | 689 | ||
687 | bitmap_zero(signal, VHOST_SCSI_MAX_VQ); | 690 | bitmap_zero(signal, VHOST_SCSI_MAX_VQ); |
@@ -703,8 +706,11 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | |||
703 | se_cmd->scsi_sense_length); | 706 | se_cmd->scsi_sense_length); |
704 | memcpy(v_rsp.sense, cmd->tvc_sense_buf, | 707 | memcpy(v_rsp.sense, cmd->tvc_sense_buf, |
705 | se_cmd->scsi_sense_length); | 708 | se_cmd->scsi_sense_length); |
706 | ret = copy_to_user(cmd->tvc_resp, &v_rsp, sizeof(v_rsp)); | 709 | |
707 | if (likely(ret == 0)) { | 710 | iov_iter_init(&iov_iter, READ, cmd->tvc_resp_iov, |
711 | cmd->tvc_in_iovs, sizeof(v_rsp)); | ||
712 | ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter); | ||
713 | if (likely(ret == sizeof(v_rsp))) { | ||
708 | struct vhost_scsi_virtqueue *q; | 714 | struct vhost_scsi_virtqueue *q; |
709 | vhost_add_used(cmd->tvc_vq, cmd->tvc_vq_desc, 0); | 715 | vhost_add_used(cmd->tvc_vq, cmd->tvc_vq_desc, 0); |
710 | q = container_of(cmd->tvc_vq, struct vhost_scsi_virtqueue, vq); | 716 | q = container_of(cmd->tvc_vq, struct vhost_scsi_virtqueue, vq); |
@@ -1159,7 +1165,8 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) | |||
1159 | 1165 | ||
1160 | cmd->tvc_vhost = vs; | 1166 | cmd->tvc_vhost = vs; |
1161 | cmd->tvc_vq = vq; | 1167 | cmd->tvc_vq = vq; |
1162 | cmd->tvc_resp = vq->iov[out].iov_base; | 1168 | cmd->tvc_resp_iov = &vq->iov[out]; |
1169 | cmd->tvc_in_iovs = in; | ||
1163 | 1170 | ||
1164 | pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", | 1171 | pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", |
1165 | cmd->tvc_cdb[0], cmd->tvc_lun); | 1172 | cmd->tvc_cdb[0], cmd->tvc_lun); |