1
Subject: [PATCH] SUNRPC: fix shutdown of NFS TCP client socket
2
3
NFS server Duplicate Request Cache (DRC) algorithms rely on NFS clients
1
NFS server Duplicate Request Cache (DRC) algorithms rely on NFS clients
4
reconnecting using the same local TCP port. Unique NFS operations are
2
reconnecting using the same local TCP port. Unique NFS operations are
5
identified by the per-TCP connection set of XIDs. This prevents file
3
identified by the per-TCP connection set of XIDs. This prevents file
6
corruption when non-idempotent NFS operations are retried.
4
corruption when non-idempotent NFS operations are retried.
7
5
...
...
14
the same local port but fails with EADDRNOTAVAIL (99). This forces the
12
the same local port but fails with EADDRNOTAVAIL (99). This forces the
15
socket to use a different local TCP port to reconnect to the remote NFS
13
socket to use a different local TCP port to reconnect to the remote NFS
16
server.
14
server.
17
15
18
State Transition and Events:
16
State Transition and Events:
19
TCP_CLOSING(8)
17
TCP_CLOSE_WAIT(8)
20
TCP_LAST_ACK(9)
18
TCP_LAST_ACK(9)
21
connect(fail EADDRNOTAVAIL(99))
19
connect(fail EADDRNOTAVAIL(99))
22
TCP_CLOSE(7)
20
TCP_CLOSE(7)
23
bind on new port
21
bind on new port
24
connect success
22
connect success
25
23
26
dmesg excerpts showing reconnect switching from local port of 688 to 1014:
24
dmesg excerpts showing reconnect switching from TCP local port of 926 to
27
[590701.200229] NFS: mkdir(0:61/560857152), testQ
25
763 after commit 7c81e6a9d75b:
28
[590701.200231] NFS call mkdir testQ
26
[13354.947854] NFS call mkdir testW
29
[590701.200259] RPC: xs_tcp_send_request(224) = 0
30
[590751.883111] RPC: xs_tcp_state_change client 0000000051f4e000...
31
[590751.883146] RPC: state 8 conn 1 dead 0 zapped 1 sk_shutdown 1
32
[590751.883160] RPC: xs_data_ready...
33
[590751.883232] RPC: xs_tcp_state_change client 0000000051f4e000...
34
[590751.883235] RPC: state 9 conn 0 dead 0 zapped 1 sk_shutdown 3
35
[590751.883238] RPC: xs_tcp_state_change client 0000000051f4e000...
36
[590751.883239] RPC: state 9 conn 0 dead 0 zapped 1 sk_shutdown 3
37
[590751.883283] RPC: xs_connect scheduled xprt 0000000051f4e000
38
[590751.883314] RPC: xs_bind 0.0.0.0:688: ok (0)
39
[590751.883321] RPC: worker connecting xprt 0000000051f4e000 via tcp
40
             to 10.101.1.30 (port 2049)
41
[590751.883330] RPC: 0000000051f4e000 connect status 99 connected 0
42
             sock state 7
43
[590751.883342] RPC: xs_tcp_state_change client 0000000051f4e000...
44
[590751.883343] RPC: state 7 conn 0 dead 0 zapped 1 sk_shutdown 3
45
[590751.883356] RPC: xs_connect scheduled xprt 0000000051f4e000
46
[590751.883383] RPC: xs_bind 0.0.0.0:1014: ok (0)
47
[590751.883388] RPC: worker connecting xprt 0000000051f4e000 via tcp
48
             to 10.101.1.30 (port 2049)
49
[590751.883420] RPC: 0000000051f4e000 connect status 115 connected 0
50
             sock state 2
51
...
27
...
52
28
[13405.654781] RPC: xs_tcp_state_change client 00000000037d0f03...
29
[13405.654813] RPC: state 8 conn 1 dead 0 zapped 1 sk_shutdown 1
30
[13405.654826] RPC: xs_data_ready...
31
[13405.654892] RPC: xs_tcp_state_change client 00000000037d0f03...
32
[13405.654895] RPC: state 9 conn 0 dead 0 zapped 1 sk_shutdown 3
33
[13405.654899] RPC: xs_tcp_state_change client 00000000037d0f03...
34
[13405.654900] RPC: state 9 conn 0 dead 0 zapped 1 sk_shutdown 3
35
[13405.654950] RPC: xs_connect scheduled xprt 00000000037d0f03
36
[13405.654975] RPC: xs_bind 0.0.0.0:926: ok (0)
37
[13405.654980] RPC: worker connecting xprt 00000000037d0f03 via tcp
38
             to 10.101.6.228 (port 2049)
39
[13405.654991] RPC: 00000000037d0f03 connect status 99 connected 0
40
             sock state 7
41
[13405.655001] RPC: xs_tcp_state_change client 00000000037d0f03...
42
[13405.655002] RPC: state 7 conn 0 dead 0 zapped 1 sk_shutdown 3
43
[13405.655024] RPC: xs_connect scheduled xprt 00000000037d0f03
44
[13405.655038] RPC: xs_bind 0.0.0.0:763: ok (0)
45
[13405.655041] RPC: worker connecting xprt 00000000037d0f03 via tcp
46
             to 10.101.6.228 (port 2049)
47
[13405.655065] RPC: 00000000037d0f03 connect status 115 connected 0
48
             sock state 2
53
49
54
State Transition and Events with patch applied:
50
State Transition and Events with patch applied:
55
TCP_CLOSING(8)
51
TCP_CLOSE_WAIT(8)
56
TCP_LAST_ACK(9)
52
TCP_LAST_ACK(9)
57
TCP_CLOSE(7)
53
TCP_CLOSE(7)
58
connect(reuse of port succeeds)
54
connect(reuse of port succeeds)
59
55
60
dmesg excerpts showing reconnect on same port (936):
56
dmesg excerpts showing reconnect on same TCP local port of 936 with patch
57
applied:
61
[ 257.139935] NFS: mkdir(0:59/560857152), testQ
58
[ 257.139935] NFS: mkdir(0:59/560857152), testQ
62
[ 257.139937] NFS call mkdir testQ
59
[ 257.139937] NFS call mkdir testQ
63
...
60
...
64
[ 307.822702] RPC: state 8 conn 1 dead 0 zapped 1 sk_shutdown 1
61
[ 307.822702] RPC: state 8 conn 1 dead 0 zapped 1 sk_shutdown 1
65
[ 307.822714] RPC: xs_data_ready...
62
[ 307.822714] RPC: xs_data_ready...
...
...
84
[ 314.916292] RPC: worker connecting xprt 00000000ce702f14 via tcp
81
[ 314.916292] RPC: worker connecting xprt 00000000ce702f14 via tcp
85
             to 10.101.1.30 (port 2049)
82
             to 10.101.1.30 (port 2049)
86
[ 314.916342] RPC: 00000000ce702f14 connect status 115 connected 0
83
[ 314.916342] RPC: 00000000ce702f14 connect status 115 connected 0
87
             sock state 2
84
             sock state 2
88
85
89
Fixes: 7c81e6a9d75b (SUNRPC: Tweak TCP socket shutdown in the RPC client)
86
Fixes: 7c81e6a9d75b ("SUNRPC: Tweak TCP socket shutdown in the RPC client")
90
Signed-off-by: Siddharth Rajendra Kawar <sikawar@microsoft.com>
87
Signed-off-by: Siddharth Rajendra Kawar <sikawar@microsoft.com>
91
---
88
---
89
Changes in v2:
90
- Fixed definition of TCP state 8 in commit message [Trond Myklebust]
91
- Removed redundant closing of socket [Trond Myklebust]
92
- Changed handling of TCP_LAST_ACK
92
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
93
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
93
index XXXXXXX..XXXXXXX 100644
94
index XXXXXXX..XXXXXXX 100644
94
--- a/net/sunrpc/xprtsock.c
95
--- a/net/sunrpc/xprtsock.c
95
+++ b/net/sunrpc/xprtsock.c
96
+++ b/net/sunrpc/xprtsock.c
96
@@ -XXX,XX +XXX,XX @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt)
97
@@ -XXX,XX +XXX,XX @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt)
98
    switch (skst) {
99
    case TCP_FIN_WAIT1:
100
    case TCP_FIN_WAIT2:
101
+    case TCP_LAST_ACK:
97
        break;
102
        break;
98
    case TCP_ESTABLISHED:
103
    case TCP_ESTABLISHED:
99
    case TCP_CLOSE_WAIT:
104
    case TCP_CLOSE_WAIT:
100
+    case TCP_LAST_ACK:
101
        kernel_sock_shutdown(sock, SHUT_RDWR);
102
        trace_rpc_socket_shutdown(xprt, sock);
103
        break;
diff view generated by jsdifflib