Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3402

kernel-2.6.18-194.11.1.el5.src.rpm

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;