Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

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 re-calculates
the data length from the CDB and the backed device
block size (instead of each transport peeking in the cdb).

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

Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Cc: stable@vger.kernel.org # 3.15+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

authored by

Sagi Grimberg and committed by
Nicholas Bellinger
e2a4f55c d77e6535

+25 -5
+12 -3
drivers/target/loopback/tcm_loop.c
··· 179 179 struct tcm_loop_hba *tl_hba; 180 180 struct tcm_loop_tpg *tl_tpg; 181 181 struct scatterlist *sgl_bidi = NULL; 182 - u32 sgl_bidi_count = 0; 182 + u32 sgl_bidi_count = 0, transfer_length; 183 183 int rc; 184 184 185 185 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); ··· 213 213 214 214 } 215 215 216 - if (!scsi_prot_sg_count(sc) && scsi_get_prot_op(sc) != SCSI_PROT_NORMAL) 216 + transfer_length = scsi_transfer_length(sc); 217 + if (!scsi_prot_sg_count(sc) && 218 + scsi_get_prot_op(sc) != SCSI_PROT_NORMAL) { 217 219 se_cmd->prot_pto = true; 220 + /* 221 + * loopback transport doesn't support 222 + * WRITE_GENERATE, READ_STRIP protection 223 + * information operations, go ahead unprotected. 224 + */ 225 + transfer_length = scsi_bufflen(sc); 226 + } 218 227 219 228 rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd, 220 229 &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun, 221 - scsi_bufflen(sc), tcm_loop_sam_attr(sc), 230 + transfer_length, tcm_loop_sam_attr(sc), 222 231 sc->sc_data_direction, 0, 223 232 scsi_sglist(sc), scsi_sg_count(sc), 224 233 sgl_bidi, sgl_bidi_count,
+13 -2
drivers/target/target_core_sbc.c
··· 647 647 648 648 cmd->prot_type = dev->dev_attrib.pi_prot_type; 649 649 cmd->prot_length = dev->prot_length * sectors; 650 - pr_debug("%s: prot_type=%d, prot_length=%d prot_op=%d prot_checks=%d\n", 651 - __func__, cmd->prot_type, cmd->prot_length, 650 + 651 + /** 652 + * In case protection information exists over the wire 653 + * we modify command data length to describe pure data. 654 + * The actual transfer length is data length + protection 655 + * length 656 + **/ 657 + if (protect) 658 + cmd->data_length = sectors * dev->dev_attrib.block_size; 659 + 660 + pr_debug("%s: prot_type=%d, data_length=%d, prot_length=%d " 661 + "prot_op=%d prot_checks=%d\n", 662 + __func__, cmd->prot_type, cmd->data_length, cmd->prot_length, 652 663 cmd->prot_op, cmd->prot_checks); 653 664 654 665 return true;