lkml.org 
[lkml]   [2020]   [Jun]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.7 183/477] scsi: target: loopback: Fix READ with data and sensebytes
    Date
    From: Bodo Stroesser <bstroesser@ts.fujitsu.com>

    [ Upstream commit c68a56736c129f5dd1632856956f9c3e04bae200 ]

    We use tcm_loop with tape emulations running on tcmu.

    In case application reads a short tape block with a longer READ, or a long
    tape block with a short READ, according to SCC spec data has to be
    tranferred _and_ sensebytes with ILI set and information field containing
    the residual count. Similar problem also exists when using fixed block
    size in READ.

    Up to now tcm_loop is not prepared to handle sensebytes if input data is
    provided, as in tcm_loop_queue_data_in() it only sets SAM_STAT_GOOD and, if
    necessary, the residual count.

    To fix the bug, the same handling for sensebytes as present in
    tcm_loop_queue_status() must be done in tcm_loop_queue_data_in() also.

    After adding this handling, the two function now are nearly identical, so I
    created a single function with two wrappers.

    Link: https://lore.kernel.org/r/20200428182617.32726-1-bstroesser@ts.fujitsu.com
    Signed-off-by: Bodo Stroesser <bstroesser@ts.fujitsu.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/target/loopback/tcm_loop.c | 36 +++++++++++++-----------------
    1 file changed, 15 insertions(+), 21 deletions(-)

    diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
    index 3305b47fdf536..16d5a4e117a27 100644
    --- a/drivers/target/loopback/tcm_loop.c
    +++ b/drivers/target/loopback/tcm_loop.c
    @@ -545,32 +545,15 @@ static int tcm_loop_write_pending(struct se_cmd *se_cmd)
    return 0;
    }

    -static int tcm_loop_queue_data_in(struct se_cmd *se_cmd)
    +static int tcm_loop_queue_data_or_status(const char *func,
    + struct se_cmd *se_cmd, u8 scsi_status)
    {
    struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
    struct tcm_loop_cmd, tl_se_cmd);
    struct scsi_cmnd *sc = tl_cmd->sc;

    pr_debug("%s() called for scsi_cmnd: %p cdb: 0x%02x\n",
    - __func__, sc, sc->cmnd[0]);
    -
    - sc->result = SAM_STAT_GOOD;
    - set_host_byte(sc, DID_OK);
    - if ((se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) ||
    - (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT))
    - scsi_set_resid(sc, se_cmd->residual_count);
    - sc->scsi_done(sc);
    - return 0;
    -}
    -
    -static int tcm_loop_queue_status(struct se_cmd *se_cmd)
    -{
    - struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
    - struct tcm_loop_cmd, tl_se_cmd);
    - struct scsi_cmnd *sc = tl_cmd->sc;
    -
    - pr_debug("%s() called for scsi_cmnd: %p cdb: 0x%02x\n",
    - __func__, sc, sc->cmnd[0]);
    + func, sc, sc->cmnd[0]);

    if (se_cmd->sense_buffer &&
    ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
    @@ -581,7 +564,7 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd)
    sc->result = SAM_STAT_CHECK_CONDITION;
    set_driver_byte(sc, DRIVER_SENSE);
    } else
    - sc->result = se_cmd->scsi_status;
    + sc->result = scsi_status;

    set_host_byte(sc, DID_OK);
    if ((se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) ||
    @@ -591,6 +574,17 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd)
    return 0;
    }

    +static int tcm_loop_queue_data_in(struct se_cmd *se_cmd)
    +{
    + return tcm_loop_queue_data_or_status(__func__, se_cmd, SAM_STAT_GOOD);
    +}
    +
    +static int tcm_loop_queue_status(struct se_cmd *se_cmd)
    +{
    + return tcm_loop_queue_data_or_status(__func__,
    + se_cmd, se_cmd->scsi_status);
    +}
    +
    static void tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd)
    {
    struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-06-23 23:38    [W:4.233 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site