aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-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