Skip to content

Commit b70ae91

Browse files
committed
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 <[email protected]>
1 parent 9e2b9f3 commit b70ae91

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

net/sunrpc/xprtsock.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
718718
dprintk("RPC: sendmsg returned unrecognized error %d\n",
719719
-status);
720720
case -ECONNRESET:
721-
xs_tcp_shutdown(xprt);
722721
case -ECONNREFUSED:
723722
case -ENOTCONN:
724723
case -EADDRINUSE:
@@ -774,6 +773,21 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s
774773
sk->sk_error_report = transport->old_error_report;
775774
}
776775

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+
777791
/**
778792
* xs_error_report - callback to handle TCP socket state errors
779793
* @sk: socket
@@ -793,6 +807,9 @@ static void xs_error_report(struct sock *sk)
793807
err = -sk->sk_err;
794808
if (err == 0)
795809
goto out;
810+
/* Is this a reset event? */
811+
if (sk->sk_state == TCP_CLOSE)
812+
xs_sock_mark_closed(xprt);
796813
dprintk("RPC: xs_error_report client %p, error=%d...\n",
797814
xprt, -err);
798815
trace_rpc_socket_error(xprt, sk->sk_socket, err);
@@ -801,14 +818,6 @@ static void xs_error_report(struct sock *sk)
801818
read_unlock_bh(&sk->sk_callback_lock);
802819
}
803820

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-
812821
static void xs_reset_transport(struct sock_xprt *transport)
813822
{
814823
struct socket *sock = transport->sock;
@@ -1421,13 +1430,6 @@ static void xs_tcp_data_ready(struct sock *sk)
14211430
read_unlock_bh(&sk->sk_callback_lock);
14221431
}
14231432

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-
14311433
/**
14321434
* xs_tcp_state_change - callback to handle TCP socket state changes
14331435
* @sk: socket whose state has changed

0 commit comments

Comments
 (0)