Merge tag 'nfs-for-4.18-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:
"Hightlights include:

- fix an rcu deadlock in nfs_delegation_find_inode()

- fix NFSv4 deadlocks due to not freeing the session slot in
layoutget

- don't send layoutreturn if the layout is already invalid

- prevent duplicate XID allocation

- flexfiles: Don't tie up all the rpciod threads in resends"

* tag 'nfs-for-4.18-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
pNFS/flexfiles: Process writeback resends from nfsiod context as well
pNFS/flexfiles: Don't tie up all the rpciod threads in resends
sunrpc: Prevent duplicate XID allocation
pNFS: Don't send layoutreturn if the layout is already invalid
pNFS: Always free the session slot on error in nfs4_layoutget_handle_exception
NFS: Fix an rcu deadlock in nfs_delegation_find_inode()

+59 -16
+3 -1
fs/nfs/delegation.c
··· 883 883 rcu_read_lock(); 884 884 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { 885 885 res = nfs_delegation_find_inode_server(server, fhandle); 886 - if (res != ERR_PTR(-ENOENT)) 886 + if (res != ERR_PTR(-ENOENT)) { 887 + rcu_read_unlock(); 887 888 return res; 889 + } 888 890 } 889 891 rcu_read_unlock(); 890 892 return ERR_PTR(-ENOENT);
+16 -5
fs/nfs/flexfilelayout/flexfilelayout.c
··· 1243 1243 hdr->ds_clp, hdr->lseg, 1244 1244 hdr->pgio_mirror_idx); 1245 1245 1246 + clear_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags); 1247 + clear_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags); 1246 1248 switch (err) { 1247 1249 case -NFS4ERR_RESET_TO_PNFS: 1248 1250 if (ff_layout_choose_best_ds_for_read(hdr->lseg, 1249 1251 hdr->pgio_mirror_idx + 1, 1250 1252 &hdr->pgio_mirror_idx)) 1251 1253 goto out_eagain; 1252 - ff_layout_read_record_layoutstats_done(task, hdr); 1253 - pnfs_read_resend_pnfs(hdr); 1254 + set_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags); 1254 1255 return task->tk_status; 1255 1256 case -NFS4ERR_RESET_TO_MDS: 1256 - ff_layout_reset_read(hdr); 1257 + set_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags); 1257 1258 return task->tk_status; 1258 1259 case -EAGAIN: 1259 1260 goto out_eagain; ··· 1404 1403 struct nfs_pgio_header *hdr = data; 1405 1404 1406 1405 ff_layout_read_record_layoutstats_done(&hdr->task, hdr); 1406 + if (test_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags)) 1407 + pnfs_read_resend_pnfs(hdr); 1408 + else if (test_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags)) 1409 + ff_layout_reset_read(hdr); 1407 1410 pnfs_generic_rw_release(data); 1408 1411 } 1409 1412 ··· 1428 1423 hdr->ds_clp, hdr->lseg, 1429 1424 hdr->pgio_mirror_idx); 1430 1425 1426 + clear_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags); 1427 + clear_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags); 1431 1428 switch (err) { 1432 1429 case -NFS4ERR_RESET_TO_PNFS: 1433 - ff_layout_reset_write(hdr, true); 1430 + set_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags); 1434 1431 return task->tk_status; 1435 1432 case -NFS4ERR_RESET_TO_MDS: 1436 - ff_layout_reset_write(hdr, false); 1433 + set_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags); 1437 1434 return task->tk_status; 1438 1435 case -EAGAIN: 1439 1436 return -EAGAIN; ··· 1582 1575 struct nfs_pgio_header *hdr = data; 1583 1576 1584 1577 ff_layout_write_record_layoutstats_done(&hdr->task, hdr); 1578 + if (test_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags)) 1579 + ff_layout_reset_write(hdr, true); 1580 + else if (test_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags)) 1581 + ff_layout_reset_write(hdr, false); 1585 1582 pnfs_generic_rw_release(data); 1586 1583 } 1587 1584
+26 -7
fs/nfs/nfs4proc.c
··· 3294 3294 struct nfs4_closedata *calldata = data; 3295 3295 struct nfs4_state *state = calldata->state; 3296 3296 struct inode *inode = calldata->inode; 3297 + struct pnfs_layout_hdr *lo; 3297 3298 bool is_rdonly, is_wronly, is_rdwr; 3298 3299 int call_close = 0; 3299 3300 ··· 3336 3335 if (!calldata->lr.roc && nfs4_wait_on_layoutreturn(inode, task)) { 3337 3336 nfs_release_seqid(calldata->arg.seqid); 3338 3337 goto out_wait; 3338 + } 3339 + 3340 + lo = calldata->arg.lr_args ? calldata->arg.lr_args->layout : NULL; 3341 + if (lo && !pnfs_layout_is_valid(lo)) { 3342 + calldata->arg.lr_args = NULL; 3343 + calldata->res.lr_res = NULL; 3339 3344 } 3340 3345 3341 3346 if (calldata->arg.fmode == 0) ··· 5979 5972 static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data) 5980 5973 { 5981 5974 struct nfs4_delegreturndata *d_data; 5975 + struct pnfs_layout_hdr *lo; 5982 5976 5983 5977 d_data = (struct nfs4_delegreturndata *)data; 5984 5978 5985 5979 if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task)) 5986 5980 return; 5981 + 5982 + lo = d_data->args.lr_args ? d_data->args.lr_args->layout : NULL; 5983 + if (lo && !pnfs_layout_is_valid(lo)) { 5984 + d_data->args.lr_args = NULL; 5985 + d_data->res.lr_res = NULL; 5986 + } 5987 5987 5988 5988 nfs4_setup_sequence(d_data->res.server->nfs_client, 5989 5989 &d_data->args.seq_args, ··· 8664 8650 8665 8651 dprintk("--> %s tk_status => %d\n", __func__, -task->tk_status); 8666 8652 8653 + nfs4_sequence_free_slot(&lgp->res.seq_res); 8654 + 8667 8655 switch (nfs4err) { 8668 8656 case 0: 8669 8657 goto out; ··· 8730 8714 goto out; 8731 8715 } 8732 8716 8733 - nfs4_sequence_free_slot(&lgp->res.seq_res); 8734 8717 err = nfs4_handle_exception(server, nfs4err, exception); 8735 8718 if (!status) { 8736 8719 if (exception->retry) ··· 8801 8786 if (IS_ERR(task)) 8802 8787 return ERR_CAST(task); 8803 8788 status = rpc_wait_for_completion_task(task); 8804 - if (status == 0) { 8789 + if (status != 0) 8790 + goto out; 8791 + 8792 + /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */ 8793 + if (task->tk_status < 0 || lgp->res.layoutp->len == 0) { 8805 8794 status = nfs4_layoutget_handle_exception(task, lgp, &exception); 8806 8795 *timeout = exception.timeout; 8807 - } 8808 - 8796 + } else 8797 + lseg = pnfs_layout_process(lgp); 8798 + out: 8809 8799 trace_nfs4_layoutget(lgp->args.ctx, 8810 8800 &lgp->args.range, 8811 8801 &lgp->res.range, 8812 8802 &lgp->res.stateid, 8813 8803 status); 8814 8804 8815 - /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */ 8816 - if (status == 0 && lgp->res.layoutp->len) 8817 - lseg = pnfs_layout_process(lgp); 8818 8805 rpc_put_task(task); 8819 8806 dprintk("<-- %s status=%d\n", __func__, status); 8820 8807 if (status) ··· 8834 8817 &lrp->args.seq_args, 8835 8818 &lrp->res.seq_res, 8836 8819 task); 8820 + if (!pnfs_layout_is_valid(lrp->args.layout)) 8821 + rpc_exit(task, 0); 8837 8822 } 8838 8823 8839 8824 static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
+5
fs/nfs/pnfs.h
··· 801 801 { 802 802 } 803 803 804 + static inline bool pnfs_layout_is_valid(const struct pnfs_layout_hdr *lo) 805 + { 806 + return false; 807 + } 808 + 804 809 #endif /* CONFIG_NFS_V4_1 */ 805 810 806 811 #if IS_ENABLED(CONFIG_NFS_V4_2)
+2
include/linux/nfs_xdr.h
··· 1438 1438 NFS_IOHDR_EOF, 1439 1439 NFS_IOHDR_REDO, 1440 1440 NFS_IOHDR_STAT, 1441 + NFS_IOHDR_RESEND_PNFS, 1442 + NFS_IOHDR_RESEND_MDS, 1441 1443 }; 1442 1444 1443 1445 struct nfs_io_completion;
+7 -3
net/sunrpc/xprt.c
··· 987 987 task->tk_status = -EAGAIN; 988 988 goto out_unlock; 989 989 } 990 - if (!bc_prealloc(req) && !req->rq_xmit_bytes_sent) 991 - req->rq_xid = xprt_alloc_xid(xprt); 992 990 ret = true; 993 991 out_unlock: 994 992 spin_unlock_bh(&xprt->transport_lock); ··· 1296 1298 1297 1299 static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) 1298 1300 { 1299 - return (__force __be32)xprt->xid++; 1301 + __be32 xid; 1302 + 1303 + spin_lock(&xprt->reserve_lock); 1304 + xid = (__force __be32)xprt->xid++; 1305 + spin_unlock(&xprt->reserve_lock); 1306 + return xid; 1300 1307 } 1301 1308 1302 1309 static inline void xprt_init_xid(struct rpc_xprt *xprt) ··· 1319 1316 req->rq_task = task; 1320 1317 req->rq_xprt = xprt; 1321 1318 req->rq_buffer = NULL; 1319 + req->rq_xid = xprt_alloc_xid(xprt); 1322 1320 req->rq_connect_cookie = xprt->connect_cookie - 1; 1323 1321 req->rq_bytes_sent = 0; 1324 1322 req->rq_snd_buf.len = 0;