Re: [PATCH-v2 02/15] target: Add protected fabric + unprotected device support
nab == Nicholas A Bellinger n...@linux-iscsi.org writes: nab The following incremental patch saves the current sess_prot_type nab into se_node_acl, and will always reset sess_prot_type if a nab previous saved value exists. So the PI setting for the fabric's nab session with backend devices not supporting PI is persistent across nab session restart. nab I also noticed the internal DIF emulation was not honoring se_cmd- nab prot_checks for the WRPROTECT/RDPROTECT == 0x3 case, so nab sbc_dif_v1_verify() has been updated to follow which checks have nab been calculated based on WRPROTECT/RDPROTECT in nab sbc_set_prot_op_checks(). nab Finally in sbc_check_prot(), if PROTECT is non-zero for a backend nab device with DIF disabled, and sess_prot_type is not set go ahead nab and return INVALID_CDB_FIELD. Looks good to me. Reviewed-by: Martin K. Petersen martin.peter...@oracle.com -- Martin K. Petersen Oracle Linux Engineering -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH-v2 02/15] target: Add protected fabric + unprotected device support
On 4/10/2015 9:59 PM, Nicholas A. Bellinger wrote: On Thu, 2015-04-09 at 17:45 -0400, Martin K. Petersen wrote: nab == Nicholas A Bellinger n...@linux-iscsi.org writes: How do you handle RDPROTECT/WRPROTECT values of 3 if the PI is not persistent? nab AFAICT, this would result in cmd-prot_op = TARGET_PROT_*_PASS and cmd- prot_checks = 0 for RDPROTECT/WRPROTECT == 0x3 in nab sbc_set_prot_op_checks() code. nab Do DOUT_STRIP + DIN_INSERT need to be called if a protection buffer nab is present when RDPROTECT/WRPROTECT == 0x3 if fabric_prot was nab cleared..? Or should the command be rejected when a protection nab buffer is present + RDPROTECT/WRPROTECT is non-zero if fabric_prot nab was cleared..? Depends how compliant you want to be. You can synthesize PI with RDPROTECT/WRPROTECT=1 as long as the initiator doesn't rely on app tag escapes (we don't). Most non-HDD/SSD targets work this way. nod I would suggest that you return invalid field in CDB for RDPROTECT/WRPROTECT=3 unless the PI can be made persistent, however. Ok, after thinking about this some more, here's what I've come up with.. The following incremental patch saves the current sess_prot_type into se_node_acl, and will always reset sess_prot_type if a previous saved value exists. So the PI setting for the fabric's session with backend devices not supporting PI is persistent across session restart. I also noticed the internal DIF emulation was not honoring se_cmd-prot_checks for the WRPROTECT/RDPROTECT == 0x3 case, so sbc_dif_v1_verify() has been updated to follow which checks have been calculated based on WRPROTECT/RDPROTECT in sbc_set_prot_op_checks(). Finally in sbc_check_prot(), if PROTECT is non-zero for a backend device with DIF disabled, and sess_prot_type is not set go ahead and return INVALID_CDB_FIELD. WDYT..? --nab diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 315ff64..a75512f 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -697,9 +697,13 @@ sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb, pi_prot_type = cmd-se_sess-sess_prot_type; break; } + if (!protect) + return TCM_NO_SENSE; /* Fallthrough */ default: - return TCM_NO_SENSE; + pr_err(Unable to determine pi_prot_type for CDB: 0x%02x + PROTECT: 0x%02x\n, cdb[0], protect); + return TCM_INVALID_CDB_FIELD; } if (sbc_set_prot_op_checks(protect, fabric_prot, pi_prot_type, is_write, cmd)) @@ -1221,6 +1227,9 @@ sbc_dif_v1_verify(struct se_cmd *cmd, struct se_dif_v1_tuple *sdt, int block_size = dev-dev_attrib.block_size; __be16 csum; + if (!(cmd-prot_checks TARGET_DIF_CHECK_GUARD)) + goto check_ref; + csum = cpu_to_be16(crc_t10dif(p, block_size)); if (sdt-guard_tag != csum) { @@ -1230,6 +1239,10 @@ sbc_dif_v1_verify(struct se_cmd *cmd, struct se_dif_v1_tuple *sdt, return TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED; } +check_ref: + if (!(cmd-prot_checks TARGET_DIF_CHECK_REFTAG)) + return 0; + if (cmd-prot_type == TARGET_DIF_TYPE1_PROT be32_to_cpu(sdt-ref_tag) != (sector 0x)) { pr_err(DIFv1 Type 1 reference failed on sector: %llu tag: 0x%08x diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index f884198..3ff38b2 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -329,11 +329,17 @@ void __transport_register_session( 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 +* to initiators for device backends with !dev-dev_attrib.pi_prot_type. +* +* If so, then always save prot_type on a per se_node_acl node basis +* and re-instate the previous sess_prot_type to avoid disabling PI +* from below any previously initiator side registered LUNs. */ - if (tfo-tpg_check_prot_fabric_only) - se_sess-sess_prot_type = tfo-tpg_check_prot_fabric_only(se_tpg); - + if (se_nacl-saved_prot_type) + se_sess-sess_prot_type = se_nacl-saved_prot_type; + else if (tfo-tpg_check_prot_fabric_only) + se_sess-sess_prot_type = se_nacl-saved_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 * diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 383110d..51dcf2b 100644 --- a/include/target/target_core_base.h +++
Re: [PATCH-v2 02/15] target: Add protected fabric + unprotected device support
On Tue, 2015-04-07 at 19:27 -0400, Martin K. Petersen wrote: nab == Nicholas A Bellinger n...@daterainc.com writes: nab This specifically is to allow LIO to perform WRITE_STRIP + nab READ_INSERT operations when functioning with non T10-PI enabled nab devices, seperate from any available hw offloads the fabric nab supports. How do you handle RDPROTECT/WRPROTECT values of 3 if the PI is not persistent? AFAICT, this would result in cmd-prot_op = TARGET_PROT_*_PASS and cmd-prot_checks = 0 for RDPROTECT/WRPROTECT == 0x3 in sbc_set_prot_op_checks() code. Do DOUT_STRIP + DIN_INSERT need to be called if a protection buffer is present when RDPROTECT/WRPROTECT == 0x3 if fabric_prot was cleared..? Or should the command be rejected when a protection buffer is present + RDPROTECT/WRPROTECT is non-zero if fabric_prot was cleared..? Also wrt to PI persistence across session restart, one way it can work is to store the last se_sess-sess_prot_type in se_node_acl, and reinstate the previous setting across session restart. This would allow new sessions to pickup the latest fabric_prot_type endpoint attribute value, but make existing ones with PI enabled keep their previous sess_prot_type settings. WDYT..? --nab -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH-v2 02/15] target: Add protected fabric + unprotected device support
nab == Nicholas A Bellinger n...@daterainc.com writes: nab This specifically is to allow LIO to perform WRITE_STRIP + nab READ_INSERT operations when functioning with non T10-PI enabled nab devices, seperate from any available hw offloads the fabric nab supports. How do you handle RDPROTECT/WRPROTECT values of 3 if the PI is not persistent? -- Martin K. Petersen Oracle Linux Engineering -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH-v2 02/15] target: Add protected fabric + unprotected device support
On 4/1/2015 8:49 AM, Nicholas A. Bellinger wrote: On Mon, 2015-03-30 at 10:51 +0300, Sagi Grimberg wrote: On 3/30/2015 6:28 AM, Nicholas A. Bellinger wrote: From: Nicholas Bellinger n...@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.peter...@oracle.com Cc: Sagi Grimberg sa...@mellanox.com Cc: Christoph Hellwig h...@lst.de Cc: Doug Gilbert dgilb...@interlog.com Signed-off-by: Nicholas Bellinger n...@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; In this case, if the protect=1 and fabric_prot=1 we will strip won't we? I think that the protect condition should come first. Mmm, not sure I follow.. sbc_check_prot() is only ever passing fabric_prot=1 when se_cmd prot SGLs are present and se_dev does not accept PI, regardless of protect. It's a little confusing that fabric_prot is set if the backend device does not support PI. -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH-v2 02/15] target: Add protected fabric + unprotected device support
On Wed, 2015-04-01 at 12:04 +0300, Sagi Grimberg wrote: On 4/1/2015 8:49 AM, Nicholas A. Bellinger wrote: On Mon, 2015-03-30 at 10:51 +0300, Sagi Grimberg wrote: On 3/30/2015 6:28 AM, Nicholas A. Bellinger wrote: From: Nicholas Bellinger n...@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.peter...@oracle.com Cc: Sagi Grimberg sa...@mellanox.com Cc: Christoph Hellwig h...@lst.de Cc: Doug Gilbert dgilb...@interlog.com Signed-off-by: Nicholas Bellinger n...@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; In this case, if the protect=1 and fabric_prot=1 we will strip won't we? I think that the protect condition should come first. Mmm, not sure I follow.. sbc_check_prot() is only ever passing fabric_prot=1 when se_cmd prot SGLs are present and se_dev does not accept PI, regardless of protect. It's a little confusing that fabric_prot is set if the backend device does not support PI. Well, it's supposed to signal that fabric supports PI, but the backend device does not. Seems like a reasonable name to me.. Any ideas for a better one..? ;) --nab -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH-v2 02/15] target: Add protected fabric + unprotected device support
On Mon, 2015-03-30 at 10:51 +0300, Sagi Grimberg wrote: On 3/30/2015 6:28 AM, Nicholas A. Bellinger wrote: From: Nicholas Bellinger n...@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.peter...@oracle.com Cc: Sagi Grimberg sa...@mellanox.com Cc: Christoph Hellwig h...@lst.de Cc: Doug Gilbert dgilb...@interlog.com Signed-off-by: Nicholas Bellinger n...@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; In this case, if the protect=1 and fabric_prot=1 we will strip won't we? I think that the protect condition should come first. Mmm, not sure I follow.. sbc_check_prot() is only ever passing fabric_prot=1 when se_cmd prot SGLs are present and se_dev does not accept PI, regardless of protect. For the protect=1 and fabric_prot=1 case, prot_op is set to TARGET_PROT_DOUT_STRIP requesting the WRITE_STRIP operation by either HW fabric offload or target DIX software emulation because the backend device cannot accept PI. 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; Same here. 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); Can you place unlikely on these conditions? Done. 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
Re: [PATCH-v2 02/15] target: Add protected fabric + unprotected device support
On 3/30/2015 6:28 AM, Nicholas A. Bellinger wrote: From: Nicholas Bellinger n...@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.peter...@oracle.com Cc: Sagi Grimberg sa...@mellanox.com Cc: Christoph Hellwig h...@lst.de Cc: Doug Gilbert dgilb...@interlog.com Signed-off-by: Nicholas Bellinger n...@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; In this case, if the protect=1 and fabric_prot=1 we will strip won't we? I think that the protect condition should come first. 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; Same here. 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); Can you place unlikely on these conditions? 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)) : Shouldn't this be converted to bool using !!()? + (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; } -