linux-next: manual merge of the target-updates tree with Linus' tree

From: Stephen Rothwell
Date: Mon Feb 02 2015 - 01:35:26 EST


Hi Nicholas,

Today's linux-next merge of the target-updates tree got a conflict in
drivers/vhost/scsi.c between commit 46243860806b ("vhost-scsi: Add
missing virtio-scsi -> TCM attribute conversion") from Linus' tree and
commit 6df22d68ecaf ("vhost/scsi: Add ANY_LAYOUT prerequisites") from
the target-updates tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).

--
Cheers,
Stephen Rothwell sfr@xxxxxxxxxxxxxxxx

diff --cc drivers/vhost/scsi.c
index d695b1673ae5,a773af3550ee..000000000000
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@@ -911,23 -911,111 +911,128 @@@ vhost_scsi_map_iov_to_prot(struct tcm_v
return 0;
}

+static int vhost_scsi_to_tcm_attr(int attr)
+{
+ switch (attr) {
+ case VIRTIO_SCSI_S_SIMPLE:
+ return TCM_SIMPLE_TAG;
+ case VIRTIO_SCSI_S_ORDERED:
+ return TCM_ORDERED_TAG;
+ case VIRTIO_SCSI_S_HEAD:
+ return TCM_HEAD_TAG;
+ case VIRTIO_SCSI_S_ACA:
+ return TCM_ACA_TAG;
+ default:
+ break;
+ }
+ return TCM_SIMPLE_TAG;
+}
+
+ static int
+ vhost_scsi_calc_sgls(struct iovec *iov, size_t off, size_t bytes,
+ int *niov, int max_sgls)
+ {
+ size_t tmp = 0;
+ int sgl_count = 0;
+
+ *niov = 0;
+
+ while (tmp < bytes) {
+ void __user *base = iov[*niov].iov_base + off;
+ size_t len = iov[(*niov)++].iov_len - off;
+
+ sgl_count += iov_num_pages(base, len);
+ tmp += min(len, bytes);
+ off = 0;
+ }
+ 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 -ENOBUFS;
+ }
+ return sgl_count;
+ }
+
+ static int
+ vhost_scsi_iov_to_sgl(struct tcm_vhost_cmd *cmd, bool write,
+ struct iovec *iov, size_t iov_off, int niov,
+ struct scatterlist *sg, int sg_count)
+ {
+ int i, ret;
+
+ for (i = 0; i < niov; i++) {
+ void __user *base = iov[i].iov_base + iov_off;
+ size_t len = iov[i].iov_len - iov_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;
+ iov_off = 0;
+ }
+ return 0;
+ }
+
+ static int
+ vhost_scsi_mapal(struct tcm_vhost_cmd *cmd,
+ size_t prot_bytes, struct iovec *prot_iov, size_t prot_off,
+ size_t data_bytes, struct iovec *data_iov, size_t data_off)
+ {
+ int data_sgl_count = 0, niov, ret;
+ bool write = (cmd->tvc_data_direction == DMA_FROM_DEVICE);
+
+ if (prot_bytes) {
+ int prot_sgl_count;
+
+ if (!prot_iov) {
+ pr_err("%s: prot_iov is NULL, but prot_bytes: %zu"
+ "present\n", __func__, prot_bytes);
+ return -EINVAL;
+ }
+ prot_sgl_count = vhost_scsi_calc_sgls(prot_iov, prot_off,
+ prot_bytes, &niov,
+ TCM_VHOST_PREALLOC_PROT_SGLS);
+ if (prot_sgl_count < 0)
+ return prot_sgl_count;
+
+ sg_init_table(cmd->tvc_prot_sgl, prot_sgl_count);
+ cmd->tvc_prot_sgl_count = prot_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_iov, prot_off,
+ niov, cmd->tvc_prot_sgl,
+ prot_sgl_count);
+ if (ret < 0) {
+ cmd->tvc_prot_sgl_count = 0;
+ return ret;
+ }
+ }
+ if (!data_iov) {
+ pr_err("%s: data_iov is NULL, but data_bytes: %zu present\n",
+ __func__, data_bytes);
+ return -EINVAL;
+ }
+ data_sgl_count = vhost_scsi_calc_sgls(data_iov, data_off, data_bytes,
+ &niov, TCM_VHOST_PREALLOC_SGLS);
+ if (data_sgl_count < 0)
+ return data_sgl_count;
+
+ sg_init_table(cmd->tvc_sgl, data_sgl_count);
+ cmd->tvc_sgl_count = data_sgl_count;
+ pr_debug("%s data_sg %p data_sgl_count %u\n", __func__,
+ cmd->tvc_sgl, cmd->tvc_sgl_count);
+
+ return vhost_scsi_iov_to_sgl(cmd, write, data_iov, data_off,
+ niov, cmd->tvc_sgl, data_sgl_count);
+ }
+
static void tcm_vhost_submission_work(struct work_struct *work)
{
struct tcm_vhost_cmd *cmd =

Attachment: pgpZf2zeAasK7.pgp
Description: OpenPGP digital signature