On Tue, Feb 03, 2015 at 06:29:58AM +0000, Nicholas A. Bellinger wrote: > From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> > > This patch adds ANY_LAYOUT prerequisites logic for accepting a set of > protection + data payloads via iov_iter. Also includes helpers for > calcuating SGLs + invoking vhost_scsi_map_to_sgl() with a known number > of iovecs. > > Required by ANY_LAYOUT processing when struct iovec may be offset into > the first outgoing virtio-scsi request header. > > v2 changes: > - Clear ->tvc_sgl_count for vhost_scsi_mapal failure > - Make vhost_scsi_mapal + vhost_scsi_calc_sgls accept max_niov > - Minor cleanups > > v3 changes: > - Update vhost_scsi_mapal + friends to use iov_iter > - Move iov_iter sanity checks into vhost_scsi_calc_sgls > - Convert vhost_scsi_calc_sgls() to iov_iter_npages() I guess if this goes through your tree, you can drop these when applying, but it's best not to assume this, and put changelog after ---. > Cc: Michael S. Tsirkin <mst@xxxxxxxxxx> > Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> > Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> > --- > drivers/vhost/scsi.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 93 insertions(+) > > diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c > index c3b12b3..7dfff15 100644 > --- a/drivers/vhost/scsi.c > +++ b/drivers/vhost/scsi.c > @@ -914,6 +914,99 @@ vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd, > return 0; > } > > +static int > +vhost_scsi_calc_sgls(struct iov_iter *iter, size_t bytes, int max_sgls) > +{ > + int sgl_count = 0; > + > + if (!iter || !iter->iov) { > + pr_err("%s: iter->iov is NULL, but expected bytes: %zu" > + " present\n", __func__, bytes); > + return -EINVAL; > + } > + > + sgl_count = iov_iter_npages(iter, 0xffff); > + if (sgl_count > max_sgls) { > + pr_err("%s: requested sgl_count: %d exceeds pre-allocated" > + " max_sgls: %d\n", __func__, sgl_count, max_sgls); > + return -EINVAL; > + } > + return sgl_count; > +} > + > +static int > +vhost_scsi_iov_to_sgl(struct tcm_vhost_cmd *cmd, bool write, > + struct iov_iter *iter, struct scatterlist *sg, > + int sg_count) > +{ > + size_t off = iter->iov_offset; > + int i, ret; > + > + for (i = 0; i < iter->nr_segs; i++) { > + void __user *base = iter->iov[i].iov_base + off; > + size_t len = iter->iov[i].iov_len - off; > + > + ret = vhost_scsi_map_to_sgl(cmd, base, len, sg, write); > + if (ret < 0) { > + for (i = 0; i < sg_count; i++) { > + struct page *page = sg_page(&sg[i]); > + if (page) > + put_page(page); > + } > + return ret; > + } > + sg += ret; > + off = 0; > + } > + return 0; > +} > + > +static int > +vhost_scsi_mapal(struct tcm_vhost_cmd *cmd, > + size_t prot_bytes, struct iov_iter *prot_iter, > + size_t data_bytes, struct iov_iter *data_iter) > +{ > + int sgl_count, ret; > + bool write = (cmd->tvc_data_direction == DMA_FROM_DEVICE); > + > + if (prot_bytes) { > + sgl_count = vhost_scsi_calc_sgls(prot_iter, prot_bytes, > + TCM_VHOST_PREALLOC_PROT_SGLS); > + if (sgl_count < 0) > + return sgl_count; > + > + sg_init_table(cmd->tvc_prot_sgl, sgl_count); > + cmd->tvc_prot_sgl_count = sgl_count; > + pr_debug("%s prot_sg %p prot_sgl_count %u\n", __func__, > + cmd->tvc_prot_sgl, cmd->tvc_prot_sgl_count); > + > + ret = vhost_scsi_iov_to_sgl(cmd, write, prot_iter, > + cmd->tvc_prot_sgl, > + cmd->tvc_prot_sgl_count); > + if (ret < 0) { > + cmd->tvc_prot_sgl_count = 0; > + return ret; > + } > + } > + sgl_count = vhost_scsi_calc_sgls(data_iter, data_bytes, > + TCM_VHOST_PREALLOC_SGLS); > + if (sgl_count < 0) > + return sgl_count; > + > + sg_init_table(cmd->tvc_sgl, sgl_count); > + cmd->tvc_sgl_count = sgl_count; > + pr_debug("%s data_sg %p data_sgl_count %u\n", __func__, > + cmd->tvc_sgl, cmd->tvc_sgl_count); > + > + ret = vhost_scsi_iov_to_sgl(cmd, write, data_iter, > + cmd->tvc_sgl, cmd->tvc_sgl_count); > + if (ret < 0) { > + cmd->tvc_sgl_count = 0; > + return ret; > + } > + return 0; > +} > + > static void tcm_vhost_submission_work(struct work_struct *work) > { > struct tcm_vhost_cmd *cmd = > -- > 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html