diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-10-11 17:28:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-10-11 17:28:59 -0400 |
commit | 1c0cc5f1ae5ee5a6913704c0d75a6e99604ee30a (patch) | |
tree | a5fa974b1f5ca64c7e472c98168ecc7d27649e5d /net | |
parent | c6ad7c3ce9800e91d6cc6d2f6f566339ebac5656 (diff) | |
parent | af84537dbd1b39505d1f3d8023029b4a59666513 (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.c | 17 |
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) | |||
2476 | static void xs_wake_error(struct sock_xprt *transport) | 2478 | static 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); |
2493 | out: | 2492 | out: |