aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-02-09 09:41:32 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-02-09 11:27:42 -0500
commitb70ae915e4282854fb7864519e5ec559ab2de7c3 (patch)
treed15ac4bfa2b0367429736104c32d0c85d371fd08 /net/sunrpc
parent9e2b9f37760e129cee053cc7b6e7288acc2a7134 (diff)
SUNRPC: Handle connection reset more efficiently.
If the connection reset is due to an active call on our side, then the state change is sometimes not reported. Catch those instances using xs_error_report() instead. Also remove the xs_tcp_shutdown() call in xs_tcp_send_request() as the change in behaviour makes it redundant. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/xprtsock.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index c72b13e2bdf5..540d542d85e5 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -718,7 +718,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
718 dprintk("RPC: sendmsg returned unrecognized error %d\n", 718 dprintk("RPC: sendmsg returned unrecognized error %d\n",
719 -status); 719 -status);
720 case -ECONNRESET: 720 case -ECONNRESET:
721 xs_tcp_shutdown(xprt);
722 case -ECONNREFUSED: 721 case -ECONNREFUSED:
723 case -ENOTCONN: 722 case -ENOTCONN:
724 case -EADDRINUSE: 723 case -EADDRINUSE:
@@ -774,6 +773,21 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s
774 sk->sk_error_report = transport->old_error_report; 773 sk->sk_error_report = transport->old_error_report;
775} 774}
776 775
776static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
777{
778 smp_mb__before_atomic();
779 clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
780 clear_bit(XPRT_CLOSING, &xprt->state);
781 smp_mb__after_atomic();
782}
783
784static void xs_sock_mark_closed(struct rpc_xprt *xprt)
785{
786 xs_sock_reset_connection_flags(xprt);
787 /* Mark transport as closed and wake up all pending tasks */
788 xprt_disconnect_done(xprt);
789}
790
777/** 791/**
778 * xs_error_report - callback to handle TCP socket state errors 792 * xs_error_report - callback to handle TCP socket state errors
779 * @sk: socket 793 * @sk: socket
@@ -793,6 +807,9 @@ static void xs_error_report(struct sock *sk)
793 err = -sk->sk_err; 807 err = -sk->sk_err;
794 if (err == 0) 808 if (err == 0)
795 goto out; 809 goto out;
810 /* Is this a reset event? */
811 if (sk->sk_state == TCP_CLOSE)
812 xs_sock_mark_closed(xprt);
796 dprintk("RPC: xs_error_report client %p, error=%d...\n", 813 dprintk("RPC: xs_error_report client %p, error=%d...\n",
797 xprt, -err); 814 xprt, -err);
798 trace_rpc_socket_error(xprt, sk->sk_socket, err); 815 trace_rpc_socket_error(xprt, sk->sk_socket, err);
@@ -801,14 +818,6 @@ static void xs_error_report(struct sock *sk)
801 read_unlock_bh(&sk->sk_callback_lock); 818 read_unlock_bh(&sk->sk_callback_lock);
802} 819}
803 820
804static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
805{
806 smp_mb__before_atomic();
807 clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
808 clear_bit(XPRT_CLOSING, &xprt->state);
809 smp_mb__after_atomic();
810}
811
812static void xs_reset_transport(struct sock_xprt *transport) 821static void xs_reset_transport(struct sock_xprt *transport)
813{ 822{
814 struct socket *sock = transport->sock; 823 struct socket *sock = transport->sock;
@@ -1421,13 +1430,6 @@ out:
1421 read_unlock_bh(&sk->sk_callback_lock); 1430 read_unlock_bh(&sk->sk_callback_lock);
1422} 1431}
1423 1432
1424static void xs_sock_mark_closed(struct rpc_xprt *xprt)
1425{
1426 xs_sock_reset_connection_flags(xprt);
1427 /* Mark transport as closed and wake up all pending tasks */
1428 xprt_disconnect_done(xprt);
1429}
1430
1431/** 1433/**
1432 * xs_tcp_state_change - callback to handle TCP socket state changes 1434 * xs_tcp_state_change - callback to handle TCP socket state changes
1433 * @sk: socket whose state has changed 1435 * @sk: socket whose state has changed