Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: target: pscsi: Set SCF_TREAT_READ_AS_NORMAL flag only if there 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: bd81372065fa ("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>

authored by

David Jeffery and committed by
Martin K. Petersen
8be70a84 faad6ceb

+5 -5
+5 -5
drivers/target/target_core_pscsi.c
··· 588 588 } 589 589 590 590 static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status, 591 - unsigned char *req_sense) 591 + unsigned char *req_sense, int valid_data) 592 592 { 593 593 struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); 594 594 struct scsi_device *sd = pdv->pdv_sd; ··· 681 681 * back despite framework assumption that a 682 682 * check condition means there is no data 683 683 */ 684 - if (sd->type == TYPE_TAPE && 684 + if (sd->type == TYPE_TAPE && valid_data && 685 685 cmd->data_direction == DMA_FROM_DEVICE) { 686 686 /* 687 687 * is sense data valid, fixed format, ··· 1032 1032 struct se_cmd *cmd = req->end_io_data; 1033 1033 struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); 1034 1034 enum sam_status scsi_status = scmd->result & 0xff; 1035 + int valid_data = cmd->data_length - scmd->resid_len; 1035 1036 u8 *cdb = cmd->priv; 1036 1037 1037 1038 if (scsi_status != SAM_STAT_GOOD) { ··· 1040 1039 " 0x%02x Result: 0x%08x\n", cmd, cdb[0], scmd->result); 1041 1040 } 1042 1041 1043 - pscsi_complete_cmd(cmd, scsi_status, scmd->sense_buffer); 1042 + pscsi_complete_cmd(cmd, scsi_status, scmd->sense_buffer, valid_data); 1044 1043 1045 1044 switch (host_byte(scmd->result)) { 1046 1045 case DID_OK: 1047 - target_complete_cmd_with_length(cmd, scsi_status, 1048 - cmd->data_length - scmd->resid_len); 1046 + target_complete_cmd_with_length(cmd, scsi_status, valid_data); 1049 1047 break; 1050 1048 default: 1051 1049 pr_debug("PSCSI Host Byte exception at cmd: %p CDB:"