|
@@ -807,13 +807,6 @@ static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
|
|
|
smp_mb__after_atomic();
|
|
|
}
|
|
|
|
|
|
-static void xs_sock_mark_closed(struct rpc_xprt *xprt)
|
|
|
-{
|
|
|
- xs_sock_reset_connection_flags(xprt);
|
|
|
- /* Mark transport as closed and wake up all pending tasks */
|
|
|
- xprt_disconnect_done(xprt);
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* xs_error_report - callback to handle TCP socket state errors
|
|
|
* @sk: socket
|
|
@@ -833,9 +826,6 @@ static void xs_error_report(struct sock *sk)
|
|
|
err = -sk->sk_err;
|
|
|
if (err == 0)
|
|
|
goto out;
|
|
|
- /* Is this a reset event? */
|
|
|
- if (sk->sk_state == TCP_CLOSE)
|
|
|
- xs_sock_mark_closed(xprt);
|
|
|
dprintk("RPC: xs_error_report client %p, error=%d...\n",
|
|
|
xprt, -err);
|
|
|
trace_rpc_socket_error(xprt, sk->sk_socket, err);
|
|
@@ -1078,18 +1068,18 @@ static void xs_udp_data_read_skb(struct rpc_xprt *xprt,
|
|
|
|
|
|
/* Suck it into the iovec, verify checksum if not done by hw. */
|
|
|
if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb)) {
|
|
|
- __UDPX_INC_STATS(sk, UDP_MIB_INERRORS);
|
|
|
spin_lock(&xprt->recv_lock);
|
|
|
+ __UDPX_INC_STATS(sk, UDP_MIB_INERRORS);
|
|
|
goto out_unpin;
|
|
|
}
|
|
|
|
|
|
- __UDPX_INC_STATS(sk, UDP_MIB_INDATAGRAMS);
|
|
|
|
|
|
spin_lock_bh(&xprt->transport_lock);
|
|
|
xprt_adjust_cwnd(xprt, task, copied);
|
|
|
spin_unlock_bh(&xprt->transport_lock);
|
|
|
spin_lock(&xprt->recv_lock);
|
|
|
xprt_complete_rqst(task, copied);
|
|
|
+ __UDPX_INC_STATS(sk, UDP_MIB_INDATAGRAMS);
|
|
|
out_unpin:
|
|
|
xprt_unpin_rqst(rovr);
|
|
|
out_unlock:
|
|
@@ -1655,9 +1645,11 @@ static void xs_tcp_state_change(struct sock *sk)
|
|
|
if (test_and_clear_bit(XPRT_SOCK_CONNECTING,
|
|
|
&transport->sock_state))
|
|
|
xprt_clear_connecting(xprt);
|
|
|
+ clear_bit(XPRT_CLOSING, &xprt->state);
|
|
|
if (sk->sk_err)
|
|
|
xprt_wake_pending_tasks(xprt, -sk->sk_err);
|
|
|
- xs_sock_mark_closed(xprt);
|
|
|
+ /* Trigger the socket release */
|
|
|
+ xs_tcp_force_close(xprt);
|
|
|
}
|
|
|
out:
|
|
|
read_unlock_bh(&sk->sk_callback_lock);
|
|
@@ -2265,14 +2257,19 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt)
|
|
|
{
|
|
|
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
|
|
struct socket *sock = transport->sock;
|
|
|
+ int skst = transport->inet ? transport->inet->sk_state : TCP_CLOSE;
|
|
|
|
|
|
if (sock == NULL)
|
|
|
return;
|
|
|
- if (xprt_connected(xprt)) {
|
|
|
+ switch (skst) {
|
|
|
+ default:
|
|
|
kernel_sock_shutdown(sock, SHUT_RDWR);
|
|
|
trace_rpc_socket_shutdown(xprt, sock);
|
|
|
- } else
|
|
|
+ break;
|
|
|
+ case TCP_CLOSE:
|
|
|
+ case TCP_TIME_WAIT:
|
|
|
xs_reset_transport(transport);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void xs_tcp_set_socket_timeouts(struct rpc_xprt *xprt,
|