diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-11-05 17:42:39 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-01-30 02:05:25 -0500 |
commit | 3b948ae5be5e22532584113e2e02029519bbad8f (patch) | |
tree | 3bfa346bfbc9808c164d3d36af29a2090a5a0628 | |
parent | 67a391d72ca7efb387c30ec761a487e50a3ff085 (diff) |
SUNRPC: Allow the client to detect if the TCP connection is closed
Add an xprt->state bit to enable the TCP ->state_change() method to signal
whether or not the TCP connection is in the process of closing down.
This will to be used by the reconnection logic in a separate patch.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | include/linux/sunrpc/xprt.h | 1 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 24 |
2 files changed, 22 insertions, 3 deletions
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 6f524a9e7fd0..afb9e6ad7fe0 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
@@ -257,6 +257,7 @@ void xprt_force_disconnect(struct rpc_xprt *xprt); | |||
257 | #define XPRT_CLOSE_WAIT (3) | 257 | #define XPRT_CLOSE_WAIT (3) |
258 | #define XPRT_BOUND (4) | 258 | #define XPRT_BOUND (4) |
259 | #define XPRT_BINDING (5) | 259 | #define XPRT_BINDING (5) |
260 | #define XPRT_CLOSING (6) | ||
260 | 261 | ||
261 | static inline void xprt_set_connected(struct rpc_xprt *xprt) | 262 | static inline void xprt_set_connected(struct rpc_xprt *xprt) |
262 | { | 263 | { |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index b5544514ee57..721c5419765e 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -758,7 +758,9 @@ static void xs_close(struct rpc_xprt *xprt) | |||
758 | sock_release(sock); | 758 | sock_release(sock); |
759 | clear_close_wait: | 759 | clear_close_wait: |
760 | smp_mb__before_clear_bit(); | 760 | smp_mb__before_clear_bit(); |
761 | clear_bit(XPRT_CONNECTED, &xprt->state); | ||
761 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | 762 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); |
763 | clear_bit(XPRT_CLOSING, &xprt->state); | ||
762 | smp_mb__after_clear_bit(); | 764 | smp_mb__after_clear_bit(); |
763 | } | 765 | } |
764 | 766 | ||
@@ -1118,12 +1120,28 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1118 | } | 1120 | } |
1119 | spin_unlock_bh(&xprt->transport_lock); | 1121 | spin_unlock_bh(&xprt->transport_lock); |
1120 | break; | 1122 | break; |
1121 | case TCP_SYN_SENT: | 1123 | case TCP_FIN_WAIT1: |
1122 | case TCP_SYN_RECV: | 1124 | /* The client initiated a shutdown of the socket */ |
1125 | set_bit(XPRT_CLOSING, &xprt->state); | ||
1126 | smp_mb__before_clear_bit(); | ||
1127 | clear_bit(XPRT_CONNECTED, &xprt->state); | ||
1128 | smp_mb__after_clear_bit(); | ||
1123 | break; | 1129 | break; |
1124 | case TCP_CLOSE_WAIT: | 1130 | case TCP_CLOSE_WAIT: |
1131 | /* The server initiated a shutdown of the socket */ | ||
1132 | set_bit(XPRT_CLOSING, &xprt->state); | ||
1125 | xprt_force_disconnect(xprt); | 1133 | xprt_force_disconnect(xprt); |
1126 | default: | 1134 | break; |
1135 | case TCP_LAST_ACK: | ||
1136 | smp_mb__before_clear_bit(); | ||
1137 | clear_bit(XPRT_CONNECTED, &xprt->state); | ||
1138 | smp_mb__after_clear_bit(); | ||
1139 | break; | ||
1140 | case TCP_CLOSE: | ||
1141 | smp_mb__before_clear_bit(); | ||
1142 | clear_bit(XPRT_CLOSING, &xprt->state); | ||
1143 | smp_mb__after_clear_bit(); | ||
1144 | /* Mark transport as closed and wake up all pending tasks */ | ||
1127 | xprt_disconnect(xprt); | 1145 | xprt_disconnect(xprt); |
1128 | } | 1146 | } |
1129 | out: | 1147 | out: |