summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2008-12-06 01:29:59 +0300
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-12-29 20:24:33 +0300
commitf78badb1ae07e7f8b835ab2ea0b456ed3fc4caf4 (patch)
treedff13a13fdfac127542803b7713ea7ebf1196e0f /drivers/scsi
parent73208dfd7ab19f379d73e8a0fbf30f92c203e5e8 (diff)
downloadlinux-f78badb1ae07e7f8b835ab2ea0b456ed3fc4caf4.tar.xz
[SCSI] fc transport: pre-emptively terminate i/o upon dev_loss_tmo timeout
Pre-emptively terminate i/o on the rport if dev_loss_tmo has fired. The desire is to terminate everything, so that the i/o is cleaned up prior to the sdev's being unblocked, thus any outstanding timeouts/aborts are avoided. Also, we do this early enough such that the rport's port_id field is still valid. FCOE libFC code needs this info to find the i/o's to terminate. Signed-off-by: James Smart <james.smart@emulex.com> [michaelc@cs.wisc.edu: remove extra scsi_target_unblock call] Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi_transport_fc.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 1e71abf0607a..062304de4854 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3012,6 +3012,16 @@ fc_timeout_deleted_rport(struct work_struct *work)
rport->port_state = FC_PORTSTATE_NOTPRESENT;
rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
+ /*
+ * Pre-emptively kill I/O rather than waiting for the work queue
+ * item to teardown the starget. (FCOE libFC folks prefer this
+ * and to have the rport_port_id still set when it's done).
+ */
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ fc_terminate_rport_io(rport);
+
+ BUG_ON(rport->port_state != FC_PORTSTATE_NOTPRESENT);
+
/* remove the identifiers that aren't used in the consisting binding */
switch (fc_host->tgtid_bind_type) {
case FC_TGTID_BIND_BY_WWPN:
@@ -3035,9 +3045,6 @@ fc_timeout_deleted_rport(struct work_struct *work)
* went away and didn't come back - we'll remove
* all attached scsi devices.
*/
- spin_unlock_irqrestore(shost->host_lock, flags);
-
- scsi_target_unblock(&rport->dev);
fc_queue_work(shost, &rport->stgt_delete_work);
}