+++ /dev/null
-From: Mike Christie <michaelc@cs.wisc.edu>
-Date: Tue, 28 Apr 2009 13:38:18 -0400
-Subject: libiscsi: fix nop response/reply and session cleanup race
-References: bnc#499558
-
-If we are responding to a nop from the target by sending our nop,
-and the session is getting torn down, then iscsi_start_session_recovery
-could set the conn stop bits while the recv path is sending the nop
-response and we will hit the bug ons in __iscsi_conn_send_pdu.
-
-This has us check the state in __iscsi_conn_send_pdu and fail all
-incoming mgmt IO if we are not logged in and if the pdu is not login
-related. It also changes the ordering of the setting of conn stop state
-bits so they are set after the session state is set (both are set under
-the session lock).
-
-Acked-by: Jean Delvare <jdelvare@suse.de>
----
- drivers/scsi/libiscsi.c | 11 ++++++++---
- 1 file changed, 8 insertions(+), 3 deletions(-)
-
---- a/drivers/scsi/libiscsi.c
-+++ b/drivers/scsi/libiscsi.c
-@@ -502,6 +502,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn
- */
- task = conn->login_task;
- else {
-+ if (session->state != ISCSI_STATE_LOGGED_IN)
-+ return NULL;
-+
- BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
- BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
-
-@@ -2414,8 +2417,6 @@ static void iscsi_start_session_recovery
- {
- int old_stop_stage;
-
-- del_timer_sync(&conn->transport_timer);
--
- mutex_lock(&session->eh_mutex);
- spin_lock_bh(&session->lock);
- if (conn->stop_stage == STOP_CONN_TERM) {
-@@ -2433,13 +2434,17 @@ static void iscsi_start_session_recovery
- session->state = ISCSI_STATE_TERMINATE;
- else if (conn->stop_stage != STOP_CONN_RECOVER)
- session->state = ISCSI_STATE_IN_RECOVERY;
-+ spin_unlock_bh(&session->lock);
-
-+ del_timer_sync(&conn->transport_timer);
-+ iscsi_suspend_tx(conn);
-+
-+ spin_lock_bh(&session->lock);
- old_stop_stage = conn->stop_stage;
- conn->stop_stage = flag;
- conn->c_stage = ISCSI_CONN_STOPPED;
- spin_unlock_bh(&session->lock);
-
-- iscsi_suspend_tx(conn);
- /*
- * for connection level recovery we should not calculate
- * header digest. conn->hdr_size used for optimization