From cf340d6d98299f72a4b8376afab999d50f0ca813 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 5 Nov 2007 17:42:39 -0500 Subject: [PATCH] --- yaml --- r: 79575 b: refs/heads/master c: 3b948ae5be5e22532584113e2e02029519bbad8f h: refs/heads/master i: 79573: 55d74a6edab4e2931530b8e0cc8c86eaec9cd09a 79571: b40ea1670be2ed2eb83cae1b71efda3a046a2d82 79567: 1b88247db11dd0577f5ea1a1d111624b6ac24945 v: v3 --- [refs] | 2 +- trunk/include/linux/sunrpc/xprt.h | 1 + trunk/net/sunrpc/xprtsock.c | 24 +++++++++++++++++++++--- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 5a848dd6d65d..1b20a2ffebe7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 67a391d72ca7efb387c30ec761a487e50a3ff085 +refs/heads/master: 3b948ae5be5e22532584113e2e02029519bbad8f diff --git a/trunk/include/linux/sunrpc/xprt.h b/trunk/include/linux/sunrpc/xprt.h index 6f524a9e7fd0..afb9e6ad7fe0 100644 --- a/trunk/include/linux/sunrpc/xprt.h +++ b/trunk/include/linux/sunrpc/xprt.h @@ -257,6 +257,7 @@ void xprt_force_disconnect(struct rpc_xprt *xprt); #define XPRT_CLOSE_WAIT (3) #define XPRT_BOUND (4) #define XPRT_BINDING (5) +#define XPRT_CLOSING (6) static inline void xprt_set_connected(struct rpc_xprt *xprt) { diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c index b5544514ee57..721c5419765e 100644 --- a/trunk/net/sunrpc/xprtsock.c +++ b/trunk/net/sunrpc/xprtsock.c @@ -758,7 +758,9 @@ static void xs_close(struct rpc_xprt *xprt) sock_release(sock); clear_close_wait: smp_mb__before_clear_bit(); + clear_bit(XPRT_CONNECTED, &xprt->state); clear_bit(XPRT_CLOSE_WAIT, &xprt->state); + clear_bit(XPRT_CLOSING, &xprt->state); smp_mb__after_clear_bit(); } @@ -1118,12 +1120,28 @@ static void xs_tcp_state_change(struct sock *sk) } spin_unlock_bh(&xprt->transport_lock); break; - case TCP_SYN_SENT: - case TCP_SYN_RECV: + case TCP_FIN_WAIT1: + /* The client initiated a shutdown of the socket */ + set_bit(XPRT_CLOSING, &xprt->state); + smp_mb__before_clear_bit(); + clear_bit(XPRT_CONNECTED, &xprt->state); + smp_mb__after_clear_bit(); break; case TCP_CLOSE_WAIT: + /* The server initiated a shutdown of the socket */ + set_bit(XPRT_CLOSING, &xprt->state); xprt_force_disconnect(xprt); - default: + break; + case TCP_LAST_ACK: + smp_mb__before_clear_bit(); + clear_bit(XPRT_CONNECTED, &xprt->state); + smp_mb__after_clear_bit(); + break; + case TCP_CLOSE: + smp_mb__before_clear_bit(); + clear_bit(XPRT_CLOSING, &xprt->state); + smp_mb__after_clear_bit(); + /* Mark transport as closed and wake up all pending tasks */ xprt_disconnect(xprt); } out: