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-6.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client fixes from Trond Myklebust:

- fix a use after free in nfs_direct_join_group() (Cc: stable)

- fix sysfs server name memory leak

- fix lock recovery hang in NFSv4.0

- fix page free in the error path for nfs42_proc_getxattr() and
__nfs4_get_acl_uncached()

- SUNRPC/rdma: fix receive buffer dma-mapping after a server disconnect

* tag 'nfs-for-6.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
xprtrdma: Remap Receive buffers after a reconnect
NFSv4: fix out path in __nfs4_get_acl_uncached
NFSv4.2: fix error handling in nfs42_proc_getxattr
NFS: Fix sysfs server name memory leak
NFS: Fix a use after free in nfs_direct_join_group()
NFSv4: Fix dropped lock for racing OPEN and delegation return

+35 -23
+16 -10
fs/nfs/direct.c
··· 472 472 return result; 473 473 } 474 474 475 - static void 476 - nfs_direct_join_group(struct list_head *list, struct inode *inode) 475 + static void nfs_direct_join_group(struct list_head *list, struct inode *inode) 477 476 { 478 - struct nfs_page *req, *next; 477 + struct nfs_page *req, *subreq; 479 478 480 479 list_for_each_entry(req, list, wb_list) { 481 - if (req->wb_head != req || req->wb_this_page == req) 480 + if (req->wb_head != req) 482 481 continue; 483 - for (next = req->wb_this_page; 484 - next != req->wb_head; 485 - next = next->wb_this_page) { 486 - nfs_list_remove_request(next); 487 - nfs_release_request(next); 488 - } 482 + subreq = req->wb_this_page; 483 + if (subreq == req) 484 + continue; 485 + do { 486 + /* 487 + * Remove subrequests from this list before freeing 488 + * them in the call to nfs_join_page_group(). 489 + */ 490 + if (!list_empty(&subreq->wb_list)) { 491 + nfs_list_remove_request(subreq); 492 + nfs_release_request(subreq); 493 + } 494 + } while ((subreq = subreq->wb_this_page) != req); 489 495 nfs_join_page_group(req, inode); 490 496 } 491 497 }
+2 -3
fs/nfs/nfs42proc.c
··· 1377 1377 for (i = 0; i < np; i++) { 1378 1378 pages[i] = alloc_page(GFP_KERNEL); 1379 1379 if (!pages[i]) { 1380 - np = i + 1; 1381 1380 err = -ENOMEM; 1382 1381 goto out; 1383 1382 } ··· 1400 1401 } while (exception.retry); 1401 1402 1402 1403 out: 1403 - while (--np >= 0) 1404 - __free_page(pages[np]); 1404 + while (--i >= 0) 1405 + __free_page(pages[i]); 1405 1406 kfree(pages); 1406 1407 1407 1408 return err;
+10 -4
fs/nfs/nfs4proc.c
··· 6004 6004 out_ok: 6005 6005 ret = res.acl_len; 6006 6006 out_free: 6007 - for (i = 0; i < npages; i++) 6008 - if (pages[i]) 6009 - __free_page(pages[i]); 6007 + while (--i >= 0) 6008 + __free_page(pages[i]); 6010 6009 if (res.acl_scratch) 6011 6010 __free_page(res.acl_scratch); 6012 6011 kfree(pages); ··· 7180 7181 } else if (!nfs4_update_lock_stateid(lsp, &data->res.stateid)) 7181 7182 goto out_restart; 7182 7183 break; 7183 - case -NFS4ERR_BAD_STATEID: 7184 7184 case -NFS4ERR_OLD_STATEID: 7185 + if (data->arg.new_lock_owner != 0 && 7186 + nfs4_refresh_open_old_stateid(&data->arg.open_stateid, 7187 + lsp->ls_state)) 7188 + goto out_restart; 7189 + if (nfs4_refresh_lock_old_stateid(&data->arg.lock_stateid, lsp)) 7190 + goto out_restart; 7191 + fallthrough; 7192 + case -NFS4ERR_BAD_STATEID: 7185 7193 case -NFS4ERR_STALE_STATEID: 7186 7194 case -NFS4ERR_EXPIRED: 7187 7195 if (data->arg.new_lock_owner != 0) {
+3 -1
fs/nfs/sysfs.c
··· 345 345 int ret = -ENOMEM; 346 346 347 347 s = kasprintf(GFP_KERNEL, "server-%d", server->s_sysfs_id); 348 - if (s) 348 + if (s) { 349 349 ret = kobject_rename(&server->kobj, s); 350 + kfree(s); 351 + } 350 352 if (ret < 0) 351 353 pr_warn("NFS: rename sysfs %s failed (%d)\n", 352 354 server->kobj.name, ret);
+4 -5
net/sunrpc/xprtrdma/verbs.c
··· 935 935 if (!rep->rr_rdmabuf) 936 936 goto out_free; 937 937 938 - if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf)) 939 - goto out_free_regbuf; 940 - 941 938 rep->rr_cid.ci_completion_id = 942 939 atomic_inc_return(&r_xprt->rx_ep->re_completion_ids); 943 940 ··· 953 956 spin_unlock(&buf->rb_lock); 954 957 return rep; 955 958 956 - out_free_regbuf: 957 - rpcrdma_regbuf_free(rep->rr_rdmabuf); 958 959 out_free: 959 960 kfree(rep); 960 961 out: ··· 1358 1363 rep = rpcrdma_rep_create(r_xprt, temp); 1359 1364 if (!rep) 1360 1365 break; 1366 + if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf)) { 1367 + rpcrdma_rep_put(buf, rep); 1368 + break; 1369 + } 1361 1370 1362 1371 rep->rr_cid.ci_queue_id = ep->re_attr.recv_cq->res.id; 1363 1372 trace_xprtrdma_post_recv(rep);