aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-02-08 18:35:25 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-02-08 21:47:28 -0500
commit6cc7e908362a9dfec3c821f77ec98b6758592060 (patch)
tree305503853cae950c4f96e18f11efc2688d38512c /net/sunrpc
parent76698b2358de466d23f44eaa1b0c9ebe8206099a (diff)
SUNRPC: Ensure xs_reset_transport() resets the close connection flags
Otherwise, we may end up looping. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/xprtsock.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index ea1882f97912..0fa7ed93dc20 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -803,10 +803,21 @@ static void xs_error_report(struct sock *sk)
803 read_unlock_bh(&sk->sk_callback_lock); 803 read_unlock_bh(&sk->sk_callback_lock);
804} 804}
805 805
806static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
807{
808 smp_mb__before_atomic();
809 clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
810 clear_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
811 clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
812 clear_bit(XPRT_CLOSING, &xprt->state);
813 smp_mb__after_atomic();
814}
815
806static void xs_reset_transport(struct sock_xprt *transport) 816static void xs_reset_transport(struct sock_xprt *transport)
807{ 817{
808 struct socket *sock = transport->sock; 818 struct socket *sock = transport->sock;
809 struct sock *sk = transport->inet; 819 struct sock *sk = transport->inet;
820 struct rpc_xprt *xprt = &transport->xprt;
810 821
811 if (sk == NULL) 822 if (sk == NULL)
812 return; 823 return;
@@ -819,8 +830,9 @@ static void xs_reset_transport(struct sock_xprt *transport)
819 830
820 xs_restore_old_callbacks(transport, sk); 831 xs_restore_old_callbacks(transport, sk);
821 write_unlock_bh(&sk->sk_callback_lock); 832 write_unlock_bh(&sk->sk_callback_lock);
833 xs_sock_reset_connection_flags(xprt);
822 834
823 trace_rpc_socket_close(&transport->xprt, sock); 835 trace_rpc_socket_close(xprt, sock);
824 sock_release(sock); 836 sock_release(sock);
825} 837}
826 838
@@ -845,11 +857,6 @@ static void xs_close(struct rpc_xprt *xprt)
845 xs_reset_transport(transport); 857 xs_reset_transport(transport);
846 xprt->reestablish_timeout = 0; 858 xprt->reestablish_timeout = 0;
847 859
848 smp_mb__before_atomic();
849 clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
850 clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
851 clear_bit(XPRT_CLOSING, &xprt->state);
852 smp_mb__after_atomic();
853 xprt_disconnect_done(xprt); 860 xprt_disconnect_done(xprt);
854} 861}
855 862
@@ -1455,16 +1462,6 @@ static void xs_tcp_cancel_linger_timeout(struct rpc_xprt *xprt)
1455 xprt_clear_connecting(xprt); 1462 xprt_clear_connecting(xprt);
1456} 1463}
1457 1464
1458static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
1459{
1460 smp_mb__before_atomic();
1461 clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
1462 clear_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
1463 clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
1464 clear_bit(XPRT_CLOSING, &xprt->state);
1465 smp_mb__after_atomic();
1466}
1467
1468static void xs_sock_mark_closed(struct rpc_xprt *xprt) 1465static void xs_sock_mark_closed(struct rpc_xprt *xprt)
1469{ 1466{
1470 xs_sock_reset_connection_flags(xprt); 1467 xs_sock_reset_connection_flags(xprt);