Skip to content

Commit

Permalink
scsi: target: pscsi: Set SCF_TREAT_READ_AS_NORMAL flag only if there …
Browse files Browse the repository at this point in the history
…is valid data

With tape devices, the SCF_TREAT_READ_AS_NORMAL flag is used by the target
subsystem to mark commands which have both data to return as well as sense
data. But with pscsi, SCF_TREAT_READ_AS_NORMAL can be set even if there is
no data to return. The SCF_TREAT_READ_AS_NORMAL flag causes the target core
to call iscsit data-in callbacks even if there is no data, which iscsit
does not support. This results in iscsit going into an error state
requiring recovery and being unable to complete the command to the
initiator.

This issue can be resolved by fixing pscsi to only set
SCF_TREAT_READ_AS_NORMAL if there is valid data to return alongside the
sense data.

Link: https://lore.kernel.org/r/20220427183250.291881-1-djeffery@redhat.com
Fixes: bd81372 ("scsi: target: transport should handle st FM/EOM/ILI reads")
Reported-by: Scott Hamilton <scott.hamilton@atos.net>
Tested-by: Laurence Oberman <loberman@redhat.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
David Jeffery authored and Martin K. Petersen committed Apr 28, 2022
1 parent faad6ce commit 8be70a8
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions drivers/target/target_core_pscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ static void pscsi_destroy_device(struct se_device *dev)
}

static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status,
unsigned char *req_sense)
unsigned char *req_sense, int valid_data)
{
struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
struct scsi_device *sd = pdv->pdv_sd;
Expand Down Expand Up @@ -681,7 +681,7 @@ static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status,
* back despite framework assumption that a
* check condition means there is no data
*/
if (sd->type == TYPE_TAPE &&
if (sd->type == TYPE_TAPE && valid_data &&
cmd->data_direction == DMA_FROM_DEVICE) {
/*
* is sense data valid, fixed format,
Expand Down Expand Up @@ -1032,19 +1032,19 @@ static void pscsi_req_done(struct request *req, blk_status_t status)
struct se_cmd *cmd = req->end_io_data;
struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
enum sam_status scsi_status = scmd->result & 0xff;
int valid_data = cmd->data_length - scmd->resid_len;
u8 *cdb = cmd->priv;

if (scsi_status != SAM_STAT_GOOD) {
pr_debug("PSCSI Status Byte exception at cmd: %p CDB:"
" 0x%02x Result: 0x%08x\n", cmd, cdb[0], scmd->result);
}

pscsi_complete_cmd(cmd, scsi_status, scmd->sense_buffer);
pscsi_complete_cmd(cmd, scsi_status, scmd->sense_buffer, valid_data);

switch (host_byte(scmd->result)) {
case DID_OK:
target_complete_cmd_with_length(cmd, scsi_status,
cmd->data_length - scmd->resid_len);
target_complete_cmd_with_length(cmd, scsi_status, valid_data);
break;
default:
pr_debug("PSCSI Host Byte exception at cmd: %p CDB:"
Expand Down

0 comments on commit 8be70a8

Please sign in to comment.