diff mbox

[2/2] TARGET/sbc,loopback: Adjust command data length in case pi exists on the wire

Message ID 1401639581-20111-3-git-send-email-sagig@mellanox.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Sagi Grimberg June 1, 2014, 4:19 p.m. UTC
In various areas of the code, it is assumed that
se_cmd->data_length describes pure data. In case
that protection information exists over the wire
(protect bits is are on) the target core decrease
the protection length from the data length (instead
of each transport peeking in the cdb).

Modify loopback transport to include protection information
in the transferred data length (like other scsi transports).

Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
---
 drivers/target/loopback/tcm_loop.c |   35 +++++++++++++++++++++++++++++++----
 drivers/target/target_core_sbc.c   |   15 +++++++++++++--
 2 files changed, 44 insertions(+), 6 deletions(-)

Comments

Martin K. Petersen June 2, 2014, 4:54 p.m. UTC | #1
>>>>> "Sagi" == Sagi Grimberg <sagig@mellanox.com> writes:

Sagi,

Sagi> In various areas of the code, it is assumed that
Sagi> se_cmd-> data_length describes pure data. In case
Sagi> that protection information exists over the wire (protect bits is
Sagi> are on) the target core decrease the protection length from the
Sagi> data length (instead of each transport peeking in the cdb).

I completely agree with the notion of including PI in the transport byte
count.

Why do you open code the transfer length adjustment below?

+			/**
+			 * Adjust data_length to include
+			 * protection information
+			 **/
+			switch (sc->device->sector_size) {
+			case 512:
+				data_len += (data_len >> 9) * 8;
+				break;
+			case 1024:
+				data_len += (data_len >> 10) * 8;
+				break;
+			case 2048:
+				data_len += (data_len >> 11) * 8;
+				break;
+			case 4096:
+				data_len += (data_len >> 12) * 8;
+				break;
+			default:
+				data_len +=
+				(data_len >> ilog2(sc->device->sector_size)) * 8;
+			}
Sagi Grimberg June 5, 2014, 5:22 p.m. UTC | #2
On 6/2/2014 7:54 PM, Martin K. Petersen wrote:
>>>>>> "Sagi" == Sagi Grimberg <sagig@mellanox.com> writes:
> Sagi,
>
> Sagi> In various areas of the code, it is assumed that
> Sagi> se_cmd-> data_length describes pure data. In case
> Sagi> that protection information exists over the wire (protect bits is
> Sagi> are on) the target core decrease the protection length from the
> Sagi> data length (instead of each transport peeking in the cdb).
>
> I completely agree with the notion of including PI in the transport byte
> count.
>
> Why do you open code the transfer length adjustment below?

Can't say I have a good reason for that.
I'll move this logic to scsi_cmnd.h.

>
> +			/**
> +			 * Adjust data_length to include
> +			 * protection information
> +			 **/
> +			switch (sc->device->sector_size) {
> +			case 512:
> +				data_len += (data_len >> 9) * 8;
> +				break;
> +			case 1024:
> +				data_len += (data_len >> 10) * 8;
> +				break;
> +			case 2048:
> +				data_len += (data_len >> 11) * 8;
> +				break;
> +			case 4096:
> +				data_len += (data_len >> 12) * 8;
> +				break;
> +			default:
> +				data_len +=
> +				(data_len >> ilog2(sc->device->sector_size)) * 8;
> +			}
>

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index c886ad1..9adde8d 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -179,7 +179,7 @@  static void tcm_loop_submission_work(struct work_struct *work)
 	struct tcm_loop_hba *tl_hba;
 	struct tcm_loop_tpg *tl_tpg;
 	struct scatterlist *sgl_bidi = NULL;
-	u32 sgl_bidi_count = 0;
+	u32 sgl_bidi_count = 0, data_len;
 	int rc;
 
 	tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
@@ -213,12 +213,39 @@  static void tcm_loop_submission_work(struct work_struct *work)
 
 	}
 
-	if (!scsi_prot_sg_count(sc) && scsi_get_prot_op(sc) != SCSI_PROT_NORMAL)
-		se_cmd->prot_pto = true;
+	data_len = scsi_bufflen(sc);
+	if (scsi_get_prot_op(sc) != SCSI_PROT_NORMAL) {
+		if (!scsi_prot_sg_count(sc))
+			se_cmd->prot_pto = true;
+		else {
+			/**
+			 * Adjust data_length to include
+			 * protection information
+			 **/
+			switch (sc->device->sector_size) {
+			case 512:
+				data_len += (data_len >> 9) * 8;
+				break;
+			case 1024:
+				data_len += (data_len >> 10) * 8;
+				break;
+			case 2048:
+				data_len += (data_len >> 11) * 8;
+				break;
+			case 4096:
+				data_len += (data_len >> 12) * 8;
+				break;
+			default:
+				data_len +=
+				(data_len >> ilog2(sc->device->sector_size)) * 8;
+			}
+		}
+	}
+
 
 	rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd,
 			&tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun,
-			scsi_bufflen(sc), tcm_loop_sam_attr(sc),
+			data_len, tcm_loop_sam_attr(sc),
 			sc->sc_data_direction, 0,
 			scsi_sglist(sc), scsi_sg_count(sc),
 			sgl_bidi, sgl_bidi_count,
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index e022959..06f8ecd 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -665,8 +665,19 @@  sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
 
 	cmd->prot_type = dev->dev_attrib.pi_prot_type;
 	cmd->prot_length = dev->prot_length * sectors;
-	pr_debug("%s: prot_type=%d, prot_length=%d prot_op=%d prot_checks=%d\n",
-		 __func__, cmd->prot_type, cmd->prot_length,
+
+	/**
+	 * In case protection information exists over the wire
+	 * we modify command data length to describe pure data.
+	 * The actual transfer length is data length + protection
+	 * length
+	 **/
+	if (protect)
+		cmd->data_length -= cmd->prot_length;
+
+	pr_debug("%s: prot_type=%d, data_length=%d, prot_length=%d "
+		 "prot_op=%d prot_checks=%d\n",
+		 __func__, cmd->prot_type, cmd->data_length, cmd->prot_length,
 		 cmd->prot_op, cmd->prot_checks);
 
 	return true;