On Sun, 2014-02-16 at 19:38 +0200, Sagi Grimberg wrote:
> SBC-3 mandates the protection checks that must be
> performed in the rdprotect/wrprotect field. Use them.
> According to backstore device pi_attributes and
> cdb rdprotect/wrprotect.
>
> Signed-off-by: Sagi Grimberg <[email protected]>
> ---
> drivers/target/target_core_sbc.c | 88
> ++++++++++++++++++++++++++++++++++---
> include/target/target_core_base.h | 7 +++
> 2 files changed, 88 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/target/target_core_sbc.c
> b/drivers/target/target_core_sbc.c
> index a448944..dfeb1c2 100644
> --- a/drivers/target/target_core_sbc.c
> +++ b/drivers/target/target_core_sbc.c
> @@ -240,6 +240,11 @@ static inline u32 transport_lba_32(unsigned char *cdb)
> return (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
> }
>
> +static inline u8 rwprotect(unsigned char *cdb)
> +{
> + return cdb[1] >> 5;
> +}
> +
No need for this one-liner. Go ahead and inline instead..
> static inline unsigned long long transport_lba_64(unsigned char *cdb)
> {
> unsigned int __v1, __v2;
> @@ -569,30 +574,95 @@ sbc_compare_and_write(struct se_cmd *cmd)
> return TCM_NO_SENSE;
> }
>
> +static int
> +sbc_set_prot_op_checks(u8 protect, enum target_prot_type prot_type,
> + u8 op, struct se_cmd *cmd)
> +{
> + switch (op) {
> + case READ_10:
> + case READ_12:
> + case READ_16:
> + cmd->prot_op = protect ? TARGET_PROT_DIN_PASS :
> + TARGET_PROT_DIN_STRIP;
> + switch (protect) {
> + case 0x0:
> + case 0x1:
> + case 0x5:
> + cmd->prot_checks = TARGET_DIF_CHECK_GUARD;
> + if (prot_type == TARGET_DIF_TYPE1_PROT)
> + cmd->prot_checks |= TARGET_DIF_CHECK_REFTAG;
> + break;
> + case 0x2:
> + if (prot_type == TARGET_DIF_TYPE1_PROT)
> + cmd->prot_checks = TARGET_DIF_CHECK_REFTAG;
> + break;
> + case 0x3:
> + cmd->prot_checks = 0;
> + break;
> + case 0x4:
> + cmd->prot_checks = TARGET_DIF_CHECK_GUARD;
> + break;
> + default:
> + pr_err("Unsupported protect field %d\n", protect);
> + return -EINVAL;
> + }
> + break;
> + case WRITE_10:
> + case WRITE_12:
> + case WRITE_16:
> + case WRITE_VERIFY:
> + cmd->prot_op = protect ? TARGET_PROT_DOUT_PASS :
> + TARGET_PROT_DOUT_INSERT;
> + switch (protect) {
> + case 0x0:
> + case 0x3:
> + cmd->prot_checks = 0;
> + case 0x1:
> + case 0x5:
> + cmd->prot_checks = TARGET_DIF_CHECK_GUARD;
> + if (prot_type == TARGET_DIF_TYPE1_PROT)
> + cmd->prot_checks |= TARGET_DIF_CHECK_REFTAG;
> + break;
> + case 0x2:
> + if (prot_type == TARGET_DIF_TYPE1_PROT)
> + cmd->prot_checks = TARGET_DIF_CHECK_REFTAG;
> + break;
> + case 0x4:
> + cmd->prot_checks = TARGET_DIF_CHECK_GUARD;
> + break;
> + default:
> + pr_err("Unsupported protect field %d\n", protect);
> + return -EINVAL;
> + }
> + break;
> + default:
> + pr_err("ERROR: bad opcode %d\n", op);
> + return TCM_INVALID_CDB_FIELD;
> + }
> +
> + return 0;
> +}
> +
sbc_set_prot_op_checks() is probably better served by passing in a bool
to determine read/write, than performing a switch on individual CDB
opcode.
--nab
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html