* [PATCH 1/9] target: Convert DIF emulation to use cmd->prot_type
2015-02-28 10:35 [PATCH 0/9] target: Add WRITE_STRIP + READ_INSERT support Nicholas A. Bellinger
@ 2015-02-28 10:35 ` Nicholas A. Bellinger
2015-03-02 11:30 ` Sagi Grimberg
2015-02-28 10:35 ` [PATCH 2/9] target: Add protected fabric + unprotected device support Nicholas A. Bellinger
` (7 subsequent siblings)
8 siblings, 1 reply; 11+ messages in thread
From: Nicholas A. Bellinger @ 2015-02-28 10:35 UTC (permalink / raw)
To: target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Christoph Hellwig
From: Nicholas Bellinger <nab@linux-iscsi.org>
This patch changes existing DIF emulation to check the command descriptor's
prot_type, instead of what the backend device is exposing in pi_prot_type.
Since this value is already set in sbc_check_prot(), go ahead and use it to
allow protected fabrics to function with unprotected devices.
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/target_core_sbc.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 9a2f9d3..95a7a74 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -1167,7 +1167,7 @@ sbc_dif_generate(struct se_cmd *cmd)
sdt = paddr + offset;
sdt->guard_tag = cpu_to_be16(crc_t10dif(daddr + j,
dev->dev_attrib.block_size));
- if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE1_PROT)
+ if (cmd->prot_type == TARGET_DIF_TYPE1_PROT)
sdt->ref_tag = cpu_to_be32(sector & 0xffffffff);
sdt->app_tag = 0;
@@ -1186,9 +1186,10 @@ sbc_dif_generate(struct se_cmd *cmd)
}
static sense_reason_t
-sbc_dif_v1_verify(struct se_device *dev, struct se_dif_v1_tuple *sdt,
+sbc_dif_v1_verify(struct se_cmd *cmd, struct se_dif_v1_tuple *sdt,
const void *p, sector_t sector, unsigned int ei_lba)
{
+ struct se_device *dev = cmd->se_dev;
int block_size = dev->dev_attrib.block_size;
__be16 csum;
@@ -1201,7 +1202,7 @@ sbc_dif_v1_verify(struct se_device *dev, struct se_dif_v1_tuple *sdt,
return TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED;
}
- if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE1_PROT &&
+ if (cmd->prot_type == TARGET_DIF_TYPE1_PROT &&
be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) {
pr_err("DIFv1 Type 1 reference failed on sector: %llu tag: 0x%08x"
" sector MSB: 0x%08x\n", (unsigned long long)sector,
@@ -1209,7 +1210,7 @@ sbc_dif_v1_verify(struct se_device *dev, struct se_dif_v1_tuple *sdt,
return TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED;
}
- if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE2_PROT &&
+ if (cmd->prot_type == TARGET_DIF_TYPE2_PROT &&
be32_to_cpu(sdt->ref_tag) != ei_lba) {
pr_err("DIFv1 Type 2 reference failed on sector: %llu tag: 0x%08x"
" ei_lba: 0x%08x\n", (unsigned long long)sector,
@@ -1293,7 +1294,7 @@ sbc_dif_verify_write(struct se_cmd *cmd, sector_t start, unsigned int sectors,
(unsigned long long)sector, sdt->guard_tag,
sdt->app_tag, be32_to_cpu(sdt->ref_tag));
- rc = sbc_dif_v1_verify(dev, sdt, daddr + j, sector,
+ rc = sbc_dif_v1_verify(cmd, sdt, daddr + j, sector,
ei_lba);
if (rc) {
kunmap_atomic(paddr);
@@ -1354,7 +1355,7 @@ __sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors,
continue;
}
- rc = sbc_dif_v1_verify(dev, sdt, daddr + j, sector,
+ rc = sbc_dif_v1_verify(cmd, sdt, daddr + j, sector,
ei_lba);
if (rc) {
kunmap_atomic(paddr);
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 1/9] target: Convert DIF emulation to use cmd->prot_type
2015-02-28 10:35 ` [PATCH 1/9] target: Convert DIF emulation to use cmd->prot_type Nicholas A. Bellinger
@ 2015-03-02 11:30 ` Sagi Grimberg
0 siblings, 0 replies; 11+ messages in thread
From: Sagi Grimberg @ 2015-03-02 11:30 UTC (permalink / raw)
To: Nicholas A. Bellinger, target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Christoph Hellwig
On 2/28/2015 12:35 PM, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger <nab@linux-iscsi.org>
>
> This patch changes existing DIF emulation to check the command descriptor's
> prot_type, instead of what the backend device is exposing in pi_prot_type.
>
> Since this value is already set in sbc_check_prot(), go ahead and use it to
> allow protected fabrics to function with unprotected devices.
>
> Cc: Martin Petersen <martin.petersen@oracle.com>
> Cc: Sagi Grimberg <sagig@mellanox.com>
> Cc: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
> ---
> drivers/target/target_core_sbc.c | 13 +++++++------
> 1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
> index 9a2f9d3..95a7a74 100644
> --- a/drivers/target/target_core_sbc.c
> +++ b/drivers/target/target_core_sbc.c
> @@ -1167,7 +1167,7 @@ sbc_dif_generate(struct se_cmd *cmd)
> sdt = paddr + offset;
> sdt->guard_tag = cpu_to_be16(crc_t10dif(daddr + j,
> dev->dev_attrib.block_size));
> - if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE1_PROT)
> + if (cmd->prot_type == TARGET_DIF_TYPE1_PROT)
> sdt->ref_tag = cpu_to_be32(sector & 0xffffffff);
> sdt->app_tag = 0;
>
> @@ -1186,9 +1186,10 @@ sbc_dif_generate(struct se_cmd *cmd)
> }
>
> static sense_reason_t
> -sbc_dif_v1_verify(struct se_device *dev, struct se_dif_v1_tuple *sdt,
> +sbc_dif_v1_verify(struct se_cmd *cmd, struct se_dif_v1_tuple *sdt,
> const void *p, sector_t sector, unsigned int ei_lba)
> {
> + struct se_device *dev = cmd->se_dev;
> int block_size = dev->dev_attrib.block_size;
> __be16 csum;
>
> @@ -1201,7 +1202,7 @@ sbc_dif_v1_verify(struct se_device *dev, struct se_dif_v1_tuple *sdt,
> return TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED;
> }
>
> - if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE1_PROT &&
> + if (cmd->prot_type == TARGET_DIF_TYPE1_PROT &&
This reminds me, I wander if the dif verify needed checks should be
driven from the cmd->prot_type or from cmd->prot_checks (set at
sbc_set_prot_op_checks()). AFAICT, the protection type simply
determines the way we treat the tags. Although I guess the target is
allowed to check protection even if it wasn't requested to (for example
when the fabric is unprotected and the backend is protected...).
MKP?
Sagi.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/9] target: Add protected fabric + unprotected device support
2015-02-28 10:35 [PATCH 0/9] target: Add WRITE_STRIP + READ_INSERT support Nicholas A. Bellinger
2015-02-28 10:35 ` [PATCH 1/9] target: Convert DIF emulation to use cmd->prot_type Nicholas A. Bellinger
@ 2015-02-28 10:35 ` Nicholas A. Bellinger
2015-02-28 10:36 ` [PATCH 3/9] target: Update SPC/SBC emulation for sess_prot_type Nicholas A. Bellinger
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nicholas A. Bellinger @ 2015-02-28 10:35 UTC (permalink / raw)
To: target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Christoph Hellwig, Doug Gilbert
From: Nicholas Bellinger <nab@linux-iscsi.org>
This patch adds a new target_core_fabric_ops callback for allowing fabric
drivers to expose a TPG attribute for signaling when a T10-PI protected
fabric wants to function with an un-protected device without T10-PI.
This specifically is to allow LIO to perform WRITE_STRIP + READ_INSERT
operations when functioning with non T10-PI enabled devices, seperate
from any available hw offloads the fabric supports.
This is done using a new se_sess->sess_prot_type that is set at fabric
session creation time based upon the TPG attribute. It currently cannot
be changed for individual sessions after initial creation.
Also, update existing target_core_sbc.c code to honor sess_prot_type when
setting up cmd->prot_op + cmd->prot_type assignments.
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Doug Gilbert <dgilbert@interlog.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/target_core_sbc.c | 44 +++++++++++++++++++++++++---------
drivers/target/target_core_transport.c | 8 +++++++
include/target/target_core_base.h | 1 +
include/target/target_core_fabric.h | 8 +++++++
4 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 95a7a74..5b3564a 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -581,12 +581,13 @@ sbc_compare_and_write(struct se_cmd *cmd)
}
static int
-sbc_set_prot_op_checks(u8 protect, enum target_prot_type prot_type,
+sbc_set_prot_op_checks(u8 protect, bool fabric_prot, enum target_prot_type prot_type,
bool is_write, struct se_cmd *cmd)
{
if (is_write) {
- cmd->prot_op = protect ? TARGET_PROT_DOUT_PASS :
- TARGET_PROT_DOUT_INSERT;
+ cmd->prot_op = fabric_prot ? TARGET_PROT_DOUT_STRIP :
+ protect ? TARGET_PROT_DOUT_PASS :
+ TARGET_PROT_DOUT_INSERT;
switch (protect) {
case 0x0:
case 0x3:
@@ -610,8 +611,9 @@ sbc_set_prot_op_checks(u8 protect, enum target_prot_type prot_type,
return -EINVAL;
}
} else {
- cmd->prot_op = protect ? TARGET_PROT_DIN_PASS :
- TARGET_PROT_DIN_STRIP;
+ cmd->prot_op = fabric_prot ? TARGET_PROT_DIN_INSERT :
+ protect ? TARGET_PROT_DIN_PASS :
+ TARGET_PROT_DIN_STRIP;
switch (protect) {
case 0x0:
case 0x1:
@@ -644,11 +646,15 @@ sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
u32 sectors, bool is_write)
{
u8 protect = cdb[1] >> 5;
+ int sp_ops = cmd->se_sess->sup_prot_ops;
+ int pi_prot_type = dev->dev_attrib.pi_prot_type;
+ bool fabric_prot = false;
if (!cmd->t_prot_sg || !cmd->t_prot_nents) {
- if (protect && !dev->dev_attrib.pi_prot_type) {
- pr_err("CDB contains protect bit, but device does not"
- " advertise PROTECT=1 feature bit\n");
+ if (protect &&
+ !dev->dev_attrib.pi_prot_type && !cmd->se_sess->sess_prot_type) {
+ pr_err("CDB contains protect bit, but device + fabric does"
+ " not advertise PROTECT=1 feature bit\n");
return TCM_INVALID_CDB_FIELD;
}
if (cmd->prot_pto)
@@ -669,15 +675,28 @@ sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
cmd->reftag_seed = cmd->t_task_lba;
break;
case TARGET_DIF_TYPE0_PROT:
+ /*
+ * See if the fabric supports T10-PI, and the session has been
+ * configured to allow export PROTECT=1 feature bit with backend
+ * devices that don't support T10-PI.
+ */
+ fabric_prot = is_write ?
+ (sp_ops & (TARGET_PROT_DOUT_PASS | TARGET_PROT_DOUT_STRIP)) :
+ (sp_ops & (TARGET_PROT_DIN_PASS | TARGET_PROT_DIN_INSERT));
+
+ if (fabric_prot && cmd->se_sess->sess_prot_type) {
+ pi_prot_type = cmd->se_sess->sess_prot_type;
+ break;
+ }
+ /* Fallthrough */
default:
return TCM_NO_SENSE;
}
- if (sbc_set_prot_op_checks(protect, dev->dev_attrib.pi_prot_type,
- is_write, cmd))
+ if (sbc_set_prot_op_checks(protect, fabric_prot, pi_prot_type, is_write, cmd))
return TCM_INVALID_CDB_FIELD;
- cmd->prot_type = dev->dev_attrib.pi_prot_type;
+ cmd->prot_type = pi_prot_type;
cmd->prot_length = dev->prot_length * sectors;
/**
@@ -1231,6 +1250,9 @@ sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
unsigned int i, len, left;
unsigned int offset = sg_off;
+ if (!sg)
+ return;
+
left = sectors * dev->prot_length;
for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) {
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index ac3cbab..38d9d1b 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -322,11 +322,19 @@ void __transport_register_session(
struct se_session *se_sess,
void *fabric_sess_ptr)
{
+ struct target_core_fabric_ops *tfo = se_tpg->se_tpg_tfo;
unsigned char buf[PR_REG_ISID_LEN];
se_sess->se_tpg = se_tpg;
se_sess->fabric_sess_ptr = fabric_sess_ptr;
/*
+ * Determine if fabric allows for T10-PI feature bits to be exposed
+ * to initiators for device backends with !dev->dev_attrib.pi_prot_type
+ */
+ if (tfo->tpg_check_prot_fabric_only)
+ se_sess->sess_prot_type = tfo->tpg_check_prot_fabric_only(se_tpg);
+
+ /*
* Used by struct se_node_acl's under ConfigFS to locate active se_session-t
*
* Only set for struct se_session's that will actually be moving I/O.
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 672150b..fe25a78 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -616,6 +616,7 @@ struct se_session {
unsigned sess_tearing_down:1;
u64 sess_bin_isid;
enum target_prot_op sup_prot_ops;
+ enum target_prot_type sess_prot_type;
struct se_node_acl *se_node_acl;
struct se_portal_group *se_tpg;
void *fabric_sess_ptr;
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 22a4e98e..9811c85 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -27,6 +27,14 @@ struct target_core_fabric_ops {
* inquiry response
*/
int (*tpg_check_demo_mode_login_only)(struct se_portal_group *);
+ /*
+ * Optionally used as a configfs tunable to determine when
+ * target-core should signal the PROTECT=1 feature bit for
+ * backends that don't support T10-PI, so that either fabric
+ * HW offload or target-core emulation performs the associated
+ * WRITE_STRIP and READ_INSERT operations.
+ */
+ int (*tpg_check_prot_fabric_only)(struct se_portal_group *);
struct se_node_acl *(*tpg_alloc_fabric_acl)(
struct se_portal_group *);
void (*tpg_release_fabric_acl)(struct se_portal_group *,
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 3/9] target: Update SPC/SBC emulation for sess_prot_type
2015-02-28 10:35 [PATCH 0/9] target: Add WRITE_STRIP + READ_INSERT support Nicholas A. Bellinger
2015-02-28 10:35 ` [PATCH 1/9] target: Convert DIF emulation to use cmd->prot_type Nicholas A. Bellinger
2015-02-28 10:35 ` [PATCH 2/9] target: Add protected fabric + unprotected device support Nicholas A. Bellinger
@ 2015-02-28 10:36 ` Nicholas A. Bellinger
2015-02-28 10:36 ` [PATCH 4/9] target: Move cmd->prot_op check into target_check_write_prot Nicholas A. Bellinger
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nicholas A. Bellinger @ 2015-02-28 10:36 UTC (permalink / raw)
To: target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Christoph Hellwig, Doug Gilbert
From: Nicholas Bellinger <nab@linux-iscsi.org>
This patch updates standard INQUIRY, INQUIRY EVPD=0x86, READ_CAPACITY_16
and control mode pages to use se_sess->sess_prot_type when determing which
type of T10-PI related feature bits can be exposed.
This is required for fabric sessions supporting T10-PI metadata to
backend devices that don't have protection enabled.
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Doug Gilbert <dgilbert@interlog.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/target_core_sbc.c | 13 +++++++++++--
drivers/target/target_core_spc.c | 14 +++++++++-----
2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 5b3564a..68373c9 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -93,6 +93,8 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct se_session *sess = cmd->se_sess;
+ int pi_prot_type = dev->dev_attrib.pi_prot_type;
+
unsigned char *rbuf;
unsigned char buf[32];
unsigned long long blocks = dev->transport->get_blocks(dev);
@@ -114,8 +116,15 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd)
* Set P_TYPE and PROT_EN bits for DIF support
*/
if (sess->sup_prot_ops & (TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS)) {
- if (dev->dev_attrib.pi_prot_type)
- buf[12] = (dev->dev_attrib.pi_prot_type - 1) << 1 | 0x1;
+ /*
+ * Only override a device's pi_prot_type if no T10-PI is
+ * available, and sess_prot_type has been explicitly enabled.
+ */
+ if (!pi_prot_type)
+ pi_prot_type = sess->sess_prot_type;
+
+ if (pi_prot_type)
+ buf[12] = (pi_prot_type - 1) << 1 | 0x1;
}
if (dev->transport->get_lbppbe)
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 460e931..5b6a0af 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -103,10 +103,12 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf)
buf[5] |= 0x8;
/*
* Set Protection (PROTECT) bit when DIF has been enabled on the
- * device, and the transport supports VERIFY + PASS.
+ * device, and the fabric supports VERIFY + PASS. Also report
+ * PROTECT=1 if sess_prot_type has been configured to allow T10-PI
+ * to unprotected devices.
*/
if (sess->sup_prot_ops & (TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS)) {
- if (dev->dev_attrib.pi_prot_type)
+ if (dev->dev_attrib.pi_prot_type || cmd->se_sess->sess_prot_type)
buf[5] |= 0x1;
}
@@ -480,9 +482,11 @@ spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
* only for TYPE3 protection.
*/
if (sess->sup_prot_ops & (TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS)) {
- if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE1_PROT)
+ if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE1_PROT ||
+ cmd->se_sess->sess_prot_type == TARGET_DIF_TYPE1_PROT)
buf[4] = 0x5;
- else if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE3_PROT)
+ else if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE3_PROT ||
+ cmd->se_sess->sess_prot_type == TARGET_DIF_TYPE3_PROT)
buf[4] = 0x4;
}
@@ -874,7 +878,7 @@ static int spc_modesense_control(struct se_cmd *cmd, u8 pc, u8 *p)
* TAG field.
*/
if (sess->sup_prot_ops & (TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS)) {
- if (dev->dev_attrib.pi_prot_type)
+ if (dev->dev_attrib.pi_prot_type || sess->sess_prot_type)
p[5] |= 0x80;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 4/9] target: Move cmd->prot_op check into target_check_write_prot
2015-02-28 10:35 [PATCH 0/9] target: Add WRITE_STRIP + READ_INSERT support Nicholas A. Bellinger
` (2 preceding siblings ...)
2015-02-28 10:36 ` [PATCH 3/9] target: Update SPC/SBC emulation for sess_prot_type Nicholas A. Bellinger
@ 2015-02-28 10:36 ` Nicholas A. Bellinger
2015-02-28 10:36 ` [PATCH 5/9] target: Add internal WRITE_STRIP support Nicholas A. Bellinger
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nicholas A. Bellinger @ 2015-02-28 10:36 UTC (permalink / raw)
To: target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Christoph Hellwig
From: Nicholas Bellinger <nab@linux-iscsi.org>
This patch moves the existing target_execute_cmd() check for
cmd->prot_op into it's own function, so it's easier to add
future support for WRITE STRIP.
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/target_core_transport.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 38d9d1b..a4d64d5 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1714,6 +1714,25 @@ void __target_execute_cmd(struct se_cmd *cmd)
}
}
+static int target_check_write_prot(struct se_cmd *cmd)
+{
+ /*
+ * Perform WRITE_INSERT of PI using software emulation when backend
+ * device has PI enabled, if the transport has not already generated
+ * PI using hardware WRITE_INSERT offload.
+ */
+ switch (cmd->prot_op) {
+ case TARGET_PROT_DOUT_INSERT:
+ if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DOUT_INSERT))
+ sbc_dif_generate(cmd);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static bool target_handle_task_attr(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
@@ -1793,15 +1812,9 @@ void target_execute_cmd(struct se_cmd *cmd)
cmd->t_state = TRANSPORT_PROCESSING;
cmd->transport_state |= CMD_T_ACTIVE|CMD_T_BUSY|CMD_T_SENT;
spin_unlock_irq(&cmd->t_state_lock);
- /*
- * Perform WRITE_INSERT of PI using software emulation when backend
- * device has PI enabled, if the transport has not already generated
- * PI using hardware WRITE_INSERT offload.
- */
- if (cmd->prot_op == TARGET_PROT_DOUT_INSERT) {
- if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DOUT_INSERT))
- sbc_dif_generate(cmd);
- }
+
+ if (target_check_write_prot(cmd))
+ return;
if (target_handle_task_attr(cmd)) {
spin_lock_irq(&cmd->t_state_lock);
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 5/9] target: Add internal WRITE_STRIP support
2015-02-28 10:35 [PATCH 0/9] target: Add WRITE_STRIP + READ_INSERT support Nicholas A. Bellinger
` (3 preceding siblings ...)
2015-02-28 10:36 ` [PATCH 4/9] target: Move cmd->prot_op check into target_check_write_prot Nicholas A. Bellinger
@ 2015-02-28 10:36 ` Nicholas A. Bellinger
2015-02-28 10:36 ` [PATCH 6/9] target: Move cmd->prot_op check into target_check_read_prot Nicholas A. Bellinger
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nicholas A. Bellinger @ 2015-02-28 10:36 UTC (permalink / raw)
To: target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Christoph Hellwig
From: Nicholas Bellinger <nab@linux-iscsi.org>
This patch adds WRITE_STRIP support in target_check_write_prot() that
invokes sbc_dif_verify_write() for checking T10-PI metadata before
submitting the I/O to a backend driver.
Upon verify failure, the specific sense code is propigated up the
failure path up to transport_generic_request_failure().
Also, update sbc_dif_verify_write() to only perform the subsequent
protection metadata copy when a valid *sg is passed.
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/target_core_sbc.c | 3 +++
drivers/target/target_core_transport.c | 16 ++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 68373c9..ea23b9c 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -1342,6 +1342,9 @@ sbc_dif_verify_write(struct se_cmd *cmd, sector_t start, unsigned int sectors,
kunmap_atomic(paddr);
kunmap_atomic(daddr);
}
+ if (!sg)
+ return 0;
+
sbc_dif_copy_prot(cmd, sectors, false, sg, sg_off);
return 0;
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index a4d64d5..1b74006 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1716,6 +1716,7 @@ void __target_execute_cmd(struct se_cmd *cmd)
static int target_check_write_prot(struct se_cmd *cmd)
{
+ u32 sectors;
/*
* Perform WRITE_INSERT of PI using software emulation when backend
* device has PI enabled, if the transport has not already generated
@@ -1726,6 +1727,21 @@ static int target_check_write_prot(struct se_cmd *cmd)
if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DOUT_INSERT))
sbc_dif_generate(cmd);
break;
+ case TARGET_PROT_DOUT_STRIP:
+ if (cmd->se_sess->sup_prot_ops & TARGET_PROT_DOUT_STRIP)
+ break;
+
+ sectors = cmd->data_length / cmd->se_dev->dev_attrib.block_size;
+ cmd->pi_err = sbc_dif_verify_write(cmd, cmd->t_task_lba,
+ sectors, 0, NULL, 0);
+ if (cmd->pi_err) {
+ spin_lock_irq(&cmd->t_state_lock);
+ cmd->transport_state &= ~CMD_T_BUSY|CMD_T_SENT;
+ spin_unlock_irq(&cmd->t_state_lock);
+ transport_generic_request_failure(cmd, cmd->pi_err);
+ return -1;
+ }
+ break;
default:
break;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 6/9] target: Move cmd->prot_op check into target_check_read_prot
2015-02-28 10:35 [PATCH 0/9] target: Add WRITE_STRIP + READ_INSERT support Nicholas A. Bellinger
` (4 preceding siblings ...)
2015-02-28 10:36 ` [PATCH 5/9] target: Add internal WRITE_STRIP support Nicholas A. Bellinger
@ 2015-02-28 10:36 ` Nicholas A. Bellinger
2015-02-28 10:36 ` [PATCH 7/9] target: Add internal READ_INSERT support Nicholas A. Bellinger
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nicholas A. Bellinger @ 2015-02-28 10:36 UTC (permalink / raw)
To: target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Christoph Hellwig
From: Nicholas Bellinger <nab@linux-iscsi.org>
This patch moves the existing target_complete_ok_work() check for
cmd->prot_op into it's own function, so it's easier to add future
support for READ INSERT.
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/target_core_transport.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 1b74006..3b9923f 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1956,16 +1956,22 @@ static void transport_handle_queue_full(
schedule_work(&cmd->se_dev->qf_work_queue);
}
-static bool target_check_read_strip(struct se_cmd *cmd)
+static bool target_check_read_prot(struct se_cmd *cmd)
{
sense_reason_t rc;
- if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DIN_STRIP)) {
- rc = sbc_dif_read_strip(cmd);
- if (rc) {
- cmd->pi_err = rc;
- return true;
+ switch (cmd->prot_op) {
+ case TARGET_PROT_DIN_STRIP:
+ if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DIN_STRIP)) {
+ rc = sbc_dif_read_strip(cmd);
+ if (rc) {
+ cmd->pi_err = rc;
+ return true;
+ }
}
+ break;
+ default:
+ break;
}
return false;
@@ -2040,8 +2046,7 @@ static void target_complete_ok_work(struct work_struct *work)
* backend had PI enabled, if the transport will not be
* performing hardware READ_STRIP offload.
*/
- if (cmd->prot_op == TARGET_PROT_DIN_STRIP &&
- target_check_read_strip(cmd)) {
+ if (target_check_read_prot(cmd)) {
ret = transport_send_check_condition_and_sense(cmd,
cmd->pi_err, 0);
if (ret == -EAGAIN || ret == -ENOMEM)
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 7/9] target: Add internal READ_INSERT support
2015-02-28 10:35 [PATCH 0/9] target: Add WRITE_STRIP + READ_INSERT support Nicholas A. Bellinger
` (5 preceding siblings ...)
2015-02-28 10:36 ` [PATCH 6/9] target: Move cmd->prot_op check into target_check_read_prot Nicholas A. Bellinger
@ 2015-02-28 10:36 ` Nicholas A. Bellinger
2015-02-28 10:36 ` [PATCH 8/9] target/file: Add checks for backend DIF emulation Nicholas A. Bellinger
2015-02-28 10:36 ` [PATCH 9/9] loopback: Add fabric_prot_type attribute support Nicholas A. Bellinger
8 siblings, 0 replies; 11+ messages in thread
From: Nicholas A. Bellinger @ 2015-02-28 10:36 UTC (permalink / raw)
To: target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Christoph Hellwig
From: Nicholas Bellinger <nab@linux-iscsi.org>
This patch adds READ_INSERT support in target_check_read_prot() that
invokes sbc_dif_generate() when LIO is responsible for generating the
outgoing T10-PI.
Required for supporting fabrics that exchange protection information,
and would like to function with un-protected devices.
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/target_core_transport.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 3b9923f..1fd0f12 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1970,6 +1970,12 @@ static bool target_check_read_prot(struct se_cmd *cmd)
}
}
break;
+ case TARGET_PROT_DIN_INSERT:
+ if (cmd->se_sess->sup_prot_ops & TARGET_PROT_DIN_INSERT)
+ break;
+
+ sbc_dif_generate(cmd);
+ break;
default:
break;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 8/9] target/file: Add checks for backend DIF emulation
2015-02-28 10:35 [PATCH 0/9] target: Add WRITE_STRIP + READ_INSERT support Nicholas A. Bellinger
` (6 preceding siblings ...)
2015-02-28 10:36 ` [PATCH 7/9] target: Add internal READ_INSERT support Nicholas A. Bellinger
@ 2015-02-28 10:36 ` Nicholas A. Bellinger
2015-02-28 10:36 ` [PATCH 9/9] loopback: Add fabric_prot_type attribute support Nicholas A. Bellinger
8 siblings, 0 replies; 11+ messages in thread
From: Nicholas A. Bellinger @ 2015-02-28 10:36 UTC (permalink / raw)
To: target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Christoph Hellwig
From: Nicholas Bellinger <nab@linux-iscsi.org>
Make sure that FILEIO only attempts to use backend DIF emulation
when it's actually enabled at device level.
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/target_core_file.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index aefd448..d96e699 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -647,7 +647,7 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
if (data_direction == DMA_FROM_DEVICE) {
memset(&fd_prot, 0, sizeof(struct fd_prot));
- if (cmd->prot_type) {
+ if (cmd->prot_type && dev->dev_attrib.pi_prot_type) {
ret = fd_do_prot_rw(cmd, &fd_prot, false);
if (ret < 0)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@ -655,7 +655,7 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
ret = fd_do_rw(cmd, sgl, sgl_nents, 0);
- if (ret > 0 && cmd->prot_type) {
+ if (ret > 0 && cmd->prot_type && dev->dev_attrib.pi_prot_type) {
u32 sectors = cmd->data_length / dev->dev_attrib.block_size;
rc = sbc_dif_verify_read(cmd, cmd->t_task_lba, sectors,
@@ -671,7 +671,7 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
} else {
memset(&fd_prot, 0, sizeof(struct fd_prot));
- if (cmd->prot_type) {
+ if (cmd->prot_type && dev->dev_attrib.pi_prot_type) {
u32 sectors = cmd->data_length / dev->dev_attrib.block_size;
ret = fd_do_prot_rw(cmd, &fd_prot, false);
@@ -709,7 +709,7 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
vfs_fsync_range(fd_dev->fd_file, start, end, 1);
}
- if (ret > 0 && cmd->prot_type) {
+ if (ret > 0 && cmd->prot_type && dev->dev_attrib.pi_prot_type) {
ret = fd_do_prot_rw(cmd, &fd_prot, true);
if (ret < 0)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 9/9] loopback: Add fabric_prot_type attribute support
2015-02-28 10:35 [PATCH 0/9] target: Add WRITE_STRIP + READ_INSERT support Nicholas A. Bellinger
` (7 preceding siblings ...)
2015-02-28 10:36 ` [PATCH 8/9] target/file: Add checks for backend DIF emulation Nicholas A. Bellinger
@ 2015-02-28 10:36 ` Nicholas A. Bellinger
8 siblings, 0 replies; 11+ messages in thread
From: Nicholas A. Bellinger @ 2015-02-28 10:36 UTC (permalink / raw)
To: target-devel
Cc: linux-scsi, Nicholas Bellinger, Martin Petersen, Sagi Grimberg,
Hannes Reinecke
From: Nicholas Bellinger <nab@linux-iscsi.org>
This patch updates loopback to add a new fabric_prot_type TPG attribute,
used for controlling LLD level protection into LIO when the backend
device does not support T10-PI.
Also, go ahead and set DIN_PASS + DOUT_PASS so target-core knows that
it will be doing any WRITE_STRIP and READ_INSERT operations.
Note this currently forces the use of TARGET_DIF_TYPE1_PROT.
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/loopback/tcm_loop.c | 51 ++++++++++++++++++++++++++++++++++++--
drivers/target/loopback/tcm_loop.h | 1 +
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index c36bd7c..696c2ca 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -697,6 +697,13 @@ static int tcm_loop_check_prod_mode_write_protect(struct se_portal_group *se_tpg
return 0;
}
+static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg)
+{
+ struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
+ tl_se_tpg);
+ return tl_tpg->tl_fabric_prot_type;
+}
+
static struct se_node_acl *tcm_loop_tpg_alloc_fabric_acl(
struct se_portal_group *se_tpg)
{
@@ -912,6 +919,42 @@ static void tcm_loop_port_unlink(
/* End items for tcm_loop_port_cit */
+static ssize_t tcm_loop_tpg_attrib_show_fabric_prot_type(
+ struct se_portal_group *se_tpg,
+ char *page)
+{
+ struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
+ tl_se_tpg);
+
+ return sprintf(page, "%d\n", tl_tpg->tl_fabric_prot_type);
+}
+
+static ssize_t tcm_loop_tpg_attrib_store_fabric_prot_type(
+ struct se_portal_group *se_tpg,
+ const char *page,
+ size_t count)
+{
+ struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
+ tl_se_tpg);
+ unsigned long val;
+ int ret = kstrtoul(page, 0, &val);
+
+ if (ret) {
+ pr_err("kstrtoul() returned %d for fabric_prot_type\n", ret);
+ return ret;
+ }
+ tl_tpg->tl_fabric_prot_type = val;
+
+ return count;
+}
+
+TF_TPG_ATTRIB_ATTR(tcm_loop, fabric_prot_type, S_IRUGO | S_IWUSR);
+
+static struct configfs_attribute *tcm_loop_tpg_attrib_attrs[] = {
+ &tcm_loop_tpg_attrib_fabric_prot_type.attr,
+ NULL,
+};
+
/* Start items for tcm_loop_nexus_cit */
static int tcm_loop_make_nexus(
@@ -937,7 +980,8 @@ static int tcm_loop_make_nexus(
/*
* Initialize the struct se_session pointer
*/
- tl_nexus->se_sess = transport_init_session(TARGET_PROT_ALL);
+ tl_nexus->se_sess = transport_init_session(
+ TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS);
if (IS_ERR(tl_nexus->se_sess)) {
ret = PTR_ERR(tl_nexus->se_sess);
goto out;
@@ -1186,6 +1230,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg(
tl_tpg = &tl_hba->tl_hba_tpgs[tpgt];
tl_tpg->tl_hba = tl_hba;
tl_tpg->tl_tpgt = tpgt;
+ tl_tpg->tl_fabric_prot_type = TARGET_DIF_TYPE1_PROT;
/*
* Register the tl_tpg as a emulated SAS TCM Target Endpoint
*/
@@ -1374,6 +1419,8 @@ static int tcm_loop_register_configfs(void)
&tcm_loop_check_demo_mode_write_protect;
fabric->tf_ops.tpg_check_prod_mode_write_protect =
&tcm_loop_check_prod_mode_write_protect;
+ fabric->tf_ops.tpg_check_prot_fabric_only =
+ &tcm_loop_check_prot_fabric_only;
/*
* The TCM loopback fabric module runs in demo-mode to a local
* virtual SCSI device, so fabric dependent initator ACLs are
@@ -1426,7 +1473,7 @@ static int tcm_loop_register_configfs(void)
*/
fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_loop_wwn_attrs;
fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = tcm_loop_tpg_attrs;
- fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL;
+ fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = tcm_loop_tpg_attrib_attrs;
fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL;
fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL;
/*
diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h
index 6ae49f2..1e72ff7 100644
--- a/drivers/target/loopback/tcm_loop.h
+++ b/drivers/target/loopback/tcm_loop.h
@@ -43,6 +43,7 @@ struct tcm_loop_nacl {
struct tcm_loop_tpg {
unsigned short tl_tpgt;
unsigned short tl_transport_status;
+ enum target_prot_type tl_fabric_prot_type;
atomic_t tl_tpg_port_count;
struct se_portal_group tl_se_tpg;
struct tcm_loop_hba *tl_hba;
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread