lkml.org 
[lkml]   [2021]   [Jul]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 28/47] scsi: target: Fix protect handling in WRITE SAME(32)
    Date
    From: Dmitry Bogdanov <d.bogdanov@yadro.com>

    [ Upstream commit 6d8e7e7c932162bccd06872362751b0e1d76f5af ]

    WRITE SAME(32) command handling reads WRPROTECT at the wrong offset in 1st
    byte instead of 10th byte.

    Link: https://lore.kernel.org/r/20210702091655.22818-1-d.bogdanov@yadro.com
    Fixes: afd73f1b60fc ("target: Perform PROTECT sanity checks for WRITE_SAME")
    Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/target/target_core_sbc.c | 35 ++++++++++++++++----------------
    1 file changed, 17 insertions(+), 18 deletions(-)

    diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
    index 608117819366..a2ffa10e5a41 100644
    --- a/drivers/target/target_core_sbc.c
    +++ b/drivers/target/target_core_sbc.c
    @@ -37,7 +37,7 @@
    #include "target_core_alua.h"

    static sense_reason_t
    -sbc_check_prot(struct se_device *, struct se_cmd *, unsigned char *, u32, bool);
    +sbc_check_prot(struct se_device *, struct se_cmd *, unsigned char, u32, bool);
    static sense_reason_t sbc_execute_unmap(struct se_cmd *cmd);

    static sense_reason_t
    @@ -311,14 +311,14 @@ static inline unsigned long long transport_lba_64_ext(unsigned char *cdb)
    }

    static sense_reason_t
    -sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *ops)
    +sbc_setup_write_same(struct se_cmd *cmd, unsigned char flags, struct sbc_ops *ops)
    {
    struct se_device *dev = cmd->se_dev;
    sector_t end_lba = dev->transport->get_blocks(dev) + 1;
    unsigned int sectors = sbc_get_write_same_sectors(cmd);
    sense_reason_t ret;

    - if ((flags[0] & 0x04) || (flags[0] & 0x02)) {
    + if ((flags & 0x04) || (flags & 0x02)) {
    pr_err("WRITE_SAME PBDATA and LBDATA"
    " bits not supported for Block Discard"
    " Emulation\n");
    @@ -340,7 +340,7 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
    }

    /* We always have ANC_SUP == 0 so setting ANCHOR is always an error */
    - if (flags[0] & 0x10) {
    + if (flags & 0x10) {
    pr_warn("WRITE SAME with ANCHOR not supported\n");
    return TCM_INVALID_CDB_FIELD;
    }
    @@ -348,7 +348,7 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
    * Special case for WRITE_SAME w/ UNMAP=1 that ends up getting
    * translated into block discard requests within backend code.
    */
    - if (flags[0] & 0x08) {
    + if (flags & 0x08) {
    if (!ops->execute_unmap)
    return TCM_UNSUPPORTED_SCSI_OPCODE;

    @@ -363,7 +363,7 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
    if (!ops->execute_write_same)
    return TCM_UNSUPPORTED_SCSI_OPCODE;

    - ret = sbc_check_prot(dev, cmd, &cmd->t_task_cdb[0], sectors, true);
    + ret = sbc_check_prot(dev, cmd, flags >> 5, sectors, true);
    if (ret)
    return ret;

    @@ -721,10 +721,9 @@ sbc_set_prot_op_checks(u8 protect, bool fabric_prot, enum target_prot_type prot_
    }

    static sense_reason_t
    -sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
    +sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char protect,
    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;
    @@ -772,7 +771,7 @@ sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
    /* Fallthrough */
    default:
    pr_err("Unable to determine pi_prot_type for CDB: 0x%02x "
    - "PROTECT: 0x%02x\n", cdb[0], protect);
    + "PROTECT: 0x%02x\n", cmd->t_task_cdb[0], protect);
    return TCM_INVALID_CDB_FIELD;
    }

    @@ -847,7 +846,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
    if (sbc_check_dpofua(dev, cmd, cdb))
    return TCM_INVALID_CDB_FIELD;

    - ret = sbc_check_prot(dev, cmd, cdb, sectors, false);
    + ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, false);
    if (ret)
    return ret;

    @@ -861,7 +860,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
    if (sbc_check_dpofua(dev, cmd, cdb))
    return TCM_INVALID_CDB_FIELD;

    - ret = sbc_check_prot(dev, cmd, cdb, sectors, false);
    + ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, false);
    if (ret)
    return ret;

    @@ -875,7 +874,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
    if (sbc_check_dpofua(dev, cmd, cdb))
    return TCM_INVALID_CDB_FIELD;

    - ret = sbc_check_prot(dev, cmd, cdb, sectors, false);
    + ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, false);
    if (ret)
    return ret;

    @@ -896,7 +895,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
    if (sbc_check_dpofua(dev, cmd, cdb))
    return TCM_INVALID_CDB_FIELD;

    - ret = sbc_check_prot(dev, cmd, cdb, sectors, true);
    + ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, true);
    if (ret)
    return ret;

    @@ -910,7 +909,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
    if (sbc_check_dpofua(dev, cmd, cdb))
    return TCM_INVALID_CDB_FIELD;

    - ret = sbc_check_prot(dev, cmd, cdb, sectors, true);
    + ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, true);
    if (ret)
    return ret;

    @@ -924,7 +923,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
    if (sbc_check_dpofua(dev, cmd, cdb))
    return TCM_INVALID_CDB_FIELD;

    - ret = sbc_check_prot(dev, cmd, cdb, sectors, true);
    + ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, true);
    if (ret)
    return ret;

    @@ -983,7 +982,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
    size = sbc_get_size(cmd, 1);
    cmd->t_task_lba = get_unaligned_be64(&cdb[12]);

    - ret = sbc_setup_write_same(cmd, &cdb[10], ops);
    + ret = sbc_setup_write_same(cmd, cdb[10], ops);
    if (ret)
    return ret;
    break;
    @@ -1076,7 +1075,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
    size = sbc_get_size(cmd, 1);
    cmd->t_task_lba = get_unaligned_be64(&cdb[2]);

    - ret = sbc_setup_write_same(cmd, &cdb[1], ops);
    + ret = sbc_setup_write_same(cmd, cdb[1], ops);
    if (ret)
    return ret;
    break;
    @@ -1094,7 +1093,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
    * Follow sbcr26 with WRITE_SAME (10) and check for the existence
    * of byte 1 bit 3 UNMAP instead of original reserved field
    */
    - ret = sbc_setup_write_same(cmd, &cdb[1], ops);
    + ret = sbc_setup_write_same(cmd, cdb[1], ops);
    if (ret)
    return ret;
    break;
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-07-26 17:43    [W:4.484 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site