2021-08-24 15:38:57

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH 1/2] SUNRPC: Simplify socket shutdown when not reusing TCP ports

From: Trond Myklebust <[email protected]>

If we're not required to reuse the TCP port, then we can just
immediately close the socket, and leave the cleanup details to the TCP
layer.

Fixes: e6237b6feb37 ("NFSv4.1: Don't rebind to the same source port when reconnecting to the server")
Signed-off-by: Trond Myklebust <[email protected]>
---
net/sunrpc/xprtsock.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index e573dcecdd66..7e94f1d17edb 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2099,6 +2099,10 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt)

if (sock == NULL)
return;
+ if (!xprt->reuseport) {
+ xs_close(xprt);
+ return;
+ }
switch (skst) {
default:
kernel_sock_shutdown(sock, SHUT_RDWR);
--
2.31.1


2021-08-24 15:39:53

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH 2/2] SUNRPC: Tweak TCP socket shutdown in the RPC client

From: Trond Myklebust <[email protected]>

We only really need to call shutdown() if we're in the ESTABLISHED TCP
state, since that is the only case where the client is initiating a
close of an established connection.

If the socket is in FIN_WAIT1 or FIN_WAIT2, then we've already initiated
socket shutdown and are waiting for the server's reply, so do nothing.

In all other cases where we've already received a FIN from the server,
we should be able to just close the socket.

Signed-off-by: Trond Myklebust <[email protected]>
---
net/sunrpc/xprtsock.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 7e94f1d17edb..b91027d140df 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2104,12 +2104,15 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt)
return;
}
switch (skst) {
- default:
+ case TCP_FIN_WAIT1:
+ case TCP_FIN_WAIT2:
+ break;
+ case TCP_ESTABLISHED:
+ case TCP_CLOSE_WAIT:
kernel_sock_shutdown(sock, SHUT_RDWR);
trace_rpc_socket_shutdown(xprt, sock);
break;
- case TCP_CLOSE:
- case TCP_TIME_WAIT:
+ default:
xs_reset_transport(transport);
}
}
--
2.31.1