Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 669502ff authored by Andy Chittenden's avatar Andy Chittenden Committed by Trond Myklebust
Browse files

SUNRPC: fix NFS client over TCP hangs due to packet loss (Bug 16494)



When reusing a TCP connection, ensure that it's aborted if a previous
shutdown attempt has been made on that connection so that the RPC over
TCP recovery mechanism succeeds.

Signed-off-by: default avatarAndy Chittenden <andyc.bluearc@gmail.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent f6cec0ae
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -1305,10 +1305,11 @@ static void xs_tcp_state_change(struct sock *sk)
	if (!(xprt = xprt_from_sock(sk)))
		goto out;
	dprintk("RPC:       xs_tcp_state_change client %p...\n", xprt);
	dprintk("RPC:       state %x conn %d dead %d zapped %d\n",
	dprintk("RPC:       state %x conn %d dead %d zapped %d sk_shutdown %d\n",
			sk->sk_state, xprt_connected(xprt),
			sock_flag(sk, SOCK_DEAD),
			sock_flag(sk, SOCK_ZAPPED));
			sock_flag(sk, SOCK_ZAPPED),
			sk->sk_shutdown);

	switch (sk->sk_state) {
	case TCP_ESTABLISHED:
@@ -1779,10 +1780,25 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *tra
{
	unsigned int state = transport->inet->sk_state;

	if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED)
	if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) {
		/* we don't need to abort the connection if the socket
		 * hasn't undergone a shutdown
		 */
		if (transport->inet->sk_shutdown == 0)
			return;
	if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT))
		dprintk("RPC:       %s: TCP_CLOSEd and sk_shutdown set to %d\n",
				__func__, transport->inet->sk_shutdown);
	}
	if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) {
		/* we don't need to abort the connection if the socket
		 * hasn't undergone a shutdown
		 */
		if (transport->inet->sk_shutdown == 0)
			return;
		dprintk("RPC:       %s: ESTABLISHED/SYN_SENT "
				"sk_shutdown set to %d\n",
				__func__, transport->inet->sk_shutdown);
	}
	xs_abort_connection(xprt, transport);
}