Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+51 -83
+38 -72
fs/nfs/direct.c
··· 64 64 65 65 static struct kmem_cache *nfs_direct_cachep; 66 66 67 - /* 68 - * This represents a set of asynchronous requests that we're waiting on 69 - */ 70 - struct nfs_direct_mirror { 71 - ssize_t count; 72 - }; 73 - 74 67 struct nfs_direct_req { 75 68 struct kref kref; /* release manager */ 76 69 ··· 76 83 /* completion state */ 77 84 atomic_t io_count; /* i/os we're waiting for */ 78 85 spinlock_t lock; /* protect completion state */ 79 - 80 - struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX]; 81 - int mirror_count; 82 86 83 87 loff_t io_start; /* Start offset for I/O */ 84 88 ssize_t count, /* bytes actually processed */ ··· 113 123 } 114 124 115 125 static void 116 - nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) 126 + nfs_direct_handle_truncated(struct nfs_direct_req *dreq, 127 + const struct nfs_pgio_header *hdr, 128 + ssize_t dreq_len) 117 129 { 118 - int i; 119 - ssize_t count; 130 + if (!(test_bit(NFS_IOHDR_ERROR, &hdr->flags) || 131 + test_bit(NFS_IOHDR_EOF, &hdr->flags))) 132 + return; 133 + if (dreq->max_count >= dreq_len) { 134 + dreq->max_count = dreq_len; 135 + if (dreq->count > dreq_len) 136 + dreq->count = dreq_len; 120 137 121 - WARN_ON_ONCE(dreq->count >= dreq->max_count); 122 - 123 - if (dreq->mirror_count == 1) { 124 - dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes; 125 - dreq->count += hdr->good_bytes; 126 - } else { 127 - /* mirrored writes */ 128 - count = dreq->mirrors[hdr->pgio_mirror_idx].count; 129 - if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { 130 - count = hdr->io_start + hdr->good_bytes - dreq->io_start; 131 - dreq->mirrors[hdr->pgio_mirror_idx].count = count; 132 - } 133 - /* update the dreq->count by finding the minimum agreed count from all 134 - * mirrors */ 135 - count = dreq->mirrors[0].count; 136 - 137 - for (i = 1; i < dreq->mirror_count; i++) 138 - count = min(count, dreq->mirrors[i].count); 139 - 140 - dreq->count = count; 138 + if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) 139 + dreq->error = hdr->error; 140 + else /* Clear outstanding error if this is EOF */ 141 + dreq->error = 0; 141 142 } 143 + } 144 + 145 + static void 146 + nfs_direct_count_bytes(struct nfs_direct_req *dreq, 147 + const struct nfs_pgio_header *hdr) 148 + { 149 + loff_t hdr_end = hdr->io_start + hdr->good_bytes; 150 + ssize_t dreq_len = 0; 151 + 152 + if (hdr_end > dreq->io_start) 153 + dreq_len = hdr_end - dreq->io_start; 154 + 155 + nfs_direct_handle_truncated(dreq, hdr, dreq_len); 156 + 157 + if (dreq_len > dreq->max_count) 158 + dreq_len = dreq->max_count; 159 + 160 + if (dreq->count < dreq_len) 161 + dreq->count = dreq_len; 142 162 } 143 163 144 164 /* ··· 293 293 cinfo->completion_ops = &nfs_direct_commit_completion_ops; 294 294 } 295 295 296 - static inline void nfs_direct_setup_mirroring(struct nfs_direct_req *dreq, 297 - struct nfs_pageio_descriptor *pgio, 298 - struct nfs_page *req) 299 - { 300 - int mirror_count = 1; 301 - 302 - if (pgio->pg_ops->pg_get_mirror_count) 303 - mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req); 304 - 305 - dreq->mirror_count = mirror_count; 306 - } 307 - 308 296 static inline struct nfs_direct_req *nfs_direct_req_alloc(void) 309 297 { 310 298 struct nfs_direct_req *dreq; ··· 307 319 INIT_LIST_HEAD(&dreq->mds_cinfo.list); 308 320 dreq->verf.committed = NFS_INVALID_STABLE_HOW; /* not set yet */ 309 321 INIT_WORK(&dreq->work, nfs_direct_write_schedule_work); 310 - dreq->mirror_count = 1; 311 322 spin_lock_init(&dreq->lock); 312 323 313 324 return dreq; ··· 389 402 struct nfs_direct_req *dreq = hdr->dreq; 390 403 391 404 spin_lock(&dreq->lock); 392 - if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) 393 - dreq->error = hdr->error; 394 - 395 405 if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { 396 406 spin_unlock(&dreq->lock); 397 407 goto out_put; 398 408 } 399 409 400 - if (hdr->good_bytes != 0) 401 - nfs_direct_good_bytes(dreq, hdr); 402 - 403 - if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) 404 - dreq->error = 0; 405 - 410 + nfs_direct_count_bytes(dreq, hdr); 406 411 spin_unlock(&dreq->lock); 407 412 408 413 while (!list_empty(&hdr->pages)) { ··· 625 646 LIST_HEAD(reqs); 626 647 struct nfs_commit_info cinfo; 627 648 LIST_HEAD(failed); 628 - int i; 629 649 630 650 nfs_init_cinfo_from_dreq(&cinfo, dreq); 631 651 nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); 632 652 633 653 dreq->count = 0; 654 + dreq->max_count = 0; 655 + list_for_each_entry(req, &reqs, wb_list) 656 + dreq->max_count += req->wb_bytes; 634 657 dreq->verf.committed = NFS_INVALID_STABLE_HOW; 635 658 nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); 636 - for (i = 0; i < dreq->mirror_count; i++) 637 - dreq->mirrors[i].count = 0; 638 659 get_dreq(dreq); 639 660 640 661 nfs_pageio_init_write(&desc, dreq->inode, FLUSH_STABLE, false, 641 662 &nfs_direct_write_completion_ops); 642 663 desc.pg_dreq = dreq; 643 - 644 - req = nfs_list_entry(reqs.next); 645 - nfs_direct_setup_mirroring(dreq, &desc, req); 646 - if (desc.pg_error < 0) { 647 - list_splice_init(&reqs, &failed); 648 - goto out_failed; 649 - } 650 664 651 665 list_for_each_entry_safe(req, tmp, &reqs, wb_list) { 652 666 /* Bump the transmission count */ ··· 658 686 } 659 687 nfs_pageio_complete(&desc); 660 688 661 - out_failed: 662 689 while (!list_empty(&failed)) { 663 690 req = nfs_list_entry(failed.next); 664 691 nfs_list_remove_request(req); ··· 762 791 nfs_init_cinfo_from_dreq(&cinfo, dreq); 763 792 764 793 spin_lock(&dreq->lock); 765 - 766 - if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) 767 - dreq->error = hdr->error; 768 - 769 794 if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { 770 795 spin_unlock(&dreq->lock); 771 796 goto out_put; 772 797 } 773 798 799 + nfs_direct_count_bytes(dreq, hdr); 774 800 if (hdr->good_bytes != 0) { 775 - nfs_direct_good_bytes(dreq, hdr); 776 801 if (nfs_write_need_commit(hdr)) { 777 802 if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) 778 803 request_commit = true; ··· 890 923 break; 891 924 } 892 925 893 - nfs_direct_setup_mirroring(dreq, &desc, req); 894 926 if (desc.pg_error < 0) { 895 927 nfs_free_request(req); 896 928 result = desc.pg_error;
+1
fs/nfs/nfs4proc.c
··· 6106 6106 6107 6107 status = nfs4_call_sync_custom(&task_setup_data); 6108 6108 if (setclientid.sc_cred) { 6109 + kfree(clp->cl_acceptor); 6109 6110 clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred); 6110 6111 put_rpccred(setclientid.sc_cred); 6111 6112 }
+3 -2
fs/nfs/write.c
··· 786 786 struct nfs_inode *nfsi = NFS_I(inode); 787 787 struct nfs_page *head; 788 788 789 - atomic_long_dec(&nfsi->nrequests); 790 789 if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) { 791 790 head = req->wb_head; 792 791 ··· 798 799 spin_unlock(&mapping->private_lock); 799 800 } 800 801 801 - if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) 802 + if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) { 802 803 nfs_release_request(req); 804 + atomic_long_dec(&nfsi->nrequests); 805 + } 803 806 } 804 807 805 808 static void
+1
include/linux/sunrpc/xprtsock.h
··· 61 61 struct mutex recv_mutex; 62 62 struct sockaddr_storage srcaddr; 63 63 unsigned short srcport; 64 + int xprt_err; 64 65 65 66 /* 66 67 * UDP socket buffer size parameters
+8 -9
net/sunrpc/xprtsock.c
··· 1249 1249 { 1250 1250 struct sock_xprt *transport; 1251 1251 struct rpc_xprt *xprt; 1252 - int err; 1253 1252 1254 1253 read_lock_bh(&sk->sk_callback_lock); 1255 1254 if (!(xprt = xprt_from_sock(sk))) 1256 1255 goto out; 1257 1256 1258 1257 transport = container_of(xprt, struct sock_xprt, xprt); 1259 - err = -sk->sk_err; 1260 - if (err == 0) 1258 + transport->xprt_err = -sk->sk_err; 1259 + if (transport->xprt_err == 0) 1261 1260 goto out; 1262 1261 dprintk("RPC: xs_error_report client %p, error=%d...\n", 1263 - xprt, -err); 1264 - trace_rpc_socket_error(xprt, sk->sk_socket, err); 1262 + xprt, -transport->xprt_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 1267 xs_run_error_worker(transport, XPRT_SOCK_WAKE_ERROR); 1266 1268 out: 1267 1269 read_unlock_bh(&sk->sk_callback_lock); ··· 2478 2476 static void xs_wake_error(struct sock_xprt *transport) 2479 2477 { 2480 2478 int sockerr; 2481 - int sockerr_len = sizeof(sockerr); 2482 2479 2483 2480 if (!test_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state)) 2484 2481 return; ··· 2486 2485 goto out; 2487 2486 if (!test_and_clear_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state)) 2488 2487 goto out; 2489 - if (kernel_getsockopt(transport->sock, SOL_SOCKET, SO_ERROR, 2490 - (char *)&sockerr, &sockerr_len) != 0) 2491 - goto out; 2488 + sockerr = xchg(&transport->xprt_err, 0); 2492 2489 if (sockerr < 0) 2493 2490 xprt_wake_pending_tasks(&transport->xprt, sockerr); 2494 2491 out: