SUNRPC: Ensure xs_reset_transport() resets the close connection flags
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sun, 8 Feb 2015 23:35:25 +0000 (18:35 -0500)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Mon, 9 Feb 2015 02:47:28 +0000 (21:47 -0500)
Otherwise, we may end up looping.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
net/sunrpc/xprtsock.c

index ea1882f97912bd1fefed8f4e5d802f3d8fb16ab8..0fa7ed93dc20537ca06479207aa8d48d48f22f92 100644 (file)
@@ -803,10 +803,21 @@ static void xs_error_report(struct sock *sk)
        read_unlock_bh(&sk->sk_callback_lock);
 }
 
+static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
+{
+       smp_mb__before_atomic();
+       clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
+       clear_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
+       clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
+       clear_bit(XPRT_CLOSING, &xprt->state);
+       smp_mb__after_atomic();
+}
+
 static void xs_reset_transport(struct sock_xprt *transport)
 {
        struct socket *sock = transport->sock;
        struct sock *sk = transport->inet;
+       struct rpc_xprt *xprt = &transport->xprt;
 
        if (sk == NULL)
                return;
@@ -819,8 +830,9 @@ static void xs_reset_transport(struct sock_xprt *transport)
 
        xs_restore_old_callbacks(transport, sk);
        write_unlock_bh(&sk->sk_callback_lock);
+       xs_sock_reset_connection_flags(xprt);
 
-       trace_rpc_socket_close(&transport->xprt, sock);
+       trace_rpc_socket_close(xprt, sock);
        sock_release(sock);
 }
 
@@ -845,11 +857,6 @@ static void xs_close(struct rpc_xprt *xprt)
        xs_reset_transport(transport);
        xprt->reestablish_timeout = 0;
 
-       smp_mb__before_atomic();
-       clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
-       clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
-       clear_bit(XPRT_CLOSING, &xprt->state);
-       smp_mb__after_atomic();
        xprt_disconnect_done(xprt);
 }
 
@@ -1455,16 +1462,6 @@ static void xs_tcp_cancel_linger_timeout(struct rpc_xprt *xprt)
        xprt_clear_connecting(xprt);
 }
 
-static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
-{
-       smp_mb__before_atomic();
-       clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
-       clear_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
-       clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
-       clear_bit(XPRT_CLOSING, &xprt->state);
-       smp_mb__after_atomic();
-}
-
 static void xs_sock_mark_closed(struct rpc_xprt *xprt)
 {
        xs_sock_reset_connection_flags(xprt);