diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2010-07-22 07:29:49 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-28 10:06:06 -0400 |
commit | c01be6dcb2b5cce4feaf48035be6395e5cd7d47c (patch) | |
tree | b3080a6410e46a6c84bb6315bd56cc9fe085d874 /drivers/scsi/scsi_transport_iscsi.c | |
parent | fe4f0bdeea788a8ac049c097895cb2e4044f18b1 (diff) |
[SCSI] iscsi_transport: wait on session in error handler path
wait for session to come online in eh_device_reset_handler
and eh_target_reset_handler
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: Ravi Anand <ravi.anand@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/scsi_transport_iscsi.c')
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index d4b96623aa59..e84026def1f4 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <scsi/scsi_transport.h> | 30 | #include <scsi/scsi_transport.h> |
31 | #include <scsi/scsi_transport_iscsi.h> | 31 | #include <scsi/scsi_transport_iscsi.h> |
32 | #include <scsi/iscsi_if.h> | 32 | #include <scsi/iscsi_if.h> |
33 | #include <scsi/scsi_cmnd.h> | ||
33 | 34 | ||
34 | #define ISCSI_SESSION_ATTRS 23 | 35 | #define ISCSI_SESSION_ATTRS 23 |
35 | #define ISCSI_CONN_ATTRS 13 | 36 | #define ISCSI_CONN_ATTRS 13 |
@@ -534,6 +535,37 @@ static void iscsi_scan_session(struct work_struct *work) | |||
534 | atomic_dec(&ihost->nr_scans); | 535 | atomic_dec(&ihost->nr_scans); |
535 | } | 536 | } |
536 | 537 | ||
538 | /** | ||
539 | * iscsi_block_scsi_eh - block scsi eh until session state has transistioned | ||
540 | * cmd: scsi cmd passed to scsi eh handler | ||
541 | * | ||
542 | * If the session is down this function will wait for the recovery | ||
543 | * timer to fire or for the session to be logged back in. If the | ||
544 | * recovery timer fires then FAST_IO_FAIL is returned. The caller | ||
545 | * should pass this error value to the scsi eh. | ||
546 | */ | ||
547 | int iscsi_block_scsi_eh(struct scsi_cmnd *cmd) | ||
548 | { | ||
549 | struct iscsi_cls_session *session = | ||
550 | starget_to_session(scsi_target(cmd->device)); | ||
551 | unsigned long flags; | ||
552 | int ret = 0; | ||
553 | |||
554 | spin_lock_irqsave(&session->lock, flags); | ||
555 | while (session->state != ISCSI_SESSION_LOGGED_IN) { | ||
556 | if (session->state == ISCSI_SESSION_FREE) { | ||
557 | ret = FAST_IO_FAIL; | ||
558 | break; | ||
559 | } | ||
560 | spin_unlock_irqrestore(&session->lock, flags); | ||
561 | msleep(1000); | ||
562 | spin_lock_irqsave(&session->lock, flags); | ||
563 | } | ||
564 | spin_unlock_irqrestore(&session->lock, flags); | ||
565 | return ret; | ||
566 | } | ||
567 | EXPORT_SYMBOL_GPL(iscsi_block_scsi_eh); | ||
568 | |||
537 | static void session_recovery_timedout(struct work_struct *work) | 569 | static void session_recovery_timedout(struct work_struct *work) |
538 | { | 570 | { |
539 | struct iscsi_cls_session *session = | 571 | struct iscsi_cls_session *session = |