summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2014-02-19 19:50:17 +0400
committerNicholas Bellinger <nab@linux-iscsi.org>2014-04-07 12:48:42 +0400
commitb5b8e2989e3406798dbb88fbb4eaafbbf1a56f6a (patch)
treecd301ec29007c124aaa71ac6ce4fb60231761719
parent80dcd0c10482719bd9250b7d11bd5c360a02403a (diff)
downloadlinux-b5b8e2989e3406798dbb88fbb4eaafbbf1a56f6a.tar.xz
Target/dif: Introduce protection-passthough-only mode
Some transports (iSCSI/iSER/SRP/FC) support hardware INSERT/STRIP capabilities while other transports like loopback/vhost-scsi need perform this is software. This patch allows fabrics using SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC to signal the early LUN scan handling case where PROTECT CDB bits are set, but no fabric buffer has been provided. For transports which use generic new command these buffers have yet to be allocated. Also this way, target may support protection information against legacy initiators (writes are inserted and reads are stripped). (Only set prot_pto for loopback during early special case - nab) Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/loopback/tcm_loop.c4
-rw-r--r--drivers/target/target_core_sbc.c2
-rw-r--r--drivers/target/target_core_transport.c12
-rw-r--r--include/target/target_core_base.h1
4 files changed, 13 insertions, 6 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index fadad7c5f635..a49ef0a49fa9 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -212,6 +212,10 @@ static void tcm_loop_submission_work(struct work_struct *work)
se_cmd->se_cmd_flags |= SCF_BIDI;
}
+
+ if (!scsi_prot_sg_count(sc) && scsi_get_prot_op(sc) != SCSI_PROT_NORMAL)
+ se_cmd->prot_pto = true;
+
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),
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index a1e75dd636ac..c301d9b6874d 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -634,7 +634,7 @@ sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
{
u8 protect = cdb[1] >> 5;
- if (!cmd->t_prot_sg || !cmd->t_prot_nents)
+ if ((!cmd->t_prot_sg || !cmd->t_prot_nents) && cmd->prot_pto)
return true;
switch (dev->dev_attrib.pi_prot_type) {
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 4653d826e595..0a359fa82bd3 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1365,6 +1365,13 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
target_put_sess_cmd(se_sess, se_cmd);
return 0;
}
+
+ rc = target_setup_cmd_from_cdb(se_cmd, cdb);
+ if (rc != 0) {
+ transport_generic_request_failure(se_cmd, rc);
+ return 0;
+ }
+
/*
* Save pointers for SGLs containing protection information,
* if present.
@@ -1374,11 +1381,6 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
se_cmd->t_prot_nents = sgl_prot_count;
}
- rc = target_setup_cmd_from_cdb(se_cmd, cdb);
- if (rc != 0) {
- transport_generic_request_failure(se_cmd, rc);
- return 0;
- }
/*
* When a non zero sgl_count has been passed perform SGL passthrough
* mapping for pre-allocated fabric memory instead of having target
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 5ae92492d1ee..82cb4ed06f71 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -570,6 +570,7 @@ struct se_cmd {
enum target_prot_ho prot_handover;
sense_reason_t pi_err;
sector_t bad_sector;
+ bool prot_pto;
};
struct se_ua {