aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-10-11 17:28:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-10-11 17:28:59 -0400
commit1c0cc5f1ae5ee5a6913704c0d75a6e99604ee30a (patch)
treea5fa974b1f5ca64c7e472c98168ecc7d27649e5d /net
parentc6ad7c3ce9800e91d6cc6d2f6f566339ebac5656 (diff)
parentaf84537dbd1b39505d1f3d8023029b4a59666513 (diff)
Merge tag 'nfs-for-5.4-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client bugfixes from Anna Schumaker: "Stable bugfixes: - Fix O_DIRECT accounting of number of bytes read/written # v4.1+ Other fixes: - Fix nfsi->nrequests count error on nfs_inode_remove_request() - Remove redundant mirror tracking in O_DIRECT - Fix leak of clp->cl_acceptor string - Fix race to sk_err after xs_error_report" * tag 'nfs-for-5.4-2' of git://git.linux-nfs.org/projects/anna/linux-nfs: SUNRPC: fix race to sk_err after xs_error_report NFSv4: Fix leak of clp->cl_acceptor string NFS: Remove redundant mirror tracking in O_DIRECT NFS: Fix O_DIRECT accounting of number of bytes read/written nfs: Fix nfsi->nrequests count error on nfs_inode_remove_request
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprtsock.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 9ac88722fa83..70e52f567b2a 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1249,19 +1249,21 @@ static void xs_error_report(struct sock *sk)
1249{ 1249{
1250 struct sock_xprt *transport; 1250 struct sock_xprt *transport;
1251 struct rpc_xprt *xprt; 1251 struct rpc_xprt *xprt;
1252 int err;
1253 1252
1254 read_lock_bh(&sk->sk_callback_lock); 1253 read_lock_bh(&sk->sk_callback_lock);
1255 if (!(xprt = xprt_from_sock(sk))) 1254 if (!(xprt = xprt_from_sock(sk)))
1256 goto out; 1255 goto out;
1257 1256
1258 transport = container_of(xprt, struct sock_xprt, xprt); 1257 transport = container_of(xprt, struct sock_xprt, xprt);
1259 err = -sk->sk_err; 1258 transport->xprt_err = -sk->sk_err;
1260 if (err == 0) 1259 if (transport->xprt_err == 0)
1261 goto out; 1260 goto out;
1262 dprintk("RPC: xs_error_report client %p, error=%d...\n", 1261 dprintk("RPC: xs_error_report client %p, error=%d...\n",
1263 xprt, -err); 1262 xprt, -transport->xprt_err);
1264 trace_rpc_socket_error(xprt, sk->sk_socket, err); 1263 trace_rpc_socket_error(xprt, sk->sk_socket, transport->xprt_err);
1264
1265 /* barrier ensures xprt_err is set before XPRT_SOCK_WAKE_ERROR */
1266 smp_mb__before_atomic();
1265 xs_run_error_worker(transport, XPRT_SOCK_WAKE_ERROR); 1267 xs_run_error_worker(transport, XPRT_SOCK_WAKE_ERROR);
1266 out: 1268 out:
1267 read_unlock_bh(&sk->sk_callback_lock); 1269 read_unlock_bh(&sk->sk_callback_lock);
@@ -2476,7 +2478,6 @@ static void xs_wake_write(struct sock_xprt *transport)
2476static void xs_wake_error(struct sock_xprt *transport) 2478static void xs_wake_error(struct sock_xprt *transport)
2477{ 2479{
2478 int sockerr; 2480 int sockerr;
2479 int sockerr_len = sizeof(sockerr);
2480 2481
2481 if (!test_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state)) 2482 if (!test_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state))
2482 return; 2483 return;
@@ -2485,9 +2486,7 @@ static void xs_wake_error(struct sock_xprt *transport)
2485 goto out; 2486 goto out;
2486 if (!test_and_clear_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state)) 2487 if (!test_and_clear_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state))
2487 goto out; 2488 goto out;
2488 if (kernel_getsockopt(transport->sock, SOL_SOCKET, SO_ERROR, 2489 sockerr = xchg(&transport->xprt_err, 0);
2489 (char *)&sockerr, &sockerr_len) != 0)
2490 goto out;
2491 if (sockerr < 0) 2490 if (sockerr < 0)
2492 xprt_wake_pending_tasks(&transport->xprt, sockerr); 2491 xprt_wake_pending_tasks(&transport->xprt, sockerr);
2493out: 2492out: