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

From: Stephen Rothwell <[email-masked]>
Date: Mon, 2 Feb 2015 17:35:15 +1100

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                    [email-masked]

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 =