]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.fixes/iscsi_tcp-Evaluate-socket-state-in-data_ready
Fix oinkmaster patch.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.fixes / iscsi_tcp-Evaluate-socket-state-in-data_ready
CommitLineData
82094b55
AF
1From: Hannes Reinecke <hare@suse.de>
2Date: Thu, 13 Aug 2009 10:35:43 +0200
3Subject: iscsi_tcp: Evaluate socket state in data_ready()
4X-Git: 523eeac6703a995d58918aaf321f128f75c13108
5References: bnc#472432
6
7The network core will call the state_change() callback
8prior to the data_ready() callback, which might cause
9us to lose a connection state change.
10So we have to evaluate the socket state at the end
11of the data_ready() callback, too.
12
13Signed-off-by: Hannes Reinecke <hare@suse.de>
14Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
15---
16 drivers/scsi/iscsi_tcp.c | 27 ++++++++++++++++++++++++---
17 1 files changed, 24 insertions(+), 3 deletions(-)
18
19diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
20index cfcb8ec..b870bfc 100644
21--- a/drivers/scsi/iscsi_tcp.c
22+++ b/drivers/scsi/iscsi_tcp.c
23@@ -1014,6 +1014,24 @@ error:
24 return 0;
25 }
26
27+/**
28+ * iscsi_sw_sk_state_check - check socket state
29+ * @sk: socket
30+ *
31+ * If the socket is in CLOSE or CLOSE_WAIT we should
32+ * not close the connection if there is still some
33+ * data pending.
34+ */
35+static inline int iscsi_tcp_state_check(struct sock *sk)
36+{
37+ if ((sk->sk_state == TCP_CLOSE_WAIT ||
38+ sk->sk_state == TCP_CLOSE) &&
39+ !atomic_read(&sk->sk_rmem_alloc))
40+ return -ECONNRESET;
41+
42+ return 0;
43+}
44+
45 static void
46 iscsi_tcp_data_ready(struct sock *sk, int flag)
47 {
48@@ -1033,6 +1051,11 @@ iscsi_tcp_data_ready(struct sock *sk, int flag)
49 rd_desc.count = 1;
50 tcp_read_sock(sk, &rd_desc, iscsi_tcp_recv);
51
52+ if (iscsi_tcp_state_check(sk) < 0) {
53+ debug_tcp("iscsi_tcp_data_ready: TCP_CLOSE|TCP_CLOSE_WAIT\n");
54+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
55+ }
56+
57 read_unlock(&sk->sk_callback_lock);
58
59 /* If we had to (atomically) map a highmem page,
60@@ -1053,9 +1076,7 @@ iscsi_tcp_state_change(struct sock *sk)
61 conn = (struct iscsi_conn*)sk->sk_user_data;
62 session = conn->session;
63
64- if ((sk->sk_state == TCP_CLOSE_WAIT ||
65- sk->sk_state == TCP_CLOSE) &&
66- !atomic_read(&sk->sk_rmem_alloc)) {
67+ if (iscsi_tcp_state_check(sk) < 0) {
68 debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n");
69 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
70 }
71--
721.6.0.2
73