From: mchristi@redhat.com <mchristi@redhat.com> Date: Wed, 13 May 2009 00:49:40 -0500 Subject: [scsi] force retry of IO when port/session is changing Message-id: 1242193780-19644-1-git-send-email-mchristi@redhat.com O-Subject: [PATCH 1/1] RHEL 5.4: force retry of IO when port/session is changing state Bugzilla: 498281 RH-Acked-by: Tomas Henzl <thenzl@redhat.com> From: Mike Christie <mchristie@redhat.com> This is for BZ 498281. If the iscsi session or fc port is transitioning from their normal states to their recovery states, we want to force the scsi layer to requeue IO that hits the queuecommand during this time. DID_TRANSPORT_DISRUPTED does this, but scsi-ml decrements the retry count which we do not want to happen because we can hit a race where the transport object state is set, but the scsi device state is not yet in the blocked state. The retries can then be used up and the IO failed. This patch was sent upstream here: http://marc.info/?l=linux-scsi&m=124102888915569&w=2 I have tested it with iscsi and fc drivers by pulling cables while IO is being sent to the driver. diff --git a/drivers/scsi/scsi_transport_iscsi2.c b/drivers/scsi/scsi_transport_iscsi2.c index 33f5da4..3f19803 100644 --- a/drivers/scsi/scsi_transport_iscsi2.c +++ b/drivers/scsi/scsi_transport_iscsi2.c @@ -346,7 +346,7 @@ int iscsi2_session_chkready(struct iscsi_cls_session *session) err = 0; break; case ISCSI_SESSION_FAILED: - err = DID_TRANSPORT_DISRUPTED << 16; + err = DID_IMM_RETRY << 16; break; case ISCSI_SESSION_FREE: err = DID_TRANSPORT_FAILFAST << 16; diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index d2c1515..098e5fe 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -516,7 +516,7 @@ fc_remote_port_chkready(struct fc_rport *rport) if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) result = 0; else if (rport->flags & FC_RPORT_DEVLOSS_PENDING) - result = DID_TRANSPORT_DISRUPTED << 16; + result = DID_IMM_RETRY << 16; else result = DID_NO_CONNECT << 16; break; @@ -524,7 +524,7 @@ fc_remote_port_chkready(struct fc_rport *rport) if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT) result = DID_TRANSPORT_FAILFAST << 16; else - result = DID_TRANSPORT_DISRUPTED << 16; + result = DID_IMM_RETRY << 16; break; default: result = DID_NO_CONNECT << 16;