aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtsock.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-02-08 15:34:28 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-02-08 21:47:30 -0500
commit4efdd92c921135175a85452cd41273d9e2788db3 (patch)
tree93f7a3e5c6a3fe628df46eb776a35ead8b56e515 /net/sunrpc/xprtsock.c
parentde84d89030fa4efa44c02c96c8b4a8176042c4ff (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.c67
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 */
2109static 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
2130static 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
2156static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) 2103static 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 }
2301out_eagain:
2302 status = -EAGAIN; 2237 status = -EAGAIN;
2303out: 2238out:
2304 xprt_unlock_connect(xprt, transport); 2239 xprt_unlock_connect(xprt, transport);