diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-02-08 15:34:28 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-02-08 21:47:30 -0500 |
commit | 4efdd92c921135175a85452cd41273d9e2788db3 (patch) | |
tree | 93f7a3e5c6a3fe628df46eb776a35ead8b56e515 /net/sunrpc/xprtsock.c | |
parent | de84d89030fa4efa44c02c96c8b4a8176042c4ff (diff) |
SUNRPC: Remove TCP client connection reset hack
Instead we rely on SO_REUSEPORT to provide the reconnection semantics
that we need for NFSv2/v3.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 67 |
1 files changed, 1 insertions, 66 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index e53a5ca03daf..dbf279cd4494 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -796,8 +796,6 @@ static void xs_error_report(struct sock *sk) | |||
796 | dprintk("RPC: xs_error_report client %p, error=%d...\n", | 796 | dprintk("RPC: xs_error_report client %p, error=%d...\n", |
797 | xprt, -err); | 797 | xprt, -err); |
798 | trace_rpc_socket_error(xprt, sk->sk_socket, err); | 798 | trace_rpc_socket_error(xprt, sk->sk_socket, err); |
799 | if (test_bit(XPRT_CONNECTION_REUSE, &xprt->state)) | ||
800 | goto out; | ||
801 | xprt_wake_pending_tasks(xprt, err); | 799 | xprt_wake_pending_tasks(xprt, err); |
802 | out: | 800 | out: |
803 | read_unlock_bh(&sk->sk_callback_lock); | 801 | read_unlock_bh(&sk->sk_callback_lock); |
@@ -2102,57 +2100,6 @@ out: | |||
2102 | xprt_wake_pending_tasks(xprt, status); | 2100 | xprt_wake_pending_tasks(xprt, status); |
2103 | } | 2101 | } |
2104 | 2102 | ||
2105 | /* | ||
2106 | * We need to preserve the port number so the reply cache on the server can | ||
2107 | * find our cached RPC replies when we get around to reconnecting. | ||
2108 | */ | ||
2109 | static void xs_abort_connection(struct sock_xprt *transport) | ||
2110 | { | ||
2111 | int result; | ||
2112 | struct sockaddr any; | ||
2113 | |||
2114 | dprintk("RPC: disconnecting xprt %p to reuse port\n", transport); | ||
2115 | |||
2116 | /* | ||
2117 | * Disconnect the transport socket by doing a connect operation | ||
2118 | * with AF_UNSPEC. This should return immediately... | ||
2119 | */ | ||
2120 | memset(&any, 0, sizeof(any)); | ||
2121 | any.sa_family = AF_UNSPEC; | ||
2122 | result = kernel_connect(transport->sock, &any, sizeof(any), 0); | ||
2123 | trace_rpc_socket_reset_connection(&transport->xprt, | ||
2124 | transport->sock, result); | ||
2125 | if (!result) | ||
2126 | xs_sock_reset_connection_flags(&transport->xprt); | ||
2127 | dprintk("RPC: AF_UNSPEC connect return code %d\n", result); | ||
2128 | } | ||
2129 | |||
2130 | static void xs_tcp_reuse_connection(struct sock_xprt *transport) | ||
2131 | { | ||
2132 | unsigned int state = transport->inet->sk_state; | ||
2133 | |||
2134 | if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) { | ||
2135 | /* we don't need to abort the connection if the socket | ||
2136 | * hasn't undergone a shutdown | ||
2137 | */ | ||
2138 | if (transport->inet->sk_shutdown == 0) | ||
2139 | return; | ||
2140 | dprintk("RPC: %s: TCP_CLOSEd and sk_shutdown set to %d\n", | ||
2141 | __func__, transport->inet->sk_shutdown); | ||
2142 | } | ||
2143 | if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) { | ||
2144 | /* we don't need to abort the connection if the socket | ||
2145 | * hasn't undergone a shutdown | ||
2146 | */ | ||
2147 | if (transport->inet->sk_shutdown == 0) | ||
2148 | return; | ||
2149 | dprintk("RPC: %s: ESTABLISHED/SYN_SENT " | ||
2150 | "sk_shutdown set to %d\n", | ||
2151 | __func__, transport->inet->sk_shutdown); | ||
2152 | } | ||
2153 | xs_abort_connection(transport); | ||
2154 | } | ||
2155 | |||
2156 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 2103 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
2157 | { | 2104 | { |
2158 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 2105 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -2245,18 +2192,6 @@ static void xs_tcp_setup_socket(struct work_struct *work) | |||
2245 | status = PTR_ERR(sock); | 2192 | status = PTR_ERR(sock); |
2246 | goto out; | 2193 | goto out; |
2247 | } | 2194 | } |
2248 | } else { | ||
2249 | int abort_and_exit; | ||
2250 | |||
2251 | abort_and_exit = test_and_clear_bit(XPRT_CONNECTION_ABORT, | ||
2252 | &xprt->state); | ||
2253 | /* "close" the socket, preserving the local port */ | ||
2254 | set_bit(XPRT_CONNECTION_REUSE, &xprt->state); | ||
2255 | xs_tcp_reuse_connection(transport); | ||
2256 | clear_bit(XPRT_CONNECTION_REUSE, &xprt->state); | ||
2257 | |||
2258 | if (abort_and_exit) | ||
2259 | goto out_eagain; | ||
2260 | } | 2195 | } |
2261 | 2196 | ||
2262 | dprintk("RPC: worker connecting xprt %p via %s to " | 2197 | dprintk("RPC: worker connecting xprt %p via %s to " |
@@ -2296,9 +2231,9 @@ static void xs_tcp_setup_socket(struct work_struct *work) | |||
2296 | case -EADDRINUSE: | 2231 | case -EADDRINUSE: |
2297 | case -ENOBUFS: | 2232 | case -ENOBUFS: |
2298 | /* retry with existing socket, after a delay */ | 2233 | /* retry with existing socket, after a delay */ |
2234 | xs_tcp_force_close(xprt); | ||
2299 | goto out; | 2235 | goto out; |
2300 | } | 2236 | } |
2301 | out_eagain: | ||
2302 | status = -EAGAIN; | 2237 | status = -EAGAIN; |
2303 | out: | 2238 | out: |
2304 | xprt_unlock_connect(xprt, transport); | 2239 | xprt_unlock_connect(xprt, transport); |