lkml.org 
[lkml]   [2021]   [Mar]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.11 161/306] scsi: target: core: Add cmd length set before cmd complete
    Date
    From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    From: Aleksandr Miloserdov <a.miloserdov@yadro.com>

    [ Upstream commit 1c73e0c5e54d5f7d77f422a10b03ebe61eaed5ad ]

    TCM doesn't properly handle underflow case for service actions. One way to
    prevent it is to always complete command with
    target_complete_cmd_with_length(), however it requires access to data_sg,
    which is not always available.

    This change introduces target_set_cmd_data_length() function which allows
    to set command data length before completing it.

    Link: https://lore.kernel.org/r/20210209072202.41154-2-a.miloserdov@yadro.com
    Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
    Reviewed-by: Bodo Stroesser <bostroesser@gmail.com>
    Signed-off-by: Aleksandr Miloserdov <a.miloserdov@yadro.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/target/target_core_transport.c | 15 +++++++++++----
    include/target/target_core_backend.h | 1 +
    2 files changed, 12 insertions(+), 4 deletions(-)

    diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
    index fca4bd079d02..8a4d58fdc9fe 100644
    --- a/drivers/target/target_core_transport.c
    +++ b/drivers/target/target_core_transport.c
    @@ -879,11 +879,9 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
    }
    EXPORT_SYMBOL(target_complete_cmd);

    -void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length)
    +void target_set_cmd_data_length(struct se_cmd *cmd, int length)
    {
    - if ((scsi_status == SAM_STAT_GOOD ||
    - cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL) &&
    - length < cmd->data_length) {
    + if (length < cmd->data_length) {
    if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
    cmd->residual_count += cmd->data_length - length;
    } else {
    @@ -893,6 +891,15 @@ void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int len

    cmd->data_length = length;
    }
    +}
    +EXPORT_SYMBOL(target_set_cmd_data_length);
    +
    +void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length)
    +{
    + if (scsi_status == SAM_STAT_GOOD ||
    + cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL) {
    + target_set_cmd_data_length(cmd, length);
    + }

    target_complete_cmd(cmd, scsi_status);
    }
    diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
    index 6336780d83a7..ce2fba49c95d 100644
    --- a/include/target/target_core_backend.h
    +++ b/include/target/target_core_backend.h
    @@ -72,6 +72,7 @@ int transport_backend_register(const struct target_backend_ops *);
    void target_backend_unregister(const struct target_backend_ops *);

    void target_complete_cmd(struct se_cmd *, u8);
    +void target_set_cmd_data_length(struct se_cmd *, int);
    void target_complete_cmd_with_length(struct se_cmd *, u8, int);

    void transport_copy_sense_to_cmd(struct se_cmd *, unsigned char *);
    --
    2.30.1


    \
     
     \ /
      Last update: 2021-03-15 15:39    [W:4.090 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site