aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2007-12-13 13:43:28 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:28:31 -0500
commitbc436b278776d22eb10e7e75bf3e5257d14550a9 (patch)
tree98e3862e44333ef124becb957a0d0cd88ba24ed9
parentd8bf541e657824cb03effd726ac96e2f4dcf58a5 (diff)
[SCSI] libiscsi: grab eh_mutex during host reset
I thought we may not need the eh mutex during host reset, but that is wrong with the new shutdown code. When start_session_recovery sets the state to terminate then drops the session lock. The scsi eh thread could then grab the session lock see that we are terminating and then return failed to scsi-ml. scsi-ml's eh then owns the command and will do whatever it wants with it. But then the iscsi eh thread could grab the session lock and want to complete the scsi commands that we in the LLD, but it no longer owns them and kaboom. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/libiscsi.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index b7a2b9ad3a97..441e351b4456 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1079,17 +1079,19 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc)
1079 struct iscsi_session *session = iscsi_hostdata(host->hostdata); 1079 struct iscsi_session *session = iscsi_hostdata(host->hostdata);
1080 struct iscsi_conn *conn = session->leadconn; 1080 struct iscsi_conn *conn = session->leadconn;
1081 1081
1082 mutex_lock(&session->eh_mutex);
1082 spin_lock_bh(&session->lock); 1083 spin_lock_bh(&session->lock);
1083 if (session->state == ISCSI_STATE_TERMINATE) { 1084 if (session->state == ISCSI_STATE_TERMINATE) {
1084failed: 1085failed:
1085 debug_scsi("failing host reset: session terminated " 1086 debug_scsi("failing host reset: session terminated "
1086 "[CID %d age %d]\n", conn->id, session->age); 1087 "[CID %d age %d]\n", conn->id, session->age);
1087 spin_unlock_bh(&session->lock); 1088 spin_unlock_bh(&session->lock);
1089 mutex_unlock(&session->eh_mutex);
1088 return FAILED; 1090 return FAILED;
1089 } 1091 }
1090 1092
1091 spin_unlock_bh(&session->lock); 1093 spin_unlock_bh(&session->lock);
1092 1094 mutex_unlock(&session->eh_mutex);
1093 /* 1095 /*
1094 * we drop the lock here but the leadconn cannot be destoyed while 1096 * we drop the lock here but the leadconn cannot be destoyed while
1095 * we are in the scsi eh 1097 * we are in the scsi eh
@@ -1104,13 +1106,14 @@ failed:
1104 if (signal_pending(current)) 1106 if (signal_pending(current))
1105 flush_signals(current); 1107 flush_signals(current);
1106 1108
1109 mutex_lock(&session->eh_mutex);
1107 spin_lock_bh(&session->lock); 1110 spin_lock_bh(&session->lock);
1108 if (session->state == ISCSI_STATE_LOGGED_IN) 1111 if (session->state == ISCSI_STATE_LOGGED_IN)
1109 printk(KERN_INFO "iscsi: host reset succeeded\n"); 1112 printk(KERN_INFO "iscsi: host reset succeeded\n");
1110 else 1113 else
1111 goto failed; 1114 goto failed;
1112 spin_unlock_bh(&session->lock); 1115 spin_unlock_bh(&session->lock);
1113 1116 mutex_unlock(&session->eh_mutex);
1114 return SUCCESS; 1117 return SUCCESS;
1115} 1118}
1116EXPORT_SYMBOL_GPL(iscsi_eh_host_reset); 1119EXPORT_SYMBOL_GPL(iscsi_eh_host_reset);