Skip to content

Commit 8830271

Browse files
Christof SchmittJames Bottomley
authored andcommitted
[SCSI] zfcp: Dont fail SCSI commands when transitioning to blocked fc_rport
If an error occurs that triggers the call to fc_remote_port_delete, ideally this call would happen before any I/O is passed back to the SCSI midlayer through scsi_done. The SCSI midlayer will retry the commands and fc_remote_port_chkready will return the correct status code. But with the delay between calling scsi_done in softirq context and the call to fc_remote_port_delete from the workqueue, there is a window where zfcp returns DID_ERROR. This leads to SCSI error recovery which then leads to offline SCSI devices since all recovery actions will fail with the rport now being blocked. In this window, zfcp has to return DID_IMM_RETRY just as the FC transport class would do in fc_remote_port_chkready for the blocked fc_rport. As soon as the fc_rport is BLOCKED, fc_remote_port_chkready will do the right thing. Additionally, there are two more cases to catch in zfcp_scsi_queuecommand: - After the port has been opened, the unit has to be opened. During this period I/O has to be retried. This can also be handled with DID_IMM_RETRY. - If the access to the unit fails, but the port is good, then this single unit cannot be accessed and I/O to this unit has to fail without involving the FC transport class. Reviewed-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
1 parent 9eae07e commit 8830271

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

drivers/s390/scsi/zfcp_scsi.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,26 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
112112
}
113113

114114
status = atomic_read(&unit->status);
115-
if (unlikely((status & ZFCP_STATUS_COMMON_ERP_FAILED) ||
116-
!(status & ZFCP_STATUS_COMMON_RUNNING))) {
115+
if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) &&
116+
!(atomic_read(&unit->port->status) &
117+
ZFCP_STATUS_COMMON_ERP_FAILED)) {
118+
/* only unit access denied, but port is good
119+
* not covered by FC transport, have to fail here */
117120
zfcp_scsi_command_fail(scpnt, DID_ERROR);
118121
return 0;
119122
}
120123

124+
if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) {
125+
/* This could be either
126+
* open unit pending: this is temporary, will result in
127+
* open unit or ERP_FAILED, so retry command
128+
* call to rport_delete pending: mimic retry from
129+
* fc_remote_port_chkready until rport is BLOCKED
130+
*/
131+
zfcp_scsi_command_fail(scpnt, DID_IMM_RETRY);
132+
return 0;
133+
}
134+
121135
ret = zfcp_fsf_send_fcp_command_task(unit, scpnt);
122136
if (unlikely(ret == -EBUSY))
123137
return SCSI_MLQUEUE_DEVICE_BUSY;

0 commit comments

Comments
 (0)