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

Pull NFS client updates from Trond Myklebust:
"Bugfixes:

- SUNRPC:
- re-probe the target RPC port after an ECONNRESET error
- handle allocation errors from rpcb_call_async()
- fix a use-after-free condition in rpc_pipefs
- fix up various checks for timeouts

- NFSv4.1:
- Handle NFS4ERR_DELAY errors during session trunking
- fix SP4_MACH_CRED protection for pnfs IO

- NFSv4:
- Ensure that we test all delegations when the server notifies
us that it may have revoked some of them

Features:

- Allow knfsd processes to break out of NFS4ERR_DELAY loops when
re-exporting NFSv4.x by setting appropriate values for the
'delay_retrans' module parameter

- nfs: Convert nfs_symlink() to use a folio"

* tag 'nfs-for-6.7-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
nfs: Convert nfs_symlink() to use a folio
SUNRPC: Fix RPC client cleaned up the freed pipefs dentries
NFSv4.1: fix SP4_MACH_CRED protection for pnfs IO
SUNRPC: Add an IS_ERR() check back to where it was
NFSv4.1: fix handling NFS4ERR_DELAY when testing for session trunking
nfs41: drop dependency between flexfiles layout driver and NFSv3 modules
NFSv4: fairly test all delegations on a SEQ4_ revocation
SUNRPC: SOFTCONN tasks should time out when on the sending list
SUNRPC: Force close the socket when a hard error is reported
SUNRPC: Don't skip timeout checks in call_connect_status()
SUNRPC: ECONNRESET might require a rebind
NFSv4/pnfs: Allow layoutget to return EAGAIN for softerr mounts
NFSv4: Add a parameter to limit the number of retries after NFS4ERR_DELAY

+121 -54
+7
Documentation/admin-guide/kernel-parameters.txt
··· 3596 3596 [NFS] set the TCP port on which the NFSv4 callback 3597 3597 channel should listen. 3598 3598 3599 + nfs.delay_retrans= 3600 + [NFS] specifies the number of times the NFSv4 client 3601 + retries the request before returning an EAGAIN error, 3602 + after a reply of NFS4ERR_DELAY from the server. 3603 + Only applies if the softerr mount option is enabled, 3604 + and the specified value is >= 0. 3605 + 3599 3606 nfs.enable_ino64= 3600 3607 [NFS] enable 64-bit inode numbers. 3601 3608 If zero, the NFS client will fake up a 32-bit inode
+1 -1
fs/nfs/Kconfig
··· 125 125 126 126 config PNFS_FLEXFILE_LAYOUT 127 127 tristate 128 - depends on NFS_V4_1 && NFS_V3 128 + depends on NFS_V4_1 129 129 default NFS_V4 130 130 131 131 config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN
+6 -1
fs/nfs/delegation.c
··· 448 448 delegation->cred = get_cred(cred); 449 449 delegation->inode = inode; 450 450 delegation->flags = 1<<NFS_DELEGATION_REFERENCED; 451 + delegation->test_gen = 0; 451 452 spin_lock_init(&delegation->lock); 452 453 453 454 spin_lock(&clp->cl_lock); ··· 1295 1294 struct inode *inode; 1296 1295 const struct cred *cred; 1297 1296 nfs4_stateid stateid; 1297 + unsigned long gen = ++server->delegation_gen; 1298 + 1298 1299 restart: 1299 1300 rcu_read_lock(); 1300 1301 restart_locked: ··· 1306 1303 test_bit(NFS_DELEGATION_RETURNING, 1307 1304 &delegation->flags) || 1308 1305 test_bit(NFS_DELEGATION_TEST_EXPIRED, 1309 - &delegation->flags) == 0) 1306 + &delegation->flags) == 0 || 1307 + delegation->test_gen == gen) 1310 1308 continue; 1311 1309 inode = nfs_delegation_grab_inode(delegation); 1312 1310 if (inode == NULL) ··· 1316 1312 cred = get_cred_rcu(delegation->cred); 1317 1313 nfs4_stateid_copy(&stateid, &delegation->stateid); 1318 1314 spin_unlock(&delegation->lock); 1315 + delegation->test_gen = gen; 1319 1316 clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags); 1320 1317 rcu_read_unlock(); 1321 1318 nfs_delegation_test_free_expired(inode, &stateid, cred);
+1
fs/nfs/delegation.h
··· 21 21 fmode_t type; 22 22 unsigned long pagemod_limit; 23 23 __u64 change_attr; 24 + unsigned long test_gen; 24 25 unsigned long flags; 25 26 refcount_t refcount; 26 27 spinlock_t lock;
+12 -17
fs/nfs/dir.c
··· 2532 2532 int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir, 2533 2533 struct dentry *dentry, const char *symname) 2534 2534 { 2535 - struct page *page; 2535 + struct folio *folio; 2536 2536 char *kaddr; 2537 2537 struct iattr attr; 2538 2538 unsigned int pathlen = strlen(symname); ··· 2547 2547 attr.ia_mode = S_IFLNK | S_IRWXUGO; 2548 2548 attr.ia_valid = ATTR_MODE; 2549 2549 2550 - page = alloc_page(GFP_USER); 2551 - if (!page) 2550 + folio = folio_alloc(GFP_USER, 0); 2551 + if (!folio) 2552 2552 return -ENOMEM; 2553 2553 2554 - kaddr = page_address(page); 2554 + kaddr = folio_address(folio); 2555 2555 memcpy(kaddr, symname, pathlen); 2556 2556 if (pathlen < PAGE_SIZE) 2557 2557 memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); 2558 2558 2559 2559 trace_nfs_symlink_enter(dir, dentry); 2560 - error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); 2560 + error = NFS_PROTO(dir)->symlink(dir, dentry, folio, pathlen, &attr); 2561 2561 trace_nfs_symlink_exit(dir, dentry, error); 2562 2562 if (error != 0) { 2563 2563 dfprintk(VFS, "NFS: symlink(%s/%lu, %pd, %s) error %d\n", 2564 2564 dir->i_sb->s_id, dir->i_ino, 2565 2565 dentry, symname, error); 2566 2566 d_drop(dentry); 2567 - __free_page(page); 2567 + folio_put(folio); 2568 2568 return error; 2569 2569 } 2570 2570 ··· 2574 2574 * No big deal if we can't add this page to the page cache here. 2575 2575 * READLINK will get the missing page from the server if needed. 2576 2576 */ 2577 - if (!add_to_page_cache_lru(page, d_inode(dentry)->i_mapping, 0, 2578 - GFP_KERNEL)) { 2579 - SetPageUptodate(page); 2580 - unlock_page(page); 2581 - /* 2582 - * add_to_page_cache_lru() grabs an extra page refcount. 2583 - * Drop it here to avoid leaking this page later. 2584 - */ 2585 - put_page(page); 2586 - } else 2587 - __free_page(page); 2577 + if (filemap_add_folio(d_inode(dentry)->i_mapping, folio, 0, 2578 + GFP_KERNEL) == 0) { 2579 + folio_mark_uptodate(folio); 2580 + folio_unlock(folio); 2581 + } 2588 2582 2583 + folio_put(folio); 2589 2584 return 0; 2590 2585 } 2591 2586 EXPORT_SYMBOL_GPL(nfs_symlink);
+2 -1
fs/nfs/nfs3proc.c
··· 543 543 } 544 544 545 545 static int 546 - nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, 546 + nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct folio *folio, 547 547 unsigned int len, struct iattr *sattr) 548 548 { 549 + struct page *page = &folio->page; 549 550 struct nfs3_createdata *data; 550 551 struct dentry *d_alias; 551 552 int status = -ENOMEM;
+2
fs/nfs/nfs4_fs.h
··· 209 209 struct inode *inode; 210 210 nfs4_stateid *stateid; 211 211 long timeout; 212 + unsigned short retrans; 212 213 unsigned char task_is_privileged : 1; 213 214 unsigned char delay : 1, 214 215 recovering : 1, ··· 547 546 extern unsigned short max_session_cb_slots; 548 547 extern unsigned short send_implementation_id; 549 548 extern bool recover_lost_locks; 549 + extern short nfs_delay_retrans; 550 550 551 551 #define NFS4_CLIENT_ID_UNIQ_LEN (64) 552 552 extern char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN];
+48 -14
fs/nfs/nfs4proc.c
··· 585 585 return 0; 586 586 } 587 587 588 + /* 589 + * Track the number of NFS4ERR_DELAY related retransmissions and return 590 + * EAGAIN if the 'softerr' mount option is set, and we've exceeded the limit 591 + * set by 'nfs_delay_retrans'. 592 + */ 593 + static int nfs4_exception_should_retrans(const struct nfs_server *server, 594 + struct nfs4_exception *exception) 595 + { 596 + if (server->flags & NFS_MOUNT_SOFTERR && nfs_delay_retrans >= 0) { 597 + if (exception->retrans++ >= (unsigned short)nfs_delay_retrans) 598 + return -EAGAIN; 599 + } 600 + return 0; 601 + } 602 + 588 603 /* This is the error handling routine for processes that are allowed 589 604 * to sleep. 590 605 */ ··· 610 595 611 596 ret = nfs4_do_handle_exception(server, errorcode, exception); 612 597 if (exception->delay) { 598 + int ret2 = nfs4_exception_should_retrans(server, exception); 599 + if (ret2 < 0) { 600 + exception->retry = 0; 601 + return ret2; 602 + } 613 603 ret = nfs4_delay(&exception->timeout, 614 604 exception->interruptible); 615 605 goto out_retry; ··· 643 623 644 624 ret = nfs4_do_handle_exception(server, errorcode, exception); 645 625 if (exception->delay) { 626 + int ret2 = nfs4_exception_should_retrans(server, exception); 627 + if (ret2 < 0) { 628 + exception->retry = 0; 629 + return ret2; 630 + } 646 631 rpc_delay(task, nfs4_update_delay(&exception->timeout)); 647 632 goto out_retry; 648 633 } ··· 5036 5011 } 5037 5012 5038 5013 static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, 5039 - struct page *page, unsigned int len, struct iattr *sattr, 5014 + struct folio *folio, unsigned int len, struct iattr *sattr, 5040 5015 struct nfs4_label *label) 5041 5016 { 5017 + struct page *page = &folio->page; 5042 5018 struct nfs4_createdata *data; 5043 5019 int status = -ENAMETOOLONG; 5044 5020 ··· 5064 5038 } 5065 5039 5066 5040 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, 5067 - struct page *page, unsigned int len, struct iattr *sattr) 5041 + struct folio *folio, unsigned int len, struct iattr *sattr) 5068 5042 { 5069 5043 struct nfs4_exception exception = { 5070 5044 .interruptible = true, ··· 5075 5049 label = nfs4_label_init_security(dir, dentry, sattr, &l); 5076 5050 5077 5051 do { 5078 - err = _nfs4_proc_symlink(dir, dentry, page, len, sattr, label); 5052 + err = _nfs4_proc_symlink(dir, dentry, folio, len, sattr, label); 5079 5053 trace_nfs4_symlink(dir, &dentry->d_name, err); 5080 5054 err = nfs4_handle_exception(NFS_SERVER(dir), err, 5081 5055 &exception); ··· 5648 5622 5649 5623 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; 5650 5624 nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0); 5651 - nfs4_state_protect_write(server->nfs_client, clnt, msg, hdr); 5625 + nfs4_state_protect_write(hdr->ds_clp ? hdr->ds_clp : server->nfs_client, clnt, msg, hdr); 5652 5626 } 5653 5627 5654 5628 static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) ··· 5689 5663 data->res.server = server; 5690 5664 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; 5691 5665 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, 0); 5692 - nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_COMMIT, clnt, msg); 5666 + nfs4_state_protect(data->ds_clp ? data->ds_clp : server->nfs_client, 5667 + NFS_SP4_MACH_CRED_COMMIT, clnt, msg); 5693 5668 } 5694 5669 5695 5670 static int _nfs4_proc_commit(struct file *dst, struct nfs_commitargs *args, ··· 8961 8934 8962 8935 sp4_how = (adata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED); 8963 8936 8937 + try_again: 8964 8938 /* Test connection for session trunking. Async exchange_id call */ 8965 8939 task = nfs4_run_exchange_id(adata->clp, adata->cred, sp4_how, xprt); 8966 8940 if (IS_ERR(task)) ··· 8974 8946 8975 8947 if (status == 0) 8976 8948 rpc_clnt_xprt_switch_add_xprt(clnt, xprt); 8977 - else if (rpc_clnt_xprt_switch_has_addr(clnt, 8949 + else if (status != -NFS4ERR_DELAY && rpc_clnt_xprt_switch_has_addr(clnt, 8978 8950 (struct sockaddr *)&xprt->addr)) 8979 8951 rpc_clnt_xprt_switch_remove_xprt(clnt, xprt); 8980 8952 8981 8953 rpc_put_task(task); 8954 + if (status == -NFS4ERR_DELAY) { 8955 + ssleep(1); 8956 + goto try_again; 8957 + } 8982 8958 } 8983 8959 EXPORT_SYMBOL_GPL(nfs4_test_session_trunk); 8984 8960 ··· 9653 9621 9654 9622 nfs4_sequence_free_slot(&lgp->res.seq_res); 9655 9623 9624 + exception->state = NULL; 9625 + exception->stateid = NULL; 9626 + 9656 9627 switch (nfs4err) { 9657 9628 case 0: 9658 9629 goto out; ··· 9751 9716 }; 9752 9717 9753 9718 struct pnfs_layout_segment * 9754 - nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout) 9719 + nfs4_proc_layoutget(struct nfs4_layoutget *lgp, 9720 + struct nfs4_exception *exception) 9755 9721 { 9756 9722 struct inode *inode = lgp->args.inode; 9757 9723 struct nfs_server *server = NFS_SERVER(inode); ··· 9772 9736 RPC_TASK_MOVEABLE, 9773 9737 }; 9774 9738 struct pnfs_layout_segment *lseg = NULL; 9775 - struct nfs4_exception exception = { 9776 - .inode = inode, 9777 - .timeout = *timeout, 9778 - }; 9779 9739 int status = 0; 9780 9740 9781 9741 nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0, 0); 9742 + exception->retry = 0; 9782 9743 9783 9744 task = rpc_run_task(&task_setup_data); 9784 9745 if (IS_ERR(task)) ··· 9786 9753 goto out; 9787 9754 9788 9755 if (task->tk_status < 0) { 9789 - status = nfs4_layoutget_handle_exception(task, lgp, &exception); 9790 - *timeout = exception.timeout; 9756 + exception->retry = 1; 9757 + status = nfs4_layoutget_handle_exception(task, lgp, exception); 9791 9758 } else if (lgp->res.layoutp->len == 0) { 9759 + exception->retry = 1; 9792 9760 status = -EAGAIN; 9793 - *timeout = nfs4_update_delay(&exception.timeout); 9761 + nfs4_update_delay(&exception->timeout); 9794 9762 } else 9795 9763 lseg = pnfs_layout_process(lgp); 9796 9764 out:
+6 -2
fs/nfs/pnfs.c
··· 1980 1980 struct pnfs_layout_segment *lseg = NULL; 1981 1981 struct nfs4_layoutget *lgp; 1982 1982 nfs4_stateid stateid; 1983 - long timeout = 0; 1983 + struct nfs4_exception exception = { 1984 + .inode = ino, 1985 + }; 1984 1986 unsigned long giveup = jiffies + (clp->cl_lease_time << 1); 1985 1987 bool first; 1986 1988 ··· 2146 2144 lgp->lo = lo; 2147 2145 pnfs_get_layout_hdr(lo); 2148 2146 2149 - lseg = nfs4_proc_layoutget(lgp, &timeout); 2147 + lseg = nfs4_proc_layoutget(lgp, &exception); 2150 2148 trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg, 2151 2149 PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET); 2152 2150 nfs_layoutget_end(lo); ··· 2173 2171 goto out_put_layout_hdr; 2174 2172 } 2175 2173 if (lseg) { 2174 + if (!exception.retry) 2175 + goto out_put_layout_hdr; 2176 2176 if (first) 2177 2177 pnfs_clear_first_layoutget(lo); 2178 2178 trace_pnfs_update_layout(ino, pos, count,
+4 -1
fs/nfs/pnfs.h
··· 35 35 #include <linux/nfs_page.h> 36 36 #include <linux/workqueue.h> 37 37 38 + struct nfs4_exception; 38 39 struct nfs4_opendata; 39 40 40 41 enum { ··· 246 245 extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, 247 246 struct pnfs_device *dev, 248 247 const struct cred *cred); 249 - extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout); 248 + extern struct pnfs_layout_segment * 249 + nfs4_proc_layoutget(struct nfs4_layoutget *lgp, 250 + struct nfs4_exception *exception); 250 251 extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync); 251 252 252 253 /* pnfs.c */
+2 -1
fs/nfs/proc.c
··· 396 396 } 397 397 398 398 static int 399 - nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, 399 + nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct folio *folio, 400 400 unsigned int len, struct iattr *sattr) 401 401 { 402 + struct page *page = &folio->page; 402 403 struct nfs_fh *fh; 403 404 struct nfs_fattr *fattr; 404 405 struct nfs_symlinkargs arg = {
+7 -1
fs/nfs/super.c
··· 1371 1371 unsigned short send_implementation_id = 1; 1372 1372 char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = ""; 1373 1373 bool recover_lost_locks = false; 1374 + short nfs_delay_retrans = -1; 1374 1375 1375 1376 EXPORT_SYMBOL_GPL(nfs_callback_nr_threads); 1376 1377 EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport); ··· 1382 1381 EXPORT_SYMBOL_GPL(send_implementation_id); 1383 1382 EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier); 1384 1383 EXPORT_SYMBOL_GPL(recover_lost_locks); 1384 + EXPORT_SYMBOL_GPL(nfs_delay_retrans); 1385 1385 1386 1386 #define NFS_CALLBACK_MAXPORTNR (65535U) 1387 1387 ··· 1431 1429 "If the server reports that a lock might be lost, " 1432 1430 "try to recover it risking data corruption."); 1433 1431 1434 - 1432 + module_param_named(delay_retrans, nfs_delay_retrans, short, 0644); 1433 + MODULE_PARM_DESC(delay_retrans, 1434 + "Unless negative, specifies the number of times the NFSv4 " 1435 + "client retries a request before returning an EAGAIN error, " 1436 + "after a reply of NFS4ERR_DELAY from the server."); 1435 1437 #endif /* CONFIG_NFS_V4 */
+2
fs/nfs/write.c
··· 739 739 &pgio); 740 740 pgio.pg_error = 0; 741 741 nfs_pageio_complete(&pgio); 742 + if (err == -EAGAIN && mntflags & NFS_MOUNT_SOFTERR) 743 + break; 742 744 } while (err < 0 && !nfs_error_is_fatal(err)); 743 745 nfs_io_completion_put(ioc); 744 746
+1
include/linux/nfs_fs_sb.h
··· 239 239 struct list_head delegations; 240 240 struct list_head ss_copies; 241 241 242 + unsigned long delegation_gen; 242 243 unsigned long mig_gen; 243 244 unsigned long mig_status; 244 245 #define NFS_MIG_IN_TRANSITION (1)
+1 -1
include/linux/nfs_xdr.h
··· 1772 1772 void (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *); 1773 1773 int (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir); 1774 1774 int (*link) (struct inode *, struct inode *, const struct qstr *); 1775 - int (*symlink) (struct inode *, struct dentry *, struct page *, 1775 + int (*symlink) (struct inode *, struct dentry *, struct folio *, 1776 1776 unsigned int, struct iattr *); 1777 1777 int (*mkdir) (struct inode *, struct dentry *, struct iattr *); 1778 1778 int (*rmdir) (struct inode *, const struct qstr *);
+1
include/linux/sunrpc/clnt.h
··· 92 92 }; 93 93 const struct cred *cl_cred; 94 94 unsigned int cl_max_connect; /* max number of transports not to the same IP */ 95 + struct super_block *pipefs_sb; 95 96 }; 96 97 97 98 /*
+7 -3
net/sunrpc/clnt.c
··· 111 111 112 112 pipefs_sb = rpc_get_sb_net(net); 113 113 if (pipefs_sb) { 114 - __rpc_clnt_remove_pipedir(clnt); 114 + if (pipefs_sb == clnt->pipefs_sb) 115 + __rpc_clnt_remove_pipedir(clnt); 115 116 rpc_put_sb_net(net); 116 117 } 117 118 } ··· 151 150 rpc_setup_pipedir(struct super_block *pipefs_sb, struct rpc_clnt *clnt) 152 151 { 153 152 struct dentry *dentry; 153 + 154 + clnt->pipefs_sb = pipefs_sb; 154 155 155 156 if (clnt->cl_program->pipe_dir_name != NULL) { 156 157 dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt); ··· 2174 2171 task->tk_status = 0; 2175 2172 switch (status) { 2176 2173 case -ECONNREFUSED: 2174 + case -ECONNRESET: 2177 2175 /* A positive refusal suggests a rebind is needed. */ 2178 2176 if (RPC_IS_SOFTCONN(task)) 2179 2177 break; ··· 2183 2179 goto out_retry; 2184 2180 } 2185 2181 fallthrough; 2186 - case -ECONNRESET: 2187 2182 case -ECONNABORTED: 2188 2183 case -ENETDOWN: 2189 2184 case -ENETUNREACH: ··· 2223 2220 } 2224 2221 xprt_switch_put(xps); 2225 2222 if (!task->tk_xprt) 2226 - return; 2223 + goto out; 2227 2224 } 2228 2225 goto out_retry; 2229 2226 case -ENOBUFS: ··· 2238 2235 out_retry: 2239 2236 /* Check for timeouts before looping back to call_bind */ 2240 2237 task->tk_action = call_bind; 2238 + out: 2241 2239 rpc_check_timeout(task); 2242 2240 } 2243 2241
+4
net/sunrpc/rpcb_clnt.c
··· 769 769 770 770 child = rpcb_call_async(rpcb_clnt, map, proc); 771 771 rpc_release_client(rpcb_clnt); 772 + if (IS_ERR(child)) { 773 + /* rpcb_map_release() has freed the arguments */ 774 + return; 775 + } 772 776 773 777 xprt->stat.bind_count++; 774 778 rpc_put_task(child);
+2 -2
net/sunrpc/xprt.c
··· 283 283 xprt_clear_locked(xprt); 284 284 out_sleep: 285 285 task->tk_status = -EAGAIN; 286 - if (RPC_IS_SOFT(task)) 286 + if (RPC_IS_SOFT(task) || RPC_IS_SOFTCONN(task)) 287 287 rpc_sleep_on_timeout(&xprt->sending, task, NULL, 288 288 xprt_request_timeout(req)); 289 289 else ··· 349 349 xprt_clear_locked(xprt); 350 350 out_sleep: 351 351 task->tk_status = -EAGAIN; 352 - if (RPC_IS_SOFT(task)) 352 + if (RPC_IS_SOFT(task) || RPC_IS_SOFTCONN(task)) 353 353 rpc_sleep_on_timeout(&xprt->sending, task, NULL, 354 354 xprt_request_timeout(req)); 355 355 else
+5 -9
net/sunrpc/xprtsock.c
··· 1181 1181 { 1182 1182 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 1183 1183 1184 + transport->xprt_err = 0; 1184 1185 clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state); 1185 1186 clear_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state); 1186 1187 clear_bit(XPRT_SOCK_WAKE_WRITE, &transport->sock_state); ··· 2773 2772 { 2774 2773 int sockerr; 2775 2774 2776 - if (!test_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state)) 2777 - return; 2778 - mutex_lock(&transport->recv_mutex); 2779 - if (transport->sock == NULL) 2780 - goto out; 2781 2775 if (!test_and_clear_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state)) 2782 - goto out; 2776 + return; 2783 2777 sockerr = xchg(&transport->xprt_err, 0); 2784 - if (sockerr < 0) 2778 + if (sockerr < 0) { 2785 2779 xprt_wake_pending_tasks(&transport->xprt, sockerr); 2786 - out: 2787 - mutex_unlock(&transport->recv_mutex); 2780 + xs_tcp_force_close(&transport->xprt); 2781 + } 2788 2782 } 2789 2783 2790 2784 static void xs_wake_pending(struct sock_xprt *transport)