]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.fixes/libiscsi-fix-nop-response-reply-and-session-cleanup.patch
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / libiscsi-fix-nop-response-reply-and-session-cleanup.patch
CommitLineData
00e5a55c
BS
1From: Mike Christie <michaelc@cs.wisc.edu>
2Date: Tue, 28 Apr 2009 13:38:18 -0400
3Subject: libiscsi: fix nop response/reply and session cleanup race
4References: bnc#499558
5
6If we are responding to a nop from the target by sending our nop,
7and the session is getting torn down, then iscsi_start_session_recovery
8could set the conn stop bits while the recv path is sending the nop
9response and we will hit the bug ons in __iscsi_conn_send_pdu.
10
11This has us check the state in __iscsi_conn_send_pdu and fail all
12incoming mgmt IO if we are not logged in and if the pdu is not login
13related. It also changes the ordering of the setting of conn stop state
14bits so they are set after the session state is set (both are set under
15the session lock).
16
17Acked-by: Jean Delvare <jdelvare@suse.de>
18---
19 drivers/scsi/libiscsi.c | 11 ++++++++---
20 1 file changed, 8 insertions(+), 3 deletions(-)
21
22--- a/drivers/scsi/libiscsi.c
23+++ b/drivers/scsi/libiscsi.c
24@@ -502,6 +502,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn
25 */
26 task = conn->login_task;
27 else {
28+ if (session->state != ISCSI_STATE_LOGGED_IN)
29+ return NULL;
30+
31 BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
32 BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
33
34@@ -2414,8 +2417,6 @@ static void iscsi_start_session_recovery
35 {
36 int old_stop_stage;
37
38- del_timer_sync(&conn->transport_timer);
39-
40 mutex_lock(&session->eh_mutex);
41 spin_lock_bh(&session->lock);
42 if (conn->stop_stage == STOP_CONN_TERM) {
43@@ -2433,13 +2434,17 @@ static void iscsi_start_session_recovery
44 session->state = ISCSI_STATE_TERMINATE;
45 else if (conn->stop_stage != STOP_CONN_RECOVER)
46 session->state = ISCSI_STATE_IN_RECOVERY;
47+ spin_unlock_bh(&session->lock);
48
49+ del_timer_sync(&conn->transport_timer);
50+ iscsi_suspend_tx(conn);
51+
52+ spin_lock_bh(&session->lock);
53 old_stop_stage = conn->stop_stage;
54 conn->stop_stage = flag;
55 conn->c_stage = ISCSI_CONN_STOPPED;
56 spin_unlock_bh(&session->lock);
57
58- iscsi_suspend_tx(conn);
59 /*
60 * for connection level recovery we should not calculate
61 * header digest. conn->hdr_size used for optimization