diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/xprtsock.c | 34 |
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 | ||
776 | static 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 | |||
784 | static 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 | ||
804 | static 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 | |||
812 | static void xs_reset_transport(struct sock_xprt *transport) | 821 | static 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 | ||
1424 | static 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 |