History

Merge tag 'nfsd-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux

Pull nfsd updates from Chuck Lever: "Bruce has announced he is leaving Red Hat at the end of the month and is stepping back from his role as NFSD co-maintainer. As a result, this includes a patch removing him from the MAINTAINERS file. There is one patch in here that Jeff Layton was carrying in the locks tree. Since he had only one for this cycle, he asked us to send it to you via the nfsd tree. There continues to be 0-day reports from Robert Morris @MIT. This time we include a fix for a crash in the COPY_NOTIFY operation. Highlights: - Bruce steps down as NFSD maintainer - Prepare for dynamic nfsd thread management - More work on supporting re-exporting NFS mounts - One fs/locks patch on behalf of Jeff Layton Notable bug fixes: - Fix zero-length NFSv3 WRITEs - Fix directory cinfo on FS's that do not support iversion - Fix WRITE verifiers for stable writes - Fix crash on COPY_NOTIFY with a special state ID" * tag 'nfsd-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (51 commits) SUNRPC: Fix sockaddr handling in svcsock_accept_class trace points SUNRPC: Fix sockaddr handling in the svc_xprt_create_error trace point fs/locks: fix fcntl_getlk64/fcntl_setlk64 stub prototypes nfsd: fix crash on COPY_NOTIFY with special stateid MAINTAINERS: remove bfields NFSD: Move fill_pre_wcc() and fill_post_wcc() Revert "nfsd: skip some unnecessary stats in the v4 case" NFSD: Trace boot verifier resets NFSD: Rename boot verifier functions NFSD: Clean up the nfsd_net::nfssvc_boot field NFSD: Write verifier might go backwards nfsd: Add a tracepoint for errors in nfsd4_clone_file_range() NFSD: De-duplicate net_generic(nf->nf_net, nfsd_net_id) NFSD: De-duplicate net_generic(SVC_NET(rqstp), nfsd_net_id) NFSD: Clean up nfsd_vfs_write() nfsd: Replace use of rwsem with errseq_t NFSD: Fix verifier returned in stable WRITEs nfsd: Retry once in nfsd_open on an -EOPENSTALE return nfsd: Add errno mapping for EREMOTEIO nfsd: map EBADF ...

Linus Torvalds committed 4 years ago

Commit 175398a2 parents 49ad227 167208633 files · +702 −749Browse files

Unified · Split

33 files
  1. MAINTAINERS +1 −3
  2. fs/lockd/svc.c +61 −139
  3. fs/lockd/svclock.c +4 −2
  4. fs/nfs/callback.c +9 −23
  5. fs/nfs/export.c +1 −1
  6. fs/nfsd/filecache.c +16 −63
  7. fs/nfsd/filecache.h +0 −1
  8. fs/nfsd/netns.h +16 −11
  9. fs/nfsd/nfs3proc.c +1 −5
  10. fs/nfsd/nfs3xdr.c +0 −65
  11. fs/nfsd/nfs4proc.c +13 −11
  12. fs/nfsd/nfs4state.c +49 −14
  13. fs/nfsd/nfs4xdr.c +5 −16
  14. fs/nfsd/nfscache.c +1 −1
  15. fs/nfsd/nfsctl.c +12 −15
  16. fs/nfsd/nfsd.h +1 −1
  17. fs/nfsd/nfsfh.c +65 −1
  18. fs/nfsd/nfsfh.h +26 −14
  19. fs/nfsd/nfsproc.c +3 −5
  20. fs/nfsd/nfssvc.c +126 −94
  21. fs/nfsd/state.h +5 −0
  22. fs/nfsd/stats.c +1 −1
  23. fs/nfsd/stats.h +1 −3
  24. fs/nfsd/trace.h +85 −21
  25. fs/nfsd/vfs.c +65 −57
  26. fs/nfsd/vfs.h +2 −1
  27. include/linux/exportfs.h +0 −2
  28. include/linux/fs.h +2 −2
  29. include/linux/lockd/lockd.h +7 −2
  30. include/linux/sunrpc/svc.h +39 −40
  31. include/trace/events/sunrpc.h +8 −29
  32. net/sunrpc/svc.c +74 −101
  33. net/sunrpc/svc_xprt.c +3 −5
MAINTAINERS+1−3
@@ -7417,7 +7417,6 @@ F: include/uapi/scsi/fc/ · 7416 unmodified lines
74177417
74187418 FILE LOCKING (flock() and fcntl()/lockf())
74197419 M: Jeff Layton <jlayton@kernel.org>
7420−M: "J. Bruce Fields" <bfields@fieldses.org>
74217420 L: linux-fsdevel@vger.kernel.org
74227421 S: Maintained
74237422 F: fs/fcntl.c
@@ -10428,12 +10427,11 @@ S: Odd Fixes · 3004 unmodified lines
1042810427 W: http://kernelnewbies.org/KernelJanitors
1042910428
1043010429 KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
10431−M: "J. Bruce Fields" <bfields@fieldses.org>
1043210430 M: Chuck Lever <chuck.lever@oracle.com>
1043310431 L: linux-nfs@vger.kernel.org
1043410432 S: Supported
1043510433 W: http://nfs.sourceforge.net/
10436−T: git git://linux-nfs.org/~bfields/linux.git
10434+T: git git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git
1043710435 F: fs/lockd/
1043810436 F: fs/nfs_common/
1043910437 F: fs/nfsd/
fs/lockd/svc.c+61−139
@@ -54,13 +54,9 @@ EXPORT_SYMBOL_GPL(nlmsvc_ops); · 53 unmodified lines
5454
5555 static DEFINE_MUTEX(nlmsvc_mutex);
5656 static unsigned int nlmsvc_users;
57−static struct task_struct *nlmsvc_task;
58−static struct svc_rqst *nlmsvc_rqst;
57+static struct svc_serv *nlmsvc_serv;
5958 unsigned long nlmsvc_timeout;
6059
61−static atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
62−static DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);
63−
6460 unsigned int lockd_net_id;
6561
6662 /*
@@ -184,7 +180,12 @@ lockd(void *vrqstp) · 117 unmodified lines
184180 nlm_shutdown_hosts();
185181 cancel_delayed_work_sync(&ln->grace_period_end);
186182 locks_end_grace(&ln->lockd_manager);
187− return 0;
183+
184+ dprintk("lockd_down: service stopped\n");
185+
186+ svc_exit_thread(rqstp);
187+
188+ module_put_and_exit(0);
188189 }
189190
190191 static int create_lockd_listener(struct svc_serv *serv, const char *name,
@@ -290,8 +291,8 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net) · 99 unmodified lines
290291 __func__, net->ns.inum);
291292 }
292293 } else {
293− pr_err("%s: no users! task=%p, net=%x\n",
294− __func__, nlmsvc_task, net->ns.inum);
294+ pr_err("%s: no users! net=%x\n",
295+ __func__, net->ns.inum);
295296 BUG();
296297 }
297298 }
@@ -302,20 +303,16 @@ static int lockd_inetaddr_event(struct notifier_block *this, · 4 unmodified lines
302303 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
303304 struct sockaddr_in sin;
304305
305− if ((event != NETDEV_DOWN) ||
306− !atomic_inc_not_zero(&nlm_ntf_refcnt))
306+ if (event != NETDEV_DOWN)
307307 goto out;
308308
309− if (nlmsvc_rqst) {
309+ if (nlmsvc_serv) {
310310 dprintk("lockd_inetaddr_event: removed %pI4\n",
311311 &ifa->ifa_local);
312312 sin.sin_family = AF_INET;
313313 sin.sin_addr.s_addr = ifa->ifa_local;
314− svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
315− (struct sockaddr *)&sin);
314+ svc_age_temp_xprts_now(nlmsvc_serv, (struct sockaddr *)&sin);
316315 }
317− atomic_dec(&nlm_ntf_refcnt);
318− wake_up(&nlm_ntf_wq);
319316
320317 out:
321318 return NOTIFY_DONE;
@@ -332,21 +329,17 @@ static int lockd_inet6addr_event(struct notifier_block *this, · 10 unmodified lines
332329 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
333330 struct sockaddr_in6 sin6;
334331
335− if ((event != NETDEV_DOWN) ||
336− !atomic_inc_not_zero(&nlm_ntf_refcnt))
332+ if (event != NETDEV_DOWN)
337333 goto out;
338334
339− if (nlmsvc_rqst) {
335+ if (nlmsvc_serv) {
340336 dprintk("lockd_inet6addr_event: removed %pI6\n", &ifa->addr);
341337 sin6.sin6_family = AF_INET6;
342338 sin6.sin6_addr = ifa->addr;
343339 if (ipv6_addr_type(&sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
344340 sin6.sin6_scope_id = ifa->idev->dev->ifindex;
345− svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
346− (struct sockaddr *)&sin6);
341+ svc_age_temp_xprts_now(nlmsvc_serv, (struct sockaddr *)&sin6);
347342 }
348− atomic_dec(&nlm_ntf_refcnt);
349− wake_up(&nlm_ntf_wq);
350343
351344 out:
352345 return NOTIFY_DONE;
@@ -357,86 +350,22 @@ static struct notifier_block lockd_inet6addr_notifier = { · 4 unmodified lines
357350 };
358351 #endif
359352
360−static void lockd_unregister_notifiers(void)
361−{
362− unregister_inetaddr_notifier(&lockd_inetaddr_notifier);
363−#if IS_ENABLED(CONFIG_IPV6)
364− unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
365−#endif
366− wait_event(nlm_ntf_wq, atomic_read(&nlm_ntf_refcnt) == 0);
367−}
368−
369−static void lockd_svc_exit_thread(void)
370−{
371− atomic_dec(&nlm_ntf_refcnt);
372− lockd_unregister_notifiers();
373− svc_exit_thread(nlmsvc_rqst);
374−}
375−
376−static int lockd_start_svc(struct svc_serv *serv)
377−{
378− int error;
379−
380− if (nlmsvc_rqst)
381− return 0;
382−
383− /*
384− * Create the kernel thread and wait for it to start.
385− */
386− nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE);
387− if (IS_ERR(nlmsvc_rqst)) {
388− error = PTR_ERR(nlmsvc_rqst);
389− printk(KERN_WARNING
390− "lockd_up: svc_rqst allocation failed, error=%d\n",
391− error);
392− lockd_unregister_notifiers();
393− goto out_rqst;
394− }
395−
396− atomic_inc(&nlm_ntf_refcnt);
397− svc_sock_update_bufs(serv);
398− serv->sv_maxconn = nlm_max_connections;
399−
400− nlmsvc_task = kthread_create(lockd, nlmsvc_rqst, "%s", serv->sv_name);
401− if (IS_ERR(nlmsvc_task)) {
402− error = PTR_ERR(nlmsvc_task);
403− printk(KERN_WARNING
404− "lockd_up: kthread_run failed, error=%d\n", error);
405− goto out_task;
406− }
407− nlmsvc_rqst->rq_task = nlmsvc_task;
408− wake_up_process(nlmsvc_task);
409−
410− dprintk("lockd_up: service started\n");
411− return 0;
412−
413−out_task:
414− lockd_svc_exit_thread();
415− nlmsvc_task = NULL;
416−out_rqst:
417− nlmsvc_rqst = NULL;
418− return error;
419−}
420−
421353 static const struct svc_serv_ops lockd_sv_ops = {
422354 .svo_shutdown = svc_rpcb_cleanup,
355+ .svo_function = lockd,
423356 .svo_enqueue_xprt = svc_xprt_do_enqueue,
357+ .svo_module = THIS_MODULE,
424358 };
425359
426−static struct svc_serv *lockd_create_svc(void)
360+static int lockd_get(void)
427361 {
428362 struct svc_serv *serv;
363+ int error;
429364
430− /*
431− * Check whether we're already up and running.
432− */
433− if (nlmsvc_rqst) {
434− /*
435− * Note: increase service usage, because later in case of error
436− * svc_destroy() will be called.
437− */
438− svc_get(nlmsvc_rqst->rq_server);
439− return nlmsvc_rqst->rq_server;
365+ if (nlmsvc_serv) {
366+ svc_get(nlmsvc_serv);
367+ nlmsvc_users++;
368+ return 0;
440369 }
441370
442371 /*
@@ -454,14 +383,41 @@ static struct svc_serv *lockd_create_svc(void) · 11 unmodified lines
454383 serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, &lockd_sv_ops);
455384 if (!serv) {
456385 printk(KERN_WARNING "lockd_up: create service failed\n");
457− return ERR_PTR(-ENOMEM);
386+ return -ENOMEM;
458387 }
388+
389+ serv->sv_maxconn = nlm_max_connections;
390+ error = svc_set_num_threads(serv, NULL, 1);
391+ /* The thread now holds the only reference */
392+ svc_put(serv);
393+ if (error < 0)
394+ return error;
395+
396+ nlmsvc_serv = serv;
459397 register_inetaddr_notifier(&lockd_inetaddr_notifier);
460398 #if IS_ENABLED(CONFIG_IPV6)
461399 register_inet6addr_notifier(&lockd_inet6addr_notifier);
462400 #endif
463401 dprintk("lockd_up: service created\n");
464− return serv;
402+ nlmsvc_users++;
403+ return 0;
404+}
405+
406+static void lockd_put(void)
407+{
408+ if (WARN(nlmsvc_users <= 0, "lockd_down: no users!\n"))
409+ return;
410+ if (--nlmsvc_users)
411+ return;
412+
413+ unregister_inetaddr_notifier(&lockd_inetaddr_notifier);
414+#if IS_ENABLED(CONFIG_IPV6)
415+ unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
416+#endif
417+
418+ svc_set_num_threads(nlmsvc_serv, NULL, 0);
419+ nlmsvc_serv = NULL;
420+ dprintk("lockd_down: service destroyed\n");
465421 }
466422
467423 /*
@@ -469,36 +425,21 @@ static struct svc_serv *lockd_create_svc(void) · 1 unmodified line
469425 */
470426 int lockd_up(struct net *net, const struct cred *cred)
471427 {
472− struct svc_serv *serv;
473428 int error;
474429
475430 mutex_lock(&nlmsvc_mutex);
476431
477− serv = lockd_create_svc();
478− if (IS_ERR(serv)) {
479− error = PTR_ERR(serv);
480− goto err_create;
481− }
432+ error = lockd_get();
433+ if (error)
434+ goto err;
482435
483− error = lockd_up_net(serv, net, cred);
436+ error = lockd_up_net(nlmsvc_serv, net, cred);
484437 if (error < 0) {
485− lockd_unregister_notifiers();
486− goto err_put;
438+ lockd_put();
439+ goto err;
487440 }
488441
489− error = lockd_start_svc(serv);
490− if (error < 0) {
491− lockd_down_net(serv, net);
492− goto err_put;
493− }
494− nlmsvc_users++;
495− /*
496− * Note: svc_serv structures have an initial use count of 1,
497− * so we exit through here on both success and failure.
498− */
499−err_put:
500− svc_destroy(serv);
501−err_create:
442+err:
502443 mutex_unlock(&nlmsvc_mutex);
503444 return error;
504445 }
@@ -511,27 +452,8 @@ void · 6 unmodified lines
511452 lockd_down(struct net *net)
512453 {
513454 mutex_lock(&nlmsvc_mutex);
514− lockd_down_net(nlmsvc_rqst->rq_server, net);
515− if (nlmsvc_users) {
516− if (--nlmsvc_users)
517− goto out;
518− } else {
519− printk(KERN_ERR "lockd_down: no users! task=%p\n",
520− nlmsvc_task);
521− BUG();
522− }
523−
524− if (!nlmsvc_task) {
525− printk(KERN_ERR "lockd_down: no lockd running.\n");
526− BUG();
527− }
528− kthread_stop(nlmsvc_task);
529− dprintk("lockd_down: service stopped\n");
530− lockd_svc_exit_thread();
531− dprintk("lockd_down: service destroyed\n");
532− nlmsvc_task = NULL;
533− nlmsvc_rqst = NULL;
534−out:
455+ lockd_down_net(nlmsvc_serv, net);
456+ lockd_put();
535457 mutex_unlock(&nlmsvc_mutex);
536458 }
537459 EXPORT_SYMBOL_GPL(lockd_down);
fs/lockd/svclock.c+4−2
@@ -470,8 +470,10 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, · 469 unmodified lines
470470 struct nlm_host *host, struct nlm_lock *lock, int wait,
471471 struct nlm_cookie *cookie, int reclaim)
472472 {
473− struct nlm_block *block = NULL;
473+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
474474 struct inode *inode = nlmsvc_file_inode(file);
475+#endif
476+ struct nlm_block *block = NULL;
475477 int error;
476478 int mode;
477479 int async_block = 0;
@@ -484,7 +486,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, · 6 unmodified lines
484486 (long long)lock->fl.fl_end,
485487 wait);
486488
487− if (inode->i_sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS) {
489+ if (nlmsvc_file_file(file)->f_op->lock) {
488490 async_block = wait;
489491 wait = 0;
490492 }
fs/nfs/callback.c+9−23
@@ -169,12 +169,12 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, · 168 unmodified lines
169169 if (nrservs < NFS4_MIN_NR_CALLBACK_THREADS)
170170 nrservs = NFS4_MIN_NR_CALLBACK_THREADS;
171171
172− if (serv->sv_nrthreads-1 == nrservs)
172+ if (serv->sv_nrthreads == nrservs)
173173 return 0;
174174
175− ret = serv->sv_ops->svo_setup(serv, NULL, nrservs);
175+ ret = svc_set_num_threads(serv, NULL, nrservs);
176176 if (ret) {
177− serv->sv_ops->svo_setup(serv, NULL, 0);
177+ svc_set_num_threads(serv, NULL, 0);
178178 return ret;
179179 }
180180 dprintk("nfs_callback_up: service started\n");
@@ -235,14 +235,12 @@ err_bind: · 54 unmodified lines
235235 static const struct svc_serv_ops nfs40_cb_sv_ops = {
236236 .svo_function = nfs4_callback_svc,
237237 .svo_enqueue_xprt = svc_xprt_do_enqueue,
238− .svo_setup = svc_set_num_threads_sync,
239238 .svo_module = THIS_MODULE,
240239 };
241240 #if defined(CONFIG_NFS_V4_1)
242241 static const struct svc_serv_ops nfs41_cb_sv_ops = {
243242 .svo_function = nfs41_callback_svc,
244243 .svo_enqueue_xprt = svc_xprt_do_enqueue,
245− .svo_setup = svc_set_num_threads_sync,
246244 .svo_module = THIS_MODULE,
247245 };
248246
@@ -266,14 +264,8 @@ static struct svc_serv *nfs_callback_create_svc(int minorversion) · 17 unmodified lines
266264 /*
267265 * Check whether we're already up and running.
268266 */
269− if (cb_info->serv) {
270− /*
271− * Note: increase service usage, because later in case of error
272− * svc_destroy() will be called.
273− */
274− svc_get(cb_info->serv);
275− return cb_info->serv;
276− }
267+ if (cb_info->serv)
268+ return svc_get(cb_info->serv);
277269
278270 switch (minorversion) {
279271 case 0:
@@ -294,7 +286,7 @@ static struct svc_serv *nfs_callback_create_svc(int minorversion) · 14 unmodified lines
294286 printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n",
295287 cb_info->users);
296288
297− serv = svc_create_pooled(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, sv_ops);
289+ serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, sv_ops);
298290 if (!serv) {
299291 printk(KERN_ERR "nfs_callback_create_svc: create service failed\n");
300292 return ERR_PTR(-ENOMEM);
@@ -335,16 +327,10 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) · 34 unmodified lines
335327 goto err_start;
336328
337329 cb_info->users++;
338− /*
339− * svc_create creates the svc_serv with sv_nrthreads == 1, and then
340− * svc_prepare_thread increments that. So we need to call svc_destroy
341− * on both success and failure so that the refcount is 1 when the
342− * thread exits.
343− */
344330 err_net:
345331 if (!cb_info->users)
346332 cb_info->serv = NULL;
347− svc_destroy(serv);
333+ svc_put(serv);
348334 err_create:
349335 mutex_unlock(&nfs_callback_mutex);
350336 return ret;
@@ -369,8 +355,8 @@ void nfs_callback_down(int minorversion, struct net *net) · 18 unmodified lines
369355 cb_info->users--;
370356 if (cb_info->users == 0) {
371357 svc_get(serv);
372− serv->sv_ops->svo_setup(serv, NULL, 0);
373− svc_destroy(serv);
358+ svc_set_num_threads(serv, NULL, 0);
359+ svc_put(serv);
374360 dprintk("nfs_callback_down: service destroyed\n");
375361 cb_info->serv = NULL;
376362 }
fs/nfs/export.c+1−1
@@ -158,5 +158,5 @@ const struct export_operations nfs_export_ops = { · 157 unmodified lines
158158 .fetch_iversion = nfs_fetch_iversion,
159159 .flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|
160160 EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS|
161− EXPORT_OP_NOATOMIC_ATTR|EXPORT_OP_SYNC_LOCKS,
161+ EXPORT_OP_NOATOMIC_ATTR,
162162 };
fs/nfsd/filecache.c+16−63
@@ -44,12 +44,9 @@ struct nfsd_fcache_bucket { · 43 unmodified lines
4444 static DEFINE_PER_CPU(unsigned long, nfsd_file_cache_hits);
4545
4646 struct nfsd_fcache_disposal {
47− struct list_head list;
4847 struct work_struct work;
49− struct net *net;
5048 spinlock_t lock;
5149 struct list_head freeme;
52− struct rcu_head rcu;
5350 };
5451
5552 static struct workqueue_struct *nfsd_filecache_wq __read_mostly;
@@ -62,8 +59,6 @@ static long nfsd_file_lru_flags; · 6 unmodified lines
6259 static struct fsnotify_group *nfsd_file_fsnotify_group;
6360 static atomic_long_t nfsd_filecache_count;
6461 static struct delayed_work nfsd_filecache_laundrette;
65−static DEFINE_SPINLOCK(laundrette_lock);
66−static LIST_HEAD(laundrettes);
6762
6863 static void nfsd_file_gc(void);
6964
@@ -194,7 +189,6 @@ nfsd_file_alloc(struct inode *inode, unsigned int may, unsigned int hashval, · 124 unmodified lines
194189 __set_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags);
195190 }
196191 nf->nf_mark = NULL;
197− init_rwsem(&nf->nf_rwsem);
198192 trace_nfsd_file_alloc(nf);
199193 }
200194 return nf;
@@ -249,7 +243,7 @@ nfsd_file_do_unhash(struct nfsd_file *nf) · 48 unmodified lines
249243 trace_nfsd_file_unhash(nf);
250244
251245 if (nfsd_file_check_write_error(nf))
252− nfsd_reset_boot_verifier(net_generic(nf->nf_net, nfsd_net_id));
246+ nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id));
253247 --nfsd_file_hashtbl[nf->nf_hashval].nfb_count;
254248 hlist_del_rcu(&nf->nf_node);
255249 atomic_long_dec(&nfsd_filecache_count);
@@ -367,19 +361,13 @@ nfsd_file_list_remove_disposal(struct list_head *dst, · 111 unmodified lines
367361 static void
368362 nfsd_file_list_add_disposal(struct list_head *files, struct net *net)
369363 {
370− struct nfsd_fcache_disposal *l;
364+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
365+ struct nfsd_fcache_disposal *l = nn->fcache_disposal;
371366
372− rcu_read_lock();
373− list_for_each_entry_rcu(l, &laundrettes, list) {
374− if (l->net == net) {
375− spin_lock(&l->lock);
376− list_splice_tail_init(files, &l->freeme);
377− spin_unlock(&l->lock);
378− queue_work(nfsd_filecache_wq, &l->work);
379− break;
380− }
381− }
382− rcu_read_unlock();
367+ spin_lock(&l->lock);
368+ list_splice_tail_init(files, &l->freeme);
369+ spin_unlock(&l->lock);
370+ queue_work(nfsd_filecache_wq, &l->work);
383371 }
384372
385373 static void
@@ -755,7 +743,7 @@ nfsd_file_cache_purge(struct net *net) · 369 unmodified lines
755743 }
756744
757745 static struct nfsd_fcache_disposal *
758−nfsd_alloc_fcache_disposal(struct net *net)
746+nfsd_alloc_fcache_disposal(void)
759747 {
760748 struct nfsd_fcache_disposal *l;
761749
@@ -763,7 +751,6 @@ nfsd_alloc_fcache_disposal(struct net *net) · 1 unmodified line
763751 if (!l)
764752 return NULL;
765753 INIT_WORK(&l->work, nfsd_file_delayed_close);
766− l->net = net;
767754 spin_lock_init(&l->lock);
768755 INIT_LIST_HEAD(&l->freeme);
769756 return l;
@@ -772,61 +759,27 @@ nfsd_alloc_fcache_disposal(struct net *net) · 2 unmodified lines
772759 static void
773760 nfsd_free_fcache_disposal(struct nfsd_fcache_disposal *l)
774761 {
775− rcu_assign_pointer(l->net, NULL);
776762 cancel_work_sync(&l->work);
777763 nfsd_file_dispose_list(&l->freeme);
778− kfree_rcu(l, rcu);
779−}
780−
781−static void
782−nfsd_add_fcache_disposal(struct nfsd_fcache_disposal *l)
783−{
784− spin_lock(&laundrette_lock);
785− list_add_tail_rcu(&l->list, &laundrettes);
786− spin_unlock(&laundrette_lock);
787−}
788−
789−static void
790−nfsd_del_fcache_disposal(struct nfsd_fcache_disposal *l)
791−{
792− spin_lock(&laundrette_lock);
793− list_del_rcu(&l->list);
794− spin_unlock(&laundrette_lock);
795−}
796−
797−static int
798−nfsd_alloc_fcache_disposal_net(struct net *net)
799−{
800− struct nfsd_fcache_disposal *l;
801−
802− l = nfsd_alloc_fcache_disposal(net);
803− if (!l)
804− return -ENOMEM;
805− nfsd_add_fcache_disposal(l);
806− return 0;
764+ kfree(l);
807765 }
808766
809767 static void
810768 nfsd_free_fcache_disposal_net(struct net *net)
811769 {
812− struct nfsd_fcache_disposal *l;
770+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
771+ struct nfsd_fcache_disposal *l = nn->fcache_disposal;
813772
814− rcu_read_lock();
815− list_for_each_entry_rcu(l, &laundrettes, list) {
816− if (l->net != net)
817− continue;
818− nfsd_del_fcache_disposal(l);
819− rcu_read_unlock();
820− nfsd_free_fcache_disposal(l);
821− return;
822− }
823− rcu_read_unlock();
773+ nfsd_free_fcache_disposal(l);
824774 }
825775
826776 int
827777 nfsd_file_cache_start_net(struct net *net)
828778 {
829− return nfsd_alloc_fcache_disposal_net(net);
779+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
780+
781+ nn->fcache_disposal = nfsd_alloc_fcache_disposal();
782+ return nn->fcache_disposal ? 0 : -ENOMEM;
830783 }
831784
832785 void
fs/nfsd/filecache.h+0−1
@@ -46,7 +46,6 @@ struct nfsd_file { · 45 unmodified lines
4646 refcount_t nf_ref;
4747 unsigned char nf_may;
4848 struct nfsd_file_mark *nf_mark;
49− struct rw_semaphore nf_rwsem;
5049 };
5150
5251 int nfsd_file_cache_init(void);
fs/nfsd/netns.h+16−11
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <net/net_namespace.h>
1212 #include <net/netns/generic.h>
1313 #include <linux/percpu_counter.h>
14+#include <linux/siphash.h>
1415
1516 /* Hash tables for nfs4_clientid state */
1617 #define CLIENT_HASH_BITS 4
@@ -108,9 +109,8 @@ struct nfsd_net { · 91 unmodified lines
108109 bool nfsd_net_up;
109110 bool lockd_up;
110111
111− /* Time of server startup */
112− struct timespec64 nfssvc_boot;
113− seqlock_t boot_lock;
112+ seqlock_t writeverf_lock;
113+ unsigned char writeverf[8];
114114
115115 /*
116116 * Max number of connections this nfsd container will allow. Defaults
@@ -123,12 +123,13 @@ struct nfsd_net { · 6 unmodified lines
123123 u32 clverifier_counter;
124124
125125 struct svc_serv *nfsd_serv;
126−
127− wait_queue_head_t ntf_wq;
128− atomic_t ntf_refcnt;
129−
130− /* Allow umount to wait for nfsd state cleanup */
131− struct completion nfsd_shutdown_complete;
126+ /* When a listening socket is added to nfsd, keep_active is set
127+ * and this justifies a reference on nfsd_serv. This stops
128+ * nfsd_serv from being freed. When the number of threads is
129+ * set, keep_active is cleared and the reference is dropped. So
130+ * when the last thread exits, the service will be destroyed.
131+ */
132+ int keep_active;
132133
133134 /*
134135 * clientid and stateid data for construction of net unique COPY
@@ -184,6 +185,10 @@ struct nfsd_net { · 49 unmodified lines
184185
185186 /* utsname taken from the process that starts the server */
186187 char nfsd_name[UNX_MAXNODENAME+1];
188+
189+ struct nfsd_fcache_disposal *fcache_disposal;
190+
191+ siphash_key_t siphash_key;
187192 };
188193
189194 /* Simple check to find out if a given net was properly initialized */
@@ -193,6 +198,6 @@ extern void nfsd_netns_free_versions(struct nfsd_net *nn); · 3 unmodified lines
193198
194199 extern unsigned int nfsd_net_id;
195200
196−void nfsd_copy_boot_verifier(__be32 verf[2], struct nfsd_net *nn);
197−void nfsd_reset_boot_verifier(struct nfsd_net *nn);
201+void nfsd_copy_write_verifier(__be32 verf[2], struct nfsd_net *nn);
202+void nfsd_reset_write_verifier(struct nfsd_net *nn);
198203 #endif /* __NFSD_NETNS_H__ */
fs/nfsd/nfs3proc.c+1−5
@@ -202,15 +202,11 @@ nfsd3_proc_write(struct svc_rqst *rqstp) · 201 unmodified lines
202202 fh_copy(&resp->fh, &argp->fh);
203203 resp->committed = argp->stable;
204204 nvecs = svc_fill_write_vector(rqstp, &argp->payload);
205− if (!nvecs) {
206− resp->status = nfserr_io;
207− goto out;
208− }
205+
209206 resp->status = nfsd_write(rqstp, &resp->fh, argp->offset,
210207 rqstp->rq_vec, nvecs, &cnt,
211208 resp->committed, resp->verf);
212209 resp->count = cnt;
213−out:
214210 return rpc_success;
215211 }
216212
fs/nfsd/nfs3xdr.c+0−65
@@ -487,71 +487,6 @@ neither: · 486 unmodified lines
487487 return true;
488488 }
489489
490−static bool fs_supports_change_attribute(struct super_block *sb)
491−{
492− return sb->s_flags & SB_I_VERSION || sb->s_export_op->fetch_iversion;
493−}
494−
495−/*
496− * Fill in the pre_op attr for the wcc data
497− */
498−void fill_pre_wcc(struct svc_fh *fhp)
499−{
500− struct inode *inode;
501− struct kstat stat;
502− bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
503−
504− if (fhp->fh_no_wcc || fhp->fh_pre_saved)
505− return;
506− inode = d_inode(fhp->fh_dentry);
507− if (fs_supports_change_attribute(inode->i_sb) || !v4) {
508− __be32 err = fh_getattr(fhp, &stat);
509−
510− if (err) {
511− /* Grab the times from inode anyway */
512− stat.mtime = inode->i_mtime;
513− stat.ctime = inode->i_ctime;
514− stat.size = inode->i_size;
515− }
516− fhp->fh_pre_mtime = stat.mtime;
517− fhp->fh_pre_ctime = stat.ctime;
518− fhp->fh_pre_size = stat.size;
519− }
520− if (v4)
521− fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
522−
523− fhp->fh_pre_saved = true;
524−}
525−
526−/*
527− * Fill in the post_op attr for the wcc data
528− */
529−void fill_post_wcc(struct svc_fh *fhp)
530−{
531− bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
532− struct inode *inode = d_inode(fhp->fh_dentry);
533−
534− if (fhp->fh_no_wcc)
535− return;
536−
537− if (fhp->fh_post_saved)
538− printk("nfsd: inode locked twice during operation.\n");
539−
540− fhp->fh_post_saved = true;
541−
542− if (fs_supports_change_attribute(inode->i_sb) || !v4) {
543− __be32 err = fh_getattr(fhp, &fhp->fh_post_attr);
544−
545− if (err) {
546− fhp->fh_post_saved = false;
547− fhp->fh_post_attr.ctime = inode->i_ctime;
548− }
549− }
550− if (v4)
551− fhp->fh_post_change =
552− nfsd4_change_attribute(&fhp->fh_post_attr, inode);
553−}
554−
555490 /*
556491 * XDR decode functions
557492 */
fs/nfsd/nfs4proc.c+13−11
@@ -598,7 +598,7 @@ static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net) · 597 unmodified lines
598598
599599 BUILD_BUG_ON(2*sizeof(*verf) != sizeof(verifier->data));
600600
601− nfsd_copy_boot_verifier(verf, net_generic(net, nfsd_net_id));
601+ nfsd_copy_write_verifier(verf, net_generic(net, nfsd_net_id));
602602 }
603603
604604 static __be32
@@ -1101,7 +1101,7 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 496 unmodified lines
11011101 if (status)
11021102 goto out;
11031103
1104− status = nfsd4_clone_file_range(src, clone->cl_src_pos,
1104+ status = nfsd4_clone_file_range(rqstp, src, clone->cl_src_pos,
11051105 dst, clone->cl_dst_pos, clone->cl_count,
11061106 EX_ISSYNC(cstate->current_fh.fh_export));
11071107
@@ -1510,11 +1510,14 @@ static void nfsd4_init_copy_res(struct nfsd4_copy *copy, bool sync) · 402 unmodified lines
15101510
15111511 static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy)
15121512 {
1513+ struct file *dst = copy->nf_dst->nf_file;
1514+ struct file *src = copy->nf_src->nf_file;
1515+ errseq_t since;
15131516 ssize_t bytes_copied = 0;
15141517 u64 bytes_total = copy->cp_count;
15151518 u64 src_pos = copy->cp_src_pos;
15161519 u64 dst_pos = copy->cp_dst_pos;
1517− __be32 status;
1520+ int status;
15181521
15191522 /* See RFC 7862 p.67: */
15201523 if (bytes_total == 0)
@@ -1522,9 +1525,8 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy) · 1 unmodified line
15221525 do {
15231526 if (kthread_should_stop())
15241527 break;
1525− bytes_copied = nfsd_copy_file_range(copy->nf_src->nf_file,
1526− src_pos, copy->nf_dst->nf_file, dst_pos,
1527− bytes_total);
1528+ bytes_copied = nfsd_copy_file_range(src, src_pos, dst, dst_pos,
1529+ bytes_total);
15281530 if (bytes_copied <= 0)
15291531 break;
15301532 bytes_total -= bytes_copied;
@@ -1534,11 +1536,11 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy) · 3 unmodified lines
15341536 } while (bytes_total > 0 && !copy->cp_synchronous);
15351537 /* for a non-zero asynchronous copy do a commit of data */
15361538 if (!copy->cp_synchronous && copy->cp_res.wr_bytes_written > 0) {
1537− down_write(&copy->nf_dst->nf_rwsem);
1538− status = vfs_fsync_range(copy->nf_dst->nf_file,
1539− copy->cp_dst_pos,
1539+ since = READ_ONCE(dst->f_wb_err);
1540+ status = vfs_fsync_range(dst, copy->cp_dst_pos,
15401541 copy->cp_res.wr_bytes_written, 0);
1541− up_write(&copy->nf_dst->nf_rwsem);
1542+ if (!status)
1543+ status = filemap_check_wb_err(dst->f_mapping, since);
15421544 if (!status)
15431545 copy->committed = true;
15441546 }
@@ -2528,7 +2530,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) · 983 unmodified lines
25282530 goto encode_op;
25292531 }
25302532
2531− fh_clear_wcc(current_fh);
2533+ fh_clear_pre_post_attrs(current_fh);
25322534
25332535 /* If op is non-idempotent */
25342536 if (op->opdesc->op_flags & OP_MODIFIES_SOMETHING) {
fs/nfsd/nfs4state.c+49−14
@@ -246,6 +246,7 @@ find_blocked_lock(struct nfs4_lockowner *lo, struct knfsd_fh *fh, · 245 unmodified lines
246246 list_for_each_entry(cur, &lo->lo_blocked, nbl_list) {
247247 if (fh_match(fh, &cur->nbl_fh)) {
248248 list_del_init(&cur->nbl_list);
249+ WARN_ON(list_empty(&cur->nbl_lru));
249250 list_del_init(&cur->nbl_lru);
250251 found = cur;
251252 break;
@@ -271,6 +272,7 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh, · 19 unmodified lines
271272 INIT_LIST_HEAD(&nbl->nbl_lru);
272273 fh_copy_shallow(&nbl->nbl_fh, fh);
273274 locks_init_lock(&nbl->nbl_lock);
275+ kref_init(&nbl->nbl_kref);
274276 nfsd4_init_cb(&nbl->nbl_cb, lo->lo_owner.so_client,
275277 &nfsd4_cb_notify_lock_ops,
276278 NFSPROC4_CLNT_CB_NOTIFY_LOCK);
@@ -279,12 +281,21 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh, · 2 unmodified lines
279281 return nbl;
280282 }
281283
284+static void
285+free_nbl(struct kref *kref)
286+{
287+ struct nfsd4_blocked_lock *nbl;
288+
289+ nbl = container_of(kref, struct nfsd4_blocked_lock, nbl_kref);
290+ kfree(nbl);
291+}
292+
282293 static void
283294 free_blocked_lock(struct nfsd4_blocked_lock *nbl)
284295 {
285296 locks_delete_block(&nbl->nbl_lock);
286297 locks_release_private(&nbl->nbl_lock);
287− kfree(nbl);
298+ kref_put(&nbl->nbl_kref, free_nbl);
288299 }
289300
290301 static void
@@ -302,6 +313,7 @@ remove_blocked_locks(struct nfs4_lockowner *lo) · 11 unmodified lines
302313 struct nfsd4_blocked_lock,
303314 nbl_list);
304315 list_del_init(&nbl->nbl_list);
316+ WARN_ON(list_empty(&nbl->nbl_lru));
305317 list_move(&nbl->nbl_lru, &reaplist);
306318 }
307319 spin_unlock(&nn->blocked_locks_lock);
@@ -360,11 +372,13 @@ static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops = { · 52 unmodified lines
360372 * st_{access,deny}_bmap field of the stateid, in order to track not
361373 * only what share bits are currently in force, but also what
362374 * combinations of share bits previous opens have used. This allows us
363− * to enforce the recommendation of rfc 3530 14.2.19 that the server
364− * return an error if the client attempt to downgrade to a combination
365− * of share bits not explicable by closing some of its previous opens.
375+ * to enforce the recommendation in
376+ * https://datatracker.ietf.org/doc/html/rfc7530#section-16.19.4 that
377+ * the server return an error if the client attempt to downgrade to a
378+ * combination of share bits not explicable by closing some of its
379+ * previous opens.
366380 *
367− * XXX: This enforcement is actually incomplete, since we don't keep
381+ * This enforcement is arguably incomplete, since we don't keep
368382 * track of access/deny bit combinations; so, e.g., we allow:
369383 *
370384 * OPEN allow read, deny write
@@ -372,6 +386,10 @@ static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops = { · 1 unmodified line
372386 * DOWNGRADE allow read, deny none
373387 *
374388 * which we should reject.
389+ *
390+ * But you could also argue that our current code is already overkill,
391+ * since it only exists to return NFS4ERR_INVAL on incorrect client
392+ * behavior.
375393 */
376394 static unsigned int
377395 bmap_to_share_mode(unsigned long bmap)
@@ -6040,7 +6058,11 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, · 5662 unmodified lines
60406058 *nfp = NULL;
60416059
60426060 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
6043− status = check_special_stateids(net, fhp, stateid, flags);
6061+ if (cstid)
6062+ status = nfserr_bad_stateid;
6063+ else
6064+ status = check_special_stateids(net, fhp, stateid,
6065+ flags);
60446066 goto done;
60456067 }
60466068
@@ -6836,7 +6858,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 789 unmodified lines
68366858 struct nfsd4_blocked_lock *nbl = NULL;
68376859 struct file_lock *file_lock = NULL;
68386860 struct file_lock *conflock = NULL;
6839− struct super_block *sb;
68406861 __be32 status = 0;
68416862 int lkflg;
68426863 int err;
@@ -6858,7 +6879,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 15 unmodified lines
68586879 dprintk("NFSD: nfsd4_lock: permission denied!\n");
68596880 return status;
68606881 }
6861− sb = cstate->current_fh.fh_dentry->d_sb;
68626882
68636883 if (lock->lk_is_new) {
68646884 if (nfsd4_has_session(cstate))
@@ -6910,8 +6930,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 45 unmodified lines
69106930 fp = lock_stp->st_stid.sc_file;
69116931 switch (lock->lk_type) {
69126932 case NFS4_READW_LT:
6913− if (nfsd4_has_session(cstate) &&
6914− !(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS))
6933+ if (nfsd4_has_session(cstate))
69156934 fl_flags |= FL_SLEEP;
69166935 fallthrough;
69176936 case NFS4_READ_LT:
@@ -6923,8 +6942,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 5 unmodified lines
69236942 fl_type = F_RDLCK;
69246943 break;
69256944 case NFS4_WRITEW_LT:
6926− if (nfsd4_has_session(cstate) &&
6927− !(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS))
6945+ if (nfsd4_has_session(cstate))
69286946 fl_flags |= FL_SLEEP;
69296947 fallthrough;
69306948 case NFS4_WRITE_LT:
@@ -6945,6 +6963,16 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 14 unmodified lines
69456963 goto out;
69466964 }
69476965
6966+ /*
6967+ * Most filesystems with their own ->lock operations will block
6968+ * the nfsd thread waiting to acquire the lock. That leads to
6969+ * deadlocks (we don't want every nfsd thread tied up waiting
6970+ * for file locks), so don't attempt blocking lock notifications
6971+ * on those filesystems:
6972+ */
6973+ if (nf->nf_file->f_op->lock)
6974+ fl_flags &= ~FL_SLEEP;
6975+
69486976 nbl = find_or_allocate_block(lock_sop, &fp->fi_fhandle, nn);
69496977 if (!nbl) {
69506978 dprintk("NFSD: %s: unable to allocate block!\n", __func__);
@@ -6975,6 +7003,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 24 unmodified lines
69757003 spin_lock(&nn->blocked_locks_lock);
69767004 list_add_tail(&nbl->nbl_list, &lock_sop->lo_blocked);
69777005 list_add_tail(&nbl->nbl_lru, &nn->blocked_locks_lru);
7006+ kref_get(&nbl->nbl_kref);
69787007 spin_unlock(&nn->blocked_locks_lock);
69797008 }
69807009
@@ -6987,6 +7016,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 6 unmodified lines
69877016 nn->somebody_reclaimed = true;
69887017 break;
69897018 case FILE_LOCK_DEFERRED:
7019+ kref_put(&nbl->nbl_kref, free_nbl);
69907020 nbl = NULL;
69917021 fallthrough;
69927022 case -EAGAIN: /* conflock holds conflicting lock */
@@ -7007,8 +7037,13 @@ out: · 14 unmodified lines
70077037 /* dequeue it if we queued it before */
70087038 if (fl_flags & FL_SLEEP) {
70097039 spin_lock(&nn->blocked_locks_lock);
7010− list_del_init(&nbl->nbl_list);
7011− list_del_init(&nbl->nbl_lru);
7040+ if (!list_empty(&nbl->nbl_list) &&
7041+ !list_empty(&nbl->nbl_lru)) {
7042+ list_del_init(&nbl->nbl_list);
7043+ list_del_init(&nbl->nbl_lru);
7044+ kref_put(&nbl->nbl_kref, free_nbl);
7045+ }
7046+ /* nbl can use one of lists to be linked to reaplist */
70127047 spin_unlock(&nn->blocked_locks_lock);
70137048 }
70147049 free_blocked_lock(nbl);
fs/nfsd/nfs4xdr.c+5−16
@@ -277,21 +277,10 @@ nfsd4_decode_verifier4(struct nfsd4_compoundargs *argp, nfs4_verifier *verf) · 276 unmodified lines
277277 static __be32
278278 nfsd4_decode_bitmap4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen)
279279 {
280− u32 i, count;
281− __be32 *p;
282−
283− if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
284− return nfserr_bad_xdr;
285− /* request sanity */
286− if (count > 1000)
287− return nfserr_bad_xdr;
288− p = xdr_inline_decode(argp->xdr, count << 2);
289− if (!p)
290− return nfserr_bad_xdr;
291− for (i = 0; i < bmlen; i++)
292− bmval[i] = (i < count) ? be32_to_cpup(p++) : 0;
280+ ssize_t status;
293281
294− return nfs_ok;
282+ status = xdr_stream_decode_uint32_array(argp->xdr, bmval, bmlen);
283+ return status == -EBADMSG ? nfserr_bad_xdr : nfs_ok;
295284 }
296285
297286 static __be32
@@ -4804,8 +4793,8 @@ nfsd4_encode_read_plus_hole(struct nfsd4_compoundres *resp, · 4506 unmodified lines
48044793 return nfserr_resource;
48054794
48064795 *p++ = htonl(NFS4_CONTENT_HOLE);
4807− p = xdr_encode_hyper(p, read->rd_offset);
4808− p = xdr_encode_hyper(p, count);
4796+ p = xdr_encode_hyper(p, read->rd_offset);
4797+ p = xdr_encode_hyper(p, count);
48094798
48104799 *eof = (read->rd_offset + count) >= f_size;
48114800 *maxcount = min_t(unsigned long, count, *maxcount);
fs/nfsd/nfscache.c+1−1
@@ -87,7 +87,7 @@ nfsd_hashsize(unsigned int limit) · 86 unmodified lines
8787 static u32
8888 nfsd_cache_hash(__be32 xid, struct nfsd_net *nn)
8989 {
90− return hash_32(be32_to_cpu(xid), nn->maskbits);
90+ return hash_32((__force u32)xid, nn->maskbits);
9191 }
9292
9393 static struct svc_cacherep *
fs/nfsd/nfsctl.c+12−15
@@ -742,13 +742,12 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred · 741 unmodified lines
742742 return err;
743743
744744 err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred);
745− if (err < 0) {
746− nfsd_destroy(net);
747− return err;
748− }
749745
750− /* Decrease the count, but don't shut down the service */
751− nn->nfsd_serv->sv_nrthreads--;
746+ if (err >= 0 &&
747+ !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1))
748+ svc_get(nn->nfsd_serv);
749+
750+ nfsd_put(net);
752751 return err;
753752 }
754753
@@ -783,8 +782,10 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cr · 28 unmodified lines
783782 if (err < 0 && err != -EAFNOSUPPORT)
784783 goto out_close;
785784
786− /* Decrease the count, but don't shut down the service */
787− nn->nfsd_serv->sv_nrthreads--;
785+ if (!nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1))
786+ svc_get(nn->nfsd_serv);
787+
788+ nfsd_put(net);
788789 return 0;
789790 out_close:
790791 xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port);
@@ -793,10 +794,7 @@ out_close: · 2 unmodified lines
793794 svc_xprt_put(xprt);
794795 }
795796 out_err:
796− if (!list_empty(&nn->nfsd_serv->sv_permsocks))
797− nn->nfsd_serv->sv_nrthreads--;
798− else
799− nfsd_destroy(net);
797+ nfsd_put(net);
800798 return err;
801799 }
802800
@@ -1485,9 +1483,8 @@ static __net_init int nfsd_init_net(struct net *net) · 682 unmodified lines
14851483 nn->clientid_counter = nn->clientid_base + 1;
14861484 nn->s2s_cp_cl_id = nn->clientid_counter++;
14871485
1488− atomic_set(&nn->ntf_refcnt, 0);
1489− init_waitqueue_head(&nn->ntf_wq);
1490− seqlock_init(&nn->boot_lock);
1486+ get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key));
1487+ seqlock_init(&nn->writeverf_lock);
14911488
14921489 return 0;
14931490
fs/nfsd/nfsd.h+1−1
@@ -97,7 +97,7 @@ int nfsd_pool_stats_open(struct inode *, struct file *); · 96 unmodified lines
9797 int nfsd_pool_stats_release(struct inode *, struct file *);
9898 void nfsd_shutdown_threads(struct net *net);
9999
100−void nfsd_destroy(struct net *net);
100+void nfsd_put(struct net *net);
101101
102102 bool i_am_nfsd(void);
103103
fs/nfsd/nfsfh.c+65−1
@@ -611,6 +611,70 @@ out_negative: · 610 unmodified lines
611611 return nfserr_serverfault;
612612 }
613613
614+#ifdef CONFIG_NFSD_V3
615+
616+/**
617+ * fh_fill_pre_attrs - Fill in pre-op attributes
618+ * @fhp: file handle to be updated
619+ *
620+ */
621+void fh_fill_pre_attrs(struct svc_fh *fhp)
622+{
623+ bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
624+ struct inode *inode;
625+ struct kstat stat;
626+ __be32 err;
627+
628+ if (fhp->fh_no_wcc || fhp->fh_pre_saved)
629+ return;
630+
631+ inode = d_inode(fhp->fh_dentry);
632+ err = fh_getattr(fhp, &stat);
633+ if (err) {
634+ /* Grab the times from inode anyway */
635+ stat.mtime = inode->i_mtime;
636+ stat.ctime = inode->i_ctime;
637+ stat.size = inode->i_size;
638+ }
639+ if (v4)
640+ fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
641+
642+ fhp->fh_pre_mtime = stat.mtime;
643+ fhp->fh_pre_ctime = stat.ctime;
644+ fhp->fh_pre_size = stat.size;
645+ fhp->fh_pre_saved = true;
646+}
647+
648+/**
649+ * fh_fill_post_attrs - Fill in post-op attributes
650+ * @fhp: file handle to be updated
651+ *
652+ */
653+void fh_fill_post_attrs(struct svc_fh *fhp)
654+{
655+ bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
656+ struct inode *inode = d_inode(fhp->fh_dentry);
657+ __be32 err;
658+
659+ if (fhp->fh_no_wcc)
660+ return;
661+
662+ if (fhp->fh_post_saved)
663+ printk("nfsd: inode locked twice during operation.\n");
664+
665+ err = fh_getattr(fhp, &fhp->fh_post_attr);
666+ if (err) {
667+ fhp->fh_post_saved = false;
668+ fhp->fh_post_attr.ctime = inode->i_ctime;
669+ } else
670+ fhp->fh_post_saved = true;
671+ if (v4)
672+ fhp->fh_post_change =
673+ nfsd4_change_attribute(&fhp->fh_post_attr, inode);
674+}
675+
676+#endif /* CONFIG_NFSD_V3 */
677+
614678 /*
615679 * Release a file handle.
616680 */
@@ -623,7 +687,7 @@ fh_put(struct svc_fh *fhp) · 6 unmodified lines
623687 fh_unlock(fhp);
624688 fhp->fh_dentry = NULL;
625689 dput(dentry);
626− fh_clear_wcc(fhp);
690+ fh_clear_pre_post_attrs(fhp);
627691 }
628692 fh_drop_write(fhp);
629693 if (exp) {
fs/nfsd/nfsfh.h+26−14
@@ -284,12 +284,13 @@ static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh) · 283 unmodified lines
284284 #endif
285285
286286 #ifdef CONFIG_NFSD_V3
287−/*
288− * The wcc data stored in current_fh should be cleared
289− * between compound ops.
287+
288+/**
289+ * fh_clear_pre_post_attrs - Reset pre/post attributes
290+ * @fhp: file handle to be updated
291+ *
290292 */
291−static inline void
292−fh_clear_wcc(struct svc_fh *fhp)
293+static inline void fh_clear_pre_post_attrs(struct svc_fh *fhp)
293294 {
294295 fhp->fh_post_saved = false;
295296 fhp->fh_pre_saved = false;
@@ -323,13 +324,24 @@ static inline u64 nfsd4_change_attribute(struct kstat *stat, · 27 unmodified lines
323324 return time_to_chattr(&stat->ctime);
324325 }
325326
326−extern void fill_pre_wcc(struct svc_fh *fhp);
327−extern void fill_post_wcc(struct svc_fh *fhp);
328−#else
329−#define fh_clear_wcc(ignored)
330−#define fill_pre_wcc(ignored)
331−#define fill_post_wcc(notused)
332−#endif /* CONFIG_NFSD_V3 */
327+extern void fh_fill_pre_attrs(struct svc_fh *fhp);
328+extern void fh_fill_post_attrs(struct svc_fh *fhp);
329+
330+#else /* !CONFIG_NFSD_V3 */
331+
332+static inline void fh_clear_pre_post_attrs(struct svc_fh *fhp)
333+{
334+}
335+
336+static inline void fh_fill_pre_attrs(struct svc_fh *fhp)
337+{
338+}
339+
340+static inline void fh_fill_post_attrs(struct svc_fh *fhp)
341+{
342+}
343+
344+#endif /* !CONFIG_NFSD_V3 */
333345
334346
335347 /*
@@ -355,7 +367,7 @@ fh_lock_nested(struct svc_fh *fhp, unsigned int subclass) · 19 unmodified lines
355367
356368 inode = d_inode(dentry);
357369 inode_lock_nested(inode, subclass);
358− fill_pre_wcc(fhp);
370+ fh_fill_pre_attrs(fhp);
359371 fhp->fh_locked = true;
360372 }
361373
@@ -372,7 +384,7 @@ static inline void · 10 unmodified lines
372384 fh_unlock(struct svc_fh *fhp)
373385 {
374386 if (fhp->fh_locked) {
375− fill_post_wcc(fhp);
387+ fh_fill_post_attrs(fhp);
376388 inode_unlock(d_inode(fhp->fh_dentry));
377389 fhp->fh_locked = false;
378390 }
fs/nfsd/nfsproc.c+3−5
@@ -235,10 +235,6 @@ nfsd_proc_write(struct svc_rqst *rqstp) · 234 unmodified lines
235235 argp->len, argp->offset);
236236
237237 nvecs = svc_fill_write_vector(rqstp, &argp->payload);
238− if (!nvecs) {
239− resp->status = nfserr_io;
240− goto out;
241− }
242238
243239 resp->status = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh),
244240 argp->offset, rqstp->rq_vec, nvecs,
@@ -247,7 +243,6 @@ nfsd_proc_write(struct svc_rqst *rqstp) · 2 unmodified lines
247243 resp->status = fh_getattr(&resp->fh, &resp->stat);
248244 else if (resp->status == nfserr_jukebox)
249245 return rpc_drop_reply;
250−out:
251246 return rpc_success;
252247 }
253248
@@ -850,6 +845,7 @@ nfserrno (int errno) · 596 unmodified lines
850845 { nfserr_io, -EIO },
851846 { nfserr_nxio, -ENXIO },
852847 { nfserr_fbig, -E2BIG },
848+ { nfserr_stale, -EBADF },
853849 { nfserr_acces, -EACCES },
854850 { nfserr_exist, -EEXIST },
855851 { nfserr_xdev, -EXDEV },
@@ -878,6 +874,8 @@ nfserrno (int errno) · 22 unmodified lines
878874 { nfserr_toosmall, -ETOOSMALL },
879875 { nfserr_serverfault, -ESERVERFAULT },
880876 { nfserr_serverfault, -ENFILE },
877+ { nfserr_io, -EREMOTEIO },
878+ { nfserr_stale, -EOPENSTALE },
881879 { nfserr_io, -EUCLEAN },
882880 { nfserr_perm, -ENOKEY },
883881 { nfserr_no_grace, -ENOGRACE},
fs/nfsd/nfssvc.c+126−94
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <linux/module.h>
1313 #include <linux/fs_struct.h>
1414 #include <linux/swap.h>
15+#include <linux/siphash.h>
1516
1617 #include <linux/sunrpc/stats.h>
1718 #include <linux/sunrpc/svcsock.h>
@@ -55,18 +56,17 @@ static __be32 nfsd_init_request(struct svc_rqst *, · 37 unmodified lines
5556 struct svc_process_info *);
5657
5758 /*
58− * nfsd_mutex protects nn->nfsd_serv -- both the pointer itself and the members
59− * of the svc_serv struct. In particular, ->sv_nrthreads but also to some
60− * extent ->sv_temp_socks and ->sv_permsocks. It also protects nfsdstats.th_cnt
59+ * nfsd_mutex protects nn->nfsd_serv -- both the pointer itself and some members
60+ * of the svc_serv struct such as ->sv_temp_socks and ->sv_permsocks.
6161 *
6262 * If (out side the lock) nn->nfsd_serv is non-NULL, then it must point to a
63− * properly initialised 'struct svc_serv' with ->sv_nrthreads > 0. That number
64− * of nfsd threads must exist and each must listed in ->sp_all_threads in each
65− * entry of ->sv_pools[].
63+ * properly initialised 'struct svc_serv' with ->sv_nrthreads > 0 (unless
64+ * nn->keep_active is set). That number of nfsd threads must
65+ * exist and each must be listed in ->sp_all_threads in some entry of
66+ * ->sv_pools[].
6667 *
67− * Transitions of the thread count between zero and non-zero are of particular
68− * interest since the svc_serv needs to be created and initialized at that
69− * point, or freed.
68+ * Each active thread holds a counted reference on nn->nfsd_serv, as does
69+ * the nn->keep_active flag and various transient calls to svc_get().
7070 *
7171 * Finally, the nfsd_mutex also protects some of the global variables that are
7272 * accessed when nfsd starts and that are settable via the write_* routines in
@@ -345,33 +345,57 @@ static bool nfsd_needs_lockd(struct nfsd_net *nn) · 272 unmodified lines
345345 return nfsd_vers(nn, 2, NFSD_TEST) || nfsd_vers(nn, 3, NFSD_TEST);
346346 }
347347
348−void nfsd_copy_boot_verifier(__be32 verf[2], struct nfsd_net *nn)
348+/**
349+ * nfsd_copy_write_verifier - Atomically copy a write verifier
350+ * @verf: buffer in which to receive the verifier cookie
351+ * @nn: NFS net namespace
352+ *
353+ * This function provides a wait-free mechanism for copying the
354+ * namespace's write verifier without tearing it.
355+ */
356+void nfsd_copy_write_verifier(__be32 verf[2], struct nfsd_net *nn)
349357 {
350358 int seq = 0;
351359
352360 do {
353− read_seqbegin_or_lock(&nn->boot_lock, &seq);
354− /*
355− * This is opaque to client, so no need to byte-swap. Use
356− * __force to keep sparse happy. y2038 time_t overflow is
357− * irrelevant in this usage
358− */
359− verf[0] = (__force __be32)nn->nfssvc_boot.tv_sec;
360− verf[1] = (__force __be32)nn->nfssvc_boot.tv_nsec;
361− } while (need_seqretry(&nn->boot_lock, seq));
362− done_seqretry(&nn->boot_lock, seq);
361+ read_seqbegin_or_lock(&nn->writeverf_lock, &seq);
362+ memcpy(verf, nn->writeverf, sizeof(*verf));
363+ } while (need_seqretry(&nn->writeverf_lock, seq));
364+ done_seqretry(&nn->writeverf_lock, seq);
363365 }
364366
365−static void nfsd_reset_boot_verifier_locked(struct nfsd_net *nn)
367+static void nfsd_reset_write_verifier_locked(struct nfsd_net *nn)
366368 {
367− ktime_get_real_ts64(&nn->nfssvc_boot);
369+ struct timespec64 now;
370+ u64 verf;
371+
372+ /*
373+ * Because the time value is hashed, y2038 time_t overflow
374+ * is irrelevant in this usage.
375+ */
376+ ktime_get_raw_ts64(&now);
377+ verf = siphash_2u64(now.tv_sec, now.tv_nsec, &nn->siphash_key);
378+ memcpy(nn->writeverf, &verf, sizeof(nn->writeverf));
368379 }
369380
370−void nfsd_reset_boot_verifier(struct nfsd_net *nn)
381+/**
382+ * nfsd_reset_write_verifier - Generate a new write verifier
383+ * @nn: NFS net namespace
384+ *
385+ * This function updates the ->writeverf field of @nn. This field
386+ * contains an opaque cookie that, according to Section 18.32.3 of
387+ * RFC 8881, "the client can use to determine whether a server has
388+ * changed instance state (e.g., server restart) between a call to
389+ * WRITE and a subsequent call to either WRITE or COMMIT. This
390+ * cookie MUST be unchanged during a single instance of the NFSv4.1
391+ * server and MUST be unique between instances of the NFSv4.1
392+ * server."
393+ */
394+void nfsd_reset_write_verifier(struct nfsd_net *nn)
371395 {
372− write_seqlock(&nn->boot_lock);
373− nfsd_reset_boot_verifier_locked(nn);
374− write_sequnlock(&nn->boot_lock);
396+ write_seqlock(&nn->writeverf_lock);
397+ nfsd_reset_write_verifier_locked(nn);
398+ write_sequnlock(&nn->writeverf_lock);
375399 }
376400
377401 static int nfsd_startup_net(struct net *net, const struct cred *cred)
@@ -435,6 +459,7 @@ static void nfsd_shutdown_net(struct net *net) · 57 unmodified lines
435459 nfsd_shutdown_generic();
436460 }
437461
462+static DEFINE_SPINLOCK(nfsd_notifier_lock);
438463 static int nfsd_inetaddr_event(struct notifier_block *this, unsigned long event,
439464 void *ptr)
440465 {
@@ -444,18 +469,17 @@ static int nfsd_inetaddr_event(struct notifier_block *this, unsigned long event, · 3 unmodified lines
444469 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
445470 struct sockaddr_in sin;
446471
447− if ((event != NETDEV_DOWN) ||
448− !atomic_inc_not_zero(&nn->ntf_refcnt))
472+ if (event != NETDEV_DOWN || !nn->nfsd_serv)
449473 goto out;
450474
475+ spin_lock(&nfsd_notifier_lock);
451476 if (nn->nfsd_serv) {
452477 dprintk("nfsd_inetaddr_event: removed %pI4\n", &ifa->ifa_local);
453478 sin.sin_family = AF_INET;
454479 sin.sin_addr.s_addr = ifa->ifa_local;
455480 svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin);
456481 }
457− atomic_dec(&nn->ntf_refcnt);
458− wake_up(&nn->ntf_wq);
482+ spin_unlock(&nfsd_notifier_lock);
459483
460484 out:
461485 return NOTIFY_DONE;
@@ -475,10 +499,10 @@ static int nfsd_inet6addr_event(struct notifier_block *this, · 13 unmodified lines
475499 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
476500 struct sockaddr_in6 sin6;
477501
478− if ((event != NETDEV_DOWN) ||
479− !atomic_inc_not_zero(&nn->ntf_refcnt))
502+ if (event != NETDEV_DOWN || !nn->nfsd_serv)
480503 goto out;
481504
505+ spin_lock(&nfsd_notifier_lock);
482506 if (nn->nfsd_serv) {
483507 dprintk("nfsd_inet6addr_event: removed %pI6\n", &ifa->addr);
484508 sin6.sin6_family = AF_INET6;
@@ -487,8 +511,8 @@ static int nfsd_inet6addr_event(struct notifier_block *this, · 2 unmodified lines
487511 sin6.sin6_scope_id = ifa->idev->dev->ifindex;
488512 svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin6);
489513 }
490− atomic_dec(&nn->ntf_refcnt);
491− wake_up(&nn->ntf_wq);
514+ spin_unlock(&nfsd_notifier_lock);
515+
492516 out:
493517 return NOTIFY_DONE;
494518 }
@@ -505,7 +529,6 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net) · 10 unmodified lines
505529 {
506530 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
507531
508− atomic_dec(&nn->ntf_refcnt);
509532 /* check if the notifier still has clients */
510533 if (atomic_dec_return(&nfsd_notifier_refcount) == 0) {
511534 unregister_inetaddr_notifier(&nfsd_inetaddr_notifier);
@@ -513,7 +536,6 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net) · 1 unmodified line
513536 unregister_inet6addr_notifier(&nfsd_inet6addr_notifier);
514537 #endif
515538 }
516− wait_event(nn->ntf_wq, atomic_read(&nn->ntf_refcnt) == 0);
517539
518540 /*
519541 * write_ports can create the server without actually starting
@@ -594,20 +616,9 @@ static const struct svc_serv_ops nfsd_thread_sv_ops = { · 74 unmodified lines
594616 .svo_shutdown = nfsd_last_thread,
595617 .svo_function = nfsd,
596618 .svo_enqueue_xprt = svc_xprt_do_enqueue,
597− .svo_setup = svc_set_num_threads,
598619 .svo_module = THIS_MODULE,
599620 };
600621
601−static void nfsd_complete_shutdown(struct net *net)
602−{
603− struct nfsd_net *nn = net_generic(net, nfsd_net_id);
604−
605− WARN_ON(!mutex_is_locked(&nfsd_mutex));
606−
607− nn->nfsd_serv = NULL;
608− complete(&nn->nfsd_shutdown_complete);
609−}
610−
611622 void nfsd_shutdown_threads(struct net *net)
612623 {
613624 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
@@ -622,11 +633,9 @@ void nfsd_shutdown_threads(struct net *net) · 8 unmodified lines
622633
623634 svc_get(serv);
624635 /* Kill outstanding nfsd threads */
625− serv->sv_ops->svo_setup(serv, NULL, 0);
626− nfsd_destroy(net);
636+ svc_set_num_threads(serv, NULL, 0);
637+ nfsd_put(net);
627638 mutex_unlock(&nfsd_mutex);
628− /* Wait for shutdown of nfsd_serv to complete */
629− wait_for_completion(&nn->nfsd_shutdown_complete);
630639 }
631640
632641 bool i_am_nfsd(void)
@@ -638,6 +647,7 @@ int nfsd_create_serv(struct net *net) · 5 unmodified lines
638647 {
639648 int error;
640649 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
650+ struct svc_serv *serv;
641651
642652 WARN_ON(!mutex_is_locked(&nfsd_mutex));
643653 if (nn->nfsd_serv) {
@@ -647,19 +657,23 @@ int nfsd_create_serv(struct net *net) · 3 unmodified lines
647657 if (nfsd_max_blksize == 0)
648658 nfsd_max_blksize = nfsd_get_default_max_blksize();
649659 nfsd_reset_versions(nn);
650− nn->nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
651− &nfsd_thread_sv_ops);
652− if (nn->nfsd_serv == NULL)
660+ serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
661+ &nfsd_thread_sv_ops);
662+ if (serv == NULL)
653663 return -ENOMEM;
654− init_completion(&nn->nfsd_shutdown_complete);
655664
656− nn->nfsd_serv->sv_maxconn = nn->max_connections;
657− error = svc_bind(nn->nfsd_serv, net);
665+ serv->sv_maxconn = nn->max_connections;
666+ error = svc_bind(serv, net);
658667 if (error < 0) {
659− svc_destroy(nn->nfsd_serv);
660− nfsd_complete_shutdown(net);
668+ /* NOT nfsd_put() as notifiers (see below) haven't
669+ * been set up yet.
670+ */
671+ svc_put(serv);
661672 return error;
662673 }
674+ spin_lock(&nfsd_notifier_lock);
675+ nn->nfsd_serv = serv;
676+ spin_unlock(&nfsd_notifier_lock);
663677
664678 set_max_drc();
665679 /* check if the notifier is already set */
@@ -669,8 +683,7 @@ int nfsd_create_serv(struct net *net) · 3 unmodified lines
669683 register_inet6addr_notifier(&nfsd_inet6addr_notifier);
670684 #endif
671685 }
672− atomic_inc(&nn->ntf_refcnt);
673− nfsd_reset_boot_verifier(nn);
686+ nfsd_reset_write_verifier(nn);
674687 return 0;
675688 }
676689
@@ -697,16 +710,26 @@ int nfsd_get_nrthreads(int n, int *nthreads, struct net *net) · 20 unmodified lines
697710 return 0;
698711 }
699712
700−void nfsd_destroy(struct net *net)
713+/* This is the callback for kref_put() below.
714+ * There is no code here as the first thing to be done is
715+ * call svc_shutdown_net(), but we cannot get the 'net' from
716+ * the kref. So do all the work when kref_put returns true.
717+ */
718+static void nfsd_noop(struct kref *ref)
719+{
720+}
721+
722+void nfsd_put(struct net *net)
701723 {
702724 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
703− int destroy = (nn->nfsd_serv->sv_nrthreads == 1);
704725
705− if (destroy)
726+ if (kref_put(&nn->nfsd_serv->sv_refcnt, nfsd_noop)) {
706727 svc_shutdown_net(nn->nfsd_serv, net);
707− svc_destroy(nn->nfsd_serv);
708− if (destroy)
709− nfsd_complete_shutdown(net);
728+ svc_destroy(&nn->nfsd_serv->sv_refcnt);
729+ spin_lock(&nfsd_notifier_lock);
730+ nn->nfsd_serv = NULL;
731+ spin_unlock(&nfsd_notifier_lock);
732+ }
710733 }
711734
712735 int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
@@ -733,7 +756,7 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) · 20 unmodified lines
733756 if (tot > NFSD_MAXSERVS) {
734757 /* total too large: scale down requested numbers */
735758 for (i = 0; i < n && tot > 0; i++) {
736− int new = nthreads[i] * NFSD_MAXSERVS / tot;
759+ int new = nthreads[i] * NFSD_MAXSERVS / tot;
737760 tot -= (nthreads[i] - new);
738761 nthreads[i] = new;
739762 }
@@ -753,12 +776,13 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) · 13 unmodified lines
753776 /* apply the new numbers */
754777 svc_get(nn->nfsd_serv);
755778 for (i = 0; i < n; i++) {
756− err = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv,
757− &nn->nfsd_serv->sv_pools[i], nthreads[i]);
779+ err = svc_set_num_threads(nn->nfsd_serv,
780+ &nn->nfsd_serv->sv_pools[i],
781+ nthreads[i]);
758782 if (err)
759783 break;
760784 }
761− nfsd_destroy(net);
785+ nfsd_put(net);
762786 return err;
763787 }
764788
@@ -795,21 +819,19 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) · 30 unmodified lines
795819
796820 error = nfsd_startup_net(net, cred);
797821 if (error)
798− goto out_destroy;
799− error = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv,
800− NULL, nrservs);
822+ goto out_put;
823+ error = svc_set_num_threads(nn->nfsd_serv, NULL, nrservs);
801824 if (error)
802825 goto out_shutdown;
803− /* We are holding a reference to nn->nfsd_serv which
804− * we don't want to count in the return value,
805− * so subtract 1
806− */
807− error = nn->nfsd_serv->sv_nrthreads - 1;
826+ error = nn->nfsd_serv->sv_nrthreads;
808827 out_shutdown:
809828 if (error < 0 && !nfsd_up_before)
810829 nfsd_shutdown_net(net);
811−out_destroy:
812− nfsd_destroy(net); /* Release server */
830+out_put:
831+ /* Threads now hold service active */
832+ if (xchg(&nn->keep_active, 0))
833+ nfsd_put(net);
834+ nfsd_put(net);
813835 out:
814836 mutex_unlock(&nfsd_mutex);
815837 return error;
@@ -923,9 +945,6 @@ nfsd(void *vrqstp) · 107 unmodified lines
923945 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
924946 int err;
925947
926− /* Lock module and set up kernel thread */
927− mutex_lock(&nfsd_mutex);
928−
929948 /* At this point, the thread shares current->fs
930949 * with the init process. We need to create files with the
931950 * umask as defined by the client instead of init's umask. */
@@ -945,8 +964,7 @@ nfsd(void *vrqstp) · 13 unmodified lines
945964 allow_signal(SIGINT);
946965 allow_signal(SIGQUIT);
947966
948− nfsdstats.th_cnt++;
949− mutex_unlock(&nfsd_mutex);
967+ atomic_inc(&nfsdstats.th_cnt);
950968
951969 set_freezable();
952970
@@ -973,19 +991,35 @@ nfsd(void *vrqstp) · 20 unmodified lines
973991 /* Clear signals before calling svc_exit_thread() */
974992 flush_signals(current);
975993
976− mutex_lock(&nfsd_mutex);
977− nfsdstats.th_cnt --;
994+ atomic_dec(&nfsdstats.th_cnt);
978995
979996 out:
980− rqstp->rq_server = NULL;
997+ /* Take an extra ref so that the svc_put in svc_exit_thread()
998+ * doesn't call svc_destroy()
999+ */
1000+ svc_get(nn->nfsd_serv);
9811001
9821002 /* Release the thread */
9831003 svc_exit_thread(rqstp);
9841004
985− nfsd_destroy(net);
1005+ /* We need to drop a ref, but may not drop the last reference
1006+ * without holding nfsd_mutex, and we cannot wait for nfsd_mutex as that
1007+ * could deadlock with nfsd_shutdown_threads() waiting for us.
1008+ * So three options are:
1009+ * - drop a non-final reference,
1010+ * - get the mutex without waiting
1011+ * - sleep briefly andd try the above again
1012+ */
1013+ while (!svc_put_not_last(nn->nfsd_serv)) {
1014+ if (mutex_trylock(&nfsd_mutex)) {
1015+ nfsd_put(net);
1016+ mutex_unlock(&nfsd_mutex);
1017+ break;
1018+ }
1019+ msleep(20);
1020+ }
9861021
9871022 /* Release module */
988− mutex_unlock(&nfsd_mutex);
9891023 module_put_and_exit(0);
9901024 return 0;
9911025 }
@@ -1096,7 +1130,6 @@ int nfsd_pool_stats_open(struct inode *inode, struct file *file) · 104 unmodified lines
10961130 mutex_unlock(&nfsd_mutex);
10971131 return -ENODEV;
10981132 }
1099− /* bump up the psudo refcount while traversing */
11001133 svc_get(nn->nfsd_serv);
11011134 ret = svc_pool_stats_open(nn->nfsd_serv, file);
11021135 mutex_unlock(&nfsd_mutex);
@@ -1109,8 +1142,7 @@ int nfsd_pool_stats_release(struct inode *inode, struct file *file) · 6 unmodified lines
11091142 struct net *net = inode->i_sb->s_fs_info;
11101143
11111144 mutex_lock(&nfsd_mutex);
1112− /* this function really, really should have been called svc_put() */
1113− nfsd_destroy(net);
1145+ nfsd_put(net);
11141146 mutex_unlock(&nfsd_mutex);
11151147 return ret;
11161148 }
fs/nfsd/state.h+5−0
@@ -568,6 +568,10 @@ struct nfs4_ol_stateid { · 567 unmodified lines
568568 struct list_head st_locks;
569569 struct nfs4_stateowner *st_stateowner;
570570 struct nfs4_clnt_odstate *st_clnt_odstate;
571+/*
572+ * These bitmasks use 3 separate bits for READ, ALLOW, and BOTH; see the
573+ * comment above bmap_to_share_mode() for explanation:
574+ */
571575 unsigned char st_access_bmap;
572576 unsigned char st_deny_bmap;
573577 struct nfs4_ol_stateid *st_openstp;
@@ -629,6 +633,7 @@ struct nfsd4_blocked_lock { · 55 unmodified lines
629633 struct file_lock nbl_lock;
630634 struct knfsd_fh nbl_fh;
631635 struct nfsd4_callback nbl_cb;
636+ struct kref nbl_kref;
632637 };
633638
634639 struct nfsd4_compound_state;
fs/nfsd/stats.c+1−1
@@ -45,7 +45,7 @@ static int nfsd_proc_show(struct seq_file *seq, void *v) · 44 unmodified lines
4545 percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_WRITE]));
4646
4747 /* thread usage: */
48− seq_printf(seq, "th %u 0", nfsdstats.th_cnt);
48+ seq_printf(seq, "th %u 0", atomic_read(&nfsdstats.th_cnt));
4949
5050 /* deprecated thread usage histogram stats */
5151 for (i = 0; i < 10; i++)
fs/nfsd/stats.h+1−3
@@ -29,11 +29,9 @@ enum { · 28 unmodified lines
2929 struct nfsd_stats {
3030 struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM];
3131
32− /* Protected by nfsd_mutex */
33− unsigned int th_cnt; /* number of available threads */
32+ atomic_t th_cnt; /* number of available threads */
3433 };
3534
36−
3735 extern struct nfsd_stats nfsdstats;
3836
3937 extern struct svc_stat nfsd_svcstats;
fs/nfsd/trace.h+85−21
@@ -47,7 +47,7 @@ · 46 unmodified lines
4747 rqstp->rq_xprt->xpt_remotelen); \
4848 } while (0);
4949
50−TRACE_EVENT(nfsd_garbage_args_err,
50+DECLARE_EVENT_CLASS(nfsd_xdr_err_class,
5151 TP_PROTO(
5252 const struct svc_rqst *rqstp
5353 ),
@@ -69,27 +69,13 @@ TRACE_EVENT(nfsd_garbage_args_err, · 15 unmodified lines
6969 )
7070 );
7171
72−TRACE_EVENT(nfsd_cant_encode_err,
73− TP_PROTO(
74− const struct svc_rqst *rqstp
75− ),
76− TP_ARGS(rqstp),
77− TP_STRUCT__entry(
78− NFSD_TRACE_PROC_ARG_FIELDS
79−
80− __field(u32, vers)
81− __field(u32, proc)
82− ),
83− TP_fast_assign(
84− NFSD_TRACE_PROC_ARG_ASSIGNMENTS
72+#define DEFINE_NFSD_XDR_ERR_EVENT(name) \
73+DEFINE_EVENT(nfsd_xdr_err_class, nfsd_##name##_err, \
74+ TP_PROTO(const struct svc_rqst *rqstp), \
75+ TP_ARGS(rqstp))
8576
86− __entry->vers = rqstp->rq_vers;
87− __entry->proc = rqstp->rq_proc;
88− ),
89− TP_printk("xid=0x%08x vers=%u proc=%u",
90− __entry->xid, __entry->vers, __entry->proc
91− )
92−);
77+DEFINE_NFSD_XDR_ERR_EVENT(garbage_args);
78+DEFINE_NFSD_XDR_ERR_EVENT(cant_encode);
9379
9480 #define show_nfsd_may_flags(x) \
9581 __print_flags(x, "|", \
@@ -413,6 +399,56 @@ TRACE_EVENT(nfsd_dirent, · 317 unmodified lines
413399 )
414400 )
415401
402+DECLARE_EVENT_CLASS(nfsd_copy_err_class,
403+ TP_PROTO(struct svc_rqst *rqstp,
404+ struct svc_fh *src_fhp,
405+ loff_t src_offset,
406+ struct svc_fh *dst_fhp,
407+ loff_t dst_offset,
408+ u64 count,
409+ int status),
410+ TP_ARGS(rqstp, src_fhp, src_offset, dst_fhp, dst_offset, count, status),
411+ TP_STRUCT__entry(
412+ __field(u32, xid)
413+ __field(u32, src_fh_hash)
414+ __field(loff_t, src_offset)
415+ __field(u32, dst_fh_hash)
416+ __field(loff_t, dst_offset)
417+ __field(u64, count)
418+ __field(int, status)
419+ ),
420+ TP_fast_assign(
421+ __entry->xid = be32_to_cpu(rqstp->rq_xid);
422+ __entry->src_fh_hash = knfsd_fh_hash(&src_fhp->fh_handle);
423+ __entry->src_offset = src_offset;
424+ __entry->dst_fh_hash = knfsd_fh_hash(&dst_fhp->fh_handle);
425+ __entry->dst_offset = dst_offset;
426+ __entry->count = count;
427+ __entry->status = status;
428+ ),
429+ TP_printk("xid=0x%08x src_fh_hash=0x%08x src_offset=%lld "
430+ "dst_fh_hash=0x%08x dst_offset=%lld "
431+ "count=%llu status=%d",
432+ __entry->xid, __entry->src_fh_hash, __entry->src_offset,
433+ __entry->dst_fh_hash, __entry->dst_offset,
434+ (unsigned long long)__entry->count,
435+ __entry->status)
436+)
437+
438+#define DEFINE_NFSD_COPY_ERR_EVENT(name) \
439+DEFINE_EVENT(nfsd_copy_err_class, nfsd_##name, \
440+ TP_PROTO(struct svc_rqst *rqstp, \
441+ struct svc_fh *src_fhp, \
442+ loff_t src_offset, \
443+ struct svc_fh *dst_fhp, \
444+ loff_t dst_offset, \
445+ u64 count, \
446+ int status), \
447+ TP_ARGS(rqstp, src_fhp, src_offset, dst_fhp, dst_offset, \
448+ count, status))
449+
450+DEFINE_NFSD_COPY_ERR_EVENT(clone_file_range_err);
451+
416452 #include "state.h"
417453 #include "filecache.h"
418454 #include "vfs.h"
@@ -538,6 +574,34 @@ DEFINE_EVENT(nfsd_net_class, nfsd_##name, \ · 119 unmodified lines
538574 DEFINE_NET_EVENT(grace_start);
539575 DEFINE_NET_EVENT(grace_complete);
540576
577+TRACE_EVENT(nfsd_writeverf_reset,
578+ TP_PROTO(
579+ const struct nfsd_net *nn,
580+ const struct svc_rqst *rqstp,
581+ int error
582+ ),
583+ TP_ARGS(nn, rqstp, error),
584+ TP_STRUCT__entry(
585+ __field(unsigned long long, boot_time)
586+ __field(u32, xid)
587+ __field(int, error)
588+ __array(unsigned char, verifier, NFS4_VERIFIER_SIZE)
589+ ),
590+ TP_fast_assign(
591+ __entry->boot_time = nn->boot_time;
592+ __entry->xid = be32_to_cpu(rqstp->rq_xid);
593+ __entry->error = error;
594+
595+ /* avoid seqlock inside TP_fast_assign */
596+ memcpy(__entry->verifier, nn->writeverf,
597+ NFS4_VERIFIER_SIZE);
598+ ),
599+ TP_printk("boot_time=%16llx xid=0x%08x error=%d new verifier=0x%s",
600+ __entry->boot_time, __entry->xid, __entry->error,
601+ __print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE)
602+ )
603+);
604+
541605 TRACE_EVENT(nfsd_clid_cred_mismatch,
542606 TP_PROTO(
543607 const struct nfs4_client *clp,
fs/nfsd/vfs.c+65−57
@@ -40,6 +40,7 @@ · 39 unmodified lines
4040 #include "../internal.h"
4141 #include "acl.h"
4242 #include "idmap.h"
43+#include "xdr4.h"
4344 #endif /* CONFIG_NFSD_V4 */
4445
4546 #include "nfsd.h"
@@ -517,15 +518,23 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, · 471 unmodified lines
517518 }
518519 #endif
519520
520−__be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
521− struct nfsd_file *nf_dst, u64 dst_pos, u64 count, bool sync)
521+static struct nfsd4_compound_state *nfsd4_get_cstate(struct svc_rqst *rqstp)
522+{
523+ return &((struct nfsd4_compoundres *)rqstp->rq_resp)->cstate;
524+}
525+
526+__be32 nfsd4_clone_file_range(struct svc_rqst *rqstp,
527+ struct nfsd_file *nf_src, u64 src_pos,
528+ struct nfsd_file *nf_dst, u64 dst_pos,
529+ u64 count, bool sync)
522530 {
523531 struct file *src = nf_src->nf_file;
524532 struct file *dst = nf_dst->nf_file;
533+ errseq_t since;
525534 loff_t cloned;
526535 __be32 ret = 0;
527536
528− down_write(&nf_dst->nf_rwsem);
537+ since = READ_ONCE(dst->f_wb_err);
529538 cloned = vfs_clone_file_range(src, src_pos, dst, dst_pos, count, 0);
530539 if (cloned < 0) {
531540 ret = nfserrno(cloned);
@@ -539,16 +548,26 @@ __be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos, · 7 unmodified lines
539548 loff_t dst_end = count ? dst_pos + count - 1 : LLONG_MAX;
540549 int status = vfs_fsync_range(dst, dst_pos, dst_end, 0);
541550
551+ if (!status)
552+ status = filemap_check_wb_err(dst->f_mapping, since);
542553 if (!status)
543554 status = commit_inode_metadata(file_inode(src));
544555 if (status < 0) {
545− nfsd_reset_boot_verifier(net_generic(nf_dst->nf_net,
546− nfsd_net_id));
556+ struct nfsd_net *nn = net_generic(nf_dst->nf_net,
557+ nfsd_net_id);
558+
559+ trace_nfsd_clone_file_range_err(rqstp,
560+ &nfsd4_get_cstate(rqstp)->save_fh,
561+ src_pos,
562+ &nfsd4_get_cstate(rqstp)->current_fh,
563+ dst_pos,
564+ count, status);
565+ nfsd_reset_write_verifier(nn);
566+ trace_nfsd_writeverf_reset(nn, rqstp, status);
547567 ret = nfserrno(status);
548568 }
549569 }
550570 out_err:
551− up_write(&nf_dst->nf_rwsem);
552571 return ret;
553572 }
554573
@@ -777,6 +796,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, · 222 unmodified lines
777796 int may_flags, struct file **filp)
778797 {
779798 __be32 err;
799+ bool retried = false;
780800
781801 validate_process_creds();
782802 /*
@@ -792,9 +812,16 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, · 9 unmodified lines
792812 */
793813 if (type == S_IFREG)
794814 may_flags |= NFSD_MAY_OWNER_OVERRIDE;
815+retry:
795816 err = fh_verify(rqstp, fhp, type, may_flags);
796− if (!err)
817+ if (!err) {
797818 err = __nfsd_open(rqstp, fhp, type, may_flags, filp);
819+ if (err == nfserr_stale && !retried) {
820+ retried = true;
821+ fh_put(fhp);
822+ goto retry;
823+ }
824+ }
798825 validate_process_creds();
799826 return err;
800827 }
@@ -944,10 +971,12 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, · 143 unmodified lines
944971 unsigned long *cnt, int stable,
945972 __be32 *verf)
946973 {
974+ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
947975 struct file *file = nf->nf_file;
948976 struct super_block *sb = file_inode(file)->i_sb;
949977 struct svc_export *exp;
950978 struct iov_iter iter;
979+ errseq_t since;
951980 __be32 nfserr;
952981 int host_err;
953982 int use_wgather;
@@ -985,36 +1014,28 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, · 31 unmodified lines
9851014 flags |= RWF_SYNC;
9861015
9871016 iov_iter_kvec(&iter, WRITE, vec, vlen, *cnt);
988− if (flags & RWF_SYNC) {
989− down_write(&nf->nf_rwsem);
990− host_err = vfs_iter_write(file, &iter, &pos, flags);
991− if (host_err < 0)
992− nfsd_reset_boot_verifier(net_generic(SVC_NET(rqstp),
993− nfsd_net_id));
994− up_write(&nf->nf_rwsem);
995− } else {
996− down_read(&nf->nf_rwsem);
997− if (verf)
998− nfsd_copy_boot_verifier(verf,
999− net_generic(SVC_NET(rqstp),
1000− nfsd_net_id));
1001− host_err = vfs_iter_write(file, &iter, &pos, flags);
1002− up_read(&nf->nf_rwsem);
1003− }
1017+ since = READ_ONCE(file->f_wb_err);
1018+ if (verf)
1019+ nfsd_copy_write_verifier(verf, nn);
1020+ host_err = vfs_iter_write(file, &iter, &pos, flags);
10041021 if (host_err < 0) {
1005− nfsd_reset_boot_verifier(net_generic(SVC_NET(rqstp),
1006− nfsd_net_id));
1022+ nfsd_reset_write_verifier(nn);
1023+ trace_nfsd_writeverf_reset(nn, rqstp, host_err);
10071024 goto out_nfserr;
10081025 }
10091026 *cnt = host_err;
10101027 nfsd_stats_io_write_add(exp, *cnt);
10111028 fsnotify_modify(file);
1029+ host_err = filemap_check_wb_err(file->f_mapping, since);
1030+ if (host_err < 0)
1031+ goto out_nfserr;
10121032
10131033 if (stable && use_wgather) {
10141034 host_err = wait_for_concurrent_writes(file);
1015− if (host_err < 0)
1016− nfsd_reset_boot_verifier(net_generic(SVC_NET(rqstp),
1017− nfsd_net_id));
1035+ if (host_err < 0) {
1036+ nfsd_reset_write_verifier(nn);
1037+ trace_nfsd_writeverf_reset(nn, rqstp, host_err);
1038+ }
10181039 }
10191040
10201041 out_nfserr:
@@ -1089,19 +1110,6 @@ out: · 68 unmodified lines
10891110 }
10901111
10911112 #ifdef CONFIG_NFSD_V3
1092−static int
1093−nfsd_filemap_write_and_wait_range(struct nfsd_file *nf, loff_t offset,
1094− loff_t end)
1095−{
1096− struct address_space *mapping = nf->nf_file->f_mapping;
1097− int ret = filemap_fdatawrite_range(mapping, offset, end);
1098−
1099− if (ret)
1100− return ret;
1101− filemap_fdatawait_range_keep_errors(mapping, offset, end);
1102− return 0;
1103−}
1104−
11051113 /*
11061114 * Commit all pending writes to stable storage.
11071115 *
@@ -1115,6 +1123,7 @@ __be32 · 7 unmodified lines
11151123 nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
11161124 loff_t offset, unsigned long count, __be32 *verf)
11171125 {
1126+ struct nfsd_net *nn;
11181127 struct nfsd_file *nf;
11191128 loff_t end = LLONG_MAX;
11201129 __be32 err = nfserr_inval;
@@ -1131,29 +1140,28 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, · 10 unmodified lines
11311140 NFSD_MAY_WRITE|NFSD_MAY_NOT_BREAK_LEASE, &nf);
11321141 if (err)
11331142 goto out;
1143+ nn = net_generic(nf->nf_net, nfsd_net_id);
11341144 if (EX_ISSYNC(fhp->fh_export)) {
1135− int err2 = nfsd_filemap_write_and_wait_range(nf, offset, end);
1145+ errseq_t since = READ_ONCE(nf->nf_file->f_wb_err);
1146+ int err2;
11361147
1137− down_write(&nf->nf_rwsem);
1138− if (!err2)
1139− err2 = vfs_fsync_range(nf->nf_file, offset, end, 0);
1148+ err2 = vfs_fsync_range(nf->nf_file, offset, end, 0);
11401149 switch (err2) {
11411150 case 0:
1142− nfsd_copy_boot_verifier(verf, net_generic(nf->nf_net,
1143− nfsd_net_id));
1151+ nfsd_copy_write_verifier(verf, nn);
1152+ err2 = filemap_check_wb_err(nf->nf_file->f_mapping,
1153+ since);
11441154 break;
11451155 case -EINVAL:
11461156 err = nfserr_notsupp;
11471157 break;
11481158 default:
1149− err = nfserrno(err2);
1150− nfsd_reset_boot_verifier(net_generic(nf->nf_net,
1151− nfsd_net_id));
1159+ nfsd_reset_write_verifier(nn);
1160+ trace_nfsd_writeverf_reset(nn, rqstp, err2);
11521161 }
1153− up_write(&nf->nf_rwsem);
1162+ err = nfserrno(err2);
11541163 } else
1155− nfsd_copy_boot_verifier(verf, net_generic(nf->nf_net,
1156− nfsd_net_id));
1164+ nfsd_copy_write_verifier(verf, nn);
11571165
11581166 nfsd_file_put(nf);
11591167 out:
@@ -1747,8 +1755,8 @@ retry: · 587 unmodified lines
17471755 * so do it by hand */
17481756 trap = lock_rename(tdentry, fdentry);
17491757 ffhp->fh_locked = tfhp->fh_locked = true;
1750− fill_pre_wcc(ffhp);
1751− fill_pre_wcc(tfhp);
1758+ fh_fill_pre_attrs(ffhp);
1759+ fh_fill_pre_attrs(tfhp);
17521760
17531761 odentry = lookup_one_len(fname, fdentry, flen);
17541762 host_err = PTR_ERR(odentry);
@@ -1808,8 +1816,8 @@ retry: · 53 unmodified lines
18081816 * were the same, so again we do it by hand.
18091817 */
18101818 if (!close_cached) {
1811− fill_post_wcc(ffhp);
1812− fill_post_wcc(tfhp);
1819+ fh_fill_post_attrs(ffhp);
1820+ fh_fill_post_attrs(tfhp);
18131821 }
18141822 unlock_rename(tdentry, fdentry);
18151823 ffhp->fh_locked = tfhp->fh_locked = false;
fs/nfsd/vfs.h+2−1
@@ -57,7 +57,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *, · 56 unmodified lines
5757 struct xdr_netobj *);
5858 __be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *,
5959 struct file *, loff_t, loff_t, int);
60−__be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
60+__be32 nfsd4_clone_file_range(struct svc_rqst *rqstp,
61+ struct nfsd_file *nf_src, u64 src_pos,
6162 struct nfsd_file *nf_dst, u64 dst_pos,
6263 u64 count, bool sync);
6364 #endif /* CONFIG_NFSD_V4 */
include/linux/exportfs.h+0−2
@@ -221,8 +221,6 @@ struct export_operations { · 220 unmodified lines
221221 #define EXPORT_OP_NOATOMIC_ATTR (0x10) /* Filesystem cannot supply
222222 atomic attribute updates
223223 */
224−#define EXPORT_OP_SYNC_LOCKS (0x20) /* Filesystem can't do
225− asychronous blocking locks */
226224 unsigned long flags;
227225 };
228226
include/linux/fs.h+2−2
@@ -1221,13 +1221,13 @@ static inline int fcntl_setlk(unsigned int fd, struct file *file, · 1220 unmodified lines
12211221
12221222 #if BITS_PER_LONG == 32
12231223 static inline int fcntl_getlk64(struct file *file, unsigned int cmd,
1224− struct flock64 __user *user)
1224+ struct flock64 *user)
12251225 {
12261226 return -EINVAL;
12271227 }
12281228
12291229 static inline int fcntl_setlk64(unsigned int fd, struct file *file,
1230− unsigned int cmd, struct flock64 __user *user)
1230+ unsigned int cmd, struct flock64 *user)
12311231 {
12321232 return -EACCES;
12331233 }
include/linux/lockd/lockd.h+7−2
@@ -303,10 +303,15 @@ void nlmsvc_invalidate_all(void); · 302 unmodified lines
303303 int nlmsvc_unlock_all_by_sb(struct super_block *sb);
304304 int nlmsvc_unlock_all_by_ip(struct sockaddr *server_addr);
305305
306+static inline struct file *nlmsvc_file_file(struct nlm_file *file)
307+{
308+ return file->f_file[O_RDONLY] ?
309+ file->f_file[O_RDONLY] : file->f_file[O_WRONLY];
310+}
311+
306312 static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
307313 {
308− return locks_inode(file->f_file[O_RDONLY] ?
309− file->f_file[O_RDONLY] : file->f_file[O_WRONLY]);
314+ return locks_inode(nlmsvc_file_file(file));
310315 }
311316
312317 static inline int __nlm_privileged_request4(const struct sockaddr *sap)
include/linux/sunrpc/svc.h+39−40
@@ -64,10 +64,9 @@ struct svc_serv_ops { · 63 unmodified lines
6464 /* queue up a transport for servicing */
6565 void (*svo_enqueue_xprt)(struct svc_xprt *);
6666
67− /* set up thread (or whatever) execution context */
68− int (*svo_setup)(struct svc_serv *, struct svc_pool *, int);
69−
70− /* optional module to count when adding threads (pooled svcs only) */
67+ /* optional module to count when adding threads.
68+ * Thread function must call module_put_and_exit() to exit.
69+ */
7170 struct module *svo_module;
7271 };
7372
@@ -85,6 +84,7 @@ struct svc_serv { · 11 unmodified lines
8584 struct svc_program * sv_program; /* RPC program */
8685 struct svc_stat * sv_stats; /* RPC statistics */
8786 spinlock_t sv_lock;
87+ struct kref sv_refcnt;
8888 unsigned int sv_nrthreads; /* # of server threads */
8989 unsigned int sv_maxconn; /* max connections allowed or
9090 * '0' causing max to be based
@@ -114,15 +114,43 @@ struct svc_serv { · 23 unmodified lines
114114 #endif /* CONFIG_SUNRPC_BACKCHANNEL */
115115 };
116116
117−/*
118− * We use sv_nrthreads as a reference count. svc_destroy() drops
119− * this refcount, so we need to bump it up around operations that
120− * change the number of threads. Horrible, but there it is.
121− * Should be called with the "service mutex" held.
117+/**
118+ * svc_get() - increment reference count on a SUNRPC serv
119+ * @serv: the svc_serv to have count incremented
120+ *
121+ * Returns: the svc_serv that was passed in.
122+ */
123+static inline struct svc_serv *svc_get(struct svc_serv *serv)
124+{
125+ kref_get(&serv->sv_refcnt);
126+ return serv;
127+}
128+
129+void svc_destroy(struct kref *);
130+
131+/**
132+ * svc_put - decrement reference count on a SUNRPC serv
133+ * @serv: the svc_serv to have count decremented
134+ *
135+ * When the reference count reaches zero, svc_destroy()
136+ * is called to clean up and free the serv.
137+ */
138+static inline void svc_put(struct svc_serv *serv)
139+{
140+ kref_put(&serv->sv_refcnt, svc_destroy);
141+}
142+
143+/**
144+ * svc_put_not_last - decrement non-final reference count on SUNRPC serv
145+ * @serv: the svc_serv to have count decremented
146+ *
147+ * Returns: %true is refcount was decremented.
148+ *
149+ * If the refcount is 1, it is not decremented and instead failure is reported.
122150 */
123−static inline void svc_get(struct svc_serv *serv)
151+static inline bool svc_put_not_last(struct svc_serv *serv)
124152 {
125− serv->sv_nrthreads++;
153+ return refcount_dec_not_one(&serv->sv_refcnt.refcount);
126154 }
127155
128156 /*
@@ -468,29 +496,6 @@ struct svc_procedure { · 339 unmodified lines
468496 const char * pc_name; /* for display */
469497 };
470498
471−/*
472− * Mode for mapping cpus to pools.
473− */
474−enum {
475− SVC_POOL_AUTO = -1, /* choose one of the others */
476− SVC_POOL_GLOBAL, /* no mapping, just a single global pool
477− * (legacy & UP mode) */
478− SVC_POOL_PERCPU, /* one pool per cpu */
479− SVC_POOL_PERNODE /* one pool per numa node */
480−};
481−
482−struct svc_pool_map {
483− int count; /* How many svc_servs use us */
484− int mode; /* Note: int not enum to avoid
485− * warnings about "enumeration value
486− * not handled in switch" */
487− unsigned int npools;
488− unsigned int *pool_to; /* maps pool id to cpu or node */
489− unsigned int *to_pool; /* maps cpu or node to pool id */
490−};
491−
492−extern struct svc_pool_map svc_pool_map;
493−
494499 /*
495500 * Function prototypes.
496501 */
@@ -501,20 +506,14 @@ struct svc_serv *svc_create(struct svc_program *, unsigned int, · 4 unmodified lines
501506 const struct svc_serv_ops *);
502507 struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv,
503508 struct svc_pool *pool, int node);
504−struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
505− struct svc_pool *pool, int node);
506509 void svc_rqst_replace_page(struct svc_rqst *rqstp,
507510 struct page *page);
508511 void svc_rqst_free(struct svc_rqst *);
509512 void svc_exit_thread(struct svc_rqst *);
510−unsigned int svc_pool_map_get(void);
511−void svc_pool_map_put(void);
512513 struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
513514 const struct svc_serv_ops *);
514515 int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
515−int svc_set_num_threads_sync(struct svc_serv *, struct svc_pool *, int);
516516 int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
517−void svc_destroy(struct svc_serv *);
518517 void svc_shutdown_net(struct svc_serv *, struct net *);
519518 int svc_process(struct svc_rqst *);
520519 int bc_svc_process(struct svc_serv *, struct rpc_rqst *,
include/trace/events/sunrpc.h+8−29
@@ -1744,10 +1744,11 @@ TRACE_EVENT(svc_xprt_create_err, · 1743 unmodified lines
17441744 const char *program,
17451745 const char *protocol,
17461746 struct sockaddr *sap,
1747+ size_t salen,
17471748 const struct svc_xprt *xprt
17481749 ),
17491750
1750− TP_ARGS(program, protocol, sap, xprt),
1751+ TP_ARGS(program, protocol, sap, salen, xprt),
17511752
17521753 TP_STRUCT__entry(
17531754 __field(long, error)
@@ -1760,7 +1761,7 @@ TRACE_EVENT(svc_xprt_create_err, · 6 unmodified lines
17601761 __entry->error = PTR_ERR(xprt);
17611762 __assign_str(program, program);
17621763 __assign_str(protocol, protocol);
1763− memcpy(__entry->addr, sap, sizeof(__entry->addr));
1764+ memcpy(__entry->addr, sap, min(salen, sizeof(__entry->addr)));
17641765 ),
17651766
17661767 TP_printk("addr=%pISpc program=%s protocol=%s error=%ld",
@@ -1768,7 +1769,7 @@ TRACE_EVENT(svc_xprt_create_err, · 1 unmodified line
17681769 __entry->error)
17691770 );
17701771
1771−TRACE_EVENT(svc_xprt_do_enqueue,
1772+TRACE_EVENT(svc_xprt_enqueue,
17721773 TP_PROTO(struct svc_xprt *xprt, struct svc_rqst *rqst),
17731774
17741775 TP_ARGS(xprt, rqst),
@@ -1815,7 +1816,6 @@ DECLARE_EVENT_CLASS(svc_xprt_event, · 40 unmodified lines
18151816 ), \
18161817 TP_ARGS(xprt))
18171818
1818−DEFINE_SVC_XPRT_EVENT(received);
18191819 DEFINE_SVC_XPRT_EVENT(no_write_space);
18201820 DEFINE_SVC_XPRT_EVENT(close);
18211821 DEFINE_SVC_XPRT_EVENT(detach);
@@ -1902,27 +1902,6 @@ TRACE_EVENT(svc_alloc_arg_err, · 80 unmodified lines
19021902 TP_printk("pages=%u", __entry->pages)
19031903 );
19041904
1905−TRACE_EVENT(svc_handle_xprt,
1906− TP_PROTO(struct svc_xprt *xprt, int len),
1907−
1908− TP_ARGS(xprt, len),
1909−
1910− TP_STRUCT__entry(
1911− __field(int, len)
1912− __field(unsigned long, flags)
1913− __string(addr, xprt->xpt_remotebuf)
1914− ),
1915−
1916− TP_fast_assign(
1917− __entry->len = len;
1918− __entry->flags = xprt->xpt_flags;
1919− __assign_str(addr, xprt->xpt_remotebuf);
1920− ),
1921−
1922− TP_printk("addr=%s len=%d flags=%s", __get_str(addr),
1923− __entry->len, show_svc_xprt_flags(__entry->flags))
1924−);
1925−
19261905 TRACE_EVENT(svc_stats_latency,
19271906 TP_PROTO(const struct svc_rqst *rqst),
19281907
@@ -2146,17 +2125,17 @@ DECLARE_EVENT_CLASS(svcsock_accept_class, · 217 unmodified lines
21462125 TP_STRUCT__entry(
21472126 __field(long, status)
21482127 __string(service, service)
2149− __array(unsigned char, addr, sizeof(struct sockaddr_in6))
2128+ __field(unsigned int, netns_ino)
21502129 ),
21512130
21522131 TP_fast_assign(
21532132 __entry->status = status;
21542133 __assign_str(service, service);
2155− memcpy(__entry->addr, &xprt->xpt_local, sizeof(__entry->addr));
2134+ __entry->netns_ino = xprt->xpt_net->ns.inum;
21562135 ),
21572136
2158− TP_printk("listener=%pISpc service=%s status=%ld",
2159− __entry->addr, __get_str(service), __entry->status
2137+ TP_printk("addr=listener service=%s status=%ld",
2138+ __get_str(service), __entry->status
21602139 )
21612140 );
21622141
net/sunrpc/svc.c+74−101
@@ -37,18 +37,37 @@ · 36 unmodified lines
3737
3838 static void svc_unregister(const struct svc_serv *serv, struct net *net);
3939
40−#define svc_serv_is_pooled(serv) ((serv)->sv_ops->svo_function)
41−
4240 #define SVC_POOL_DEFAULT SVC_POOL_GLOBAL
4341
42+/*
43+ * Mode for mapping cpus to pools.
44+ */
45+enum {
46+ SVC_POOL_AUTO = -1, /* choose one of the others */
47+ SVC_POOL_GLOBAL, /* no mapping, just a single global pool
48+ * (legacy & UP mode) */
49+ SVC_POOL_PERCPU, /* one pool per cpu */
50+ SVC_POOL_PERNODE /* one pool per numa node */
51+};
52+
4453 /*
4554 * Structure for mapping cpus to pools and vice versa.
4655 * Setup once during sunrpc initialisation.
4756 */
48−struct svc_pool_map svc_pool_map = {
57+
58+struct svc_pool_map {
59+ int count; /* How many svc_servs use us */
60+ int mode; /* Note: int not enum to avoid
61+ * warnings about "enumeration value
62+ * not handled in switch" */
63+ unsigned int npools;
64+ unsigned int *pool_to; /* maps pool id to cpu or node */
65+ unsigned int *to_pool; /* maps cpu or node to pool id */
66+};
67+
68+static struct svc_pool_map svc_pool_map = {
4969 .mode = SVC_POOL_DEFAULT
5070 };
51−EXPORT_SYMBOL_GPL(svc_pool_map);
5271
5372 static DEFINE_MUTEX(svc_pool_map_mutex);/* protects svc_pool_map.count only */
5473
@@ -219,10 +238,12 @@ svc_pool_map_init_pernode(struct svc_pool_map *m) · 164 unmodified lines
219238
220239 /*
221240 * Add a reference to the global map of cpus to pools (and
222− * vice versa). Initialise the map if we're the first user.
223− * Returns the number of pools.
241+ * vice versa) if pools are in use.
242+ * Initialise the map if we're the first user.
243+ * Returns the number of pools. If this is '1', no reference
244+ * was taken.
224245 */
225−unsigned int
246+static unsigned int
226247 svc_pool_map_get(void)
227248 {
228249 struct svc_pool_map *m = &svc_pool_map;
@@ -232,6 +253,7 @@ svc_pool_map_get(void) · 3 unmodified lines
232253
233254 if (m->count++) {
234255 mutex_unlock(&svc_pool_map_mutex);
256+ WARN_ON_ONCE(m->npools <= 1);
235257 return m->npools;
236258 }
237259
@@ -247,30 +269,36 @@ svc_pool_map_get(void) · 9 unmodified lines
247269 break;
248270 }
249271
250− if (npools < 0) {
272+ if (npools <= 0) {
251273 /* default, or memory allocation failure */
252274 npools = 1;
253275 m->mode = SVC_POOL_GLOBAL;
254276 }
255277 m->npools = npools;
256278
279+ if (npools == 1)
280+ /* service is unpooled, so doesn't hold a reference */
281+ m->count--;
282+
257283 mutex_unlock(&svc_pool_map_mutex);
258− return m->npools;
284+ return npools;
259285 }
260−EXPORT_SYMBOL_GPL(svc_pool_map_get);
261286
262287 /*
263− * Drop a reference to the global map of cpus to pools.
288+ * Drop a reference to the global map of cpus to pools, if
289+ * pools were in use, i.e. if npools > 1.
264290 * When the last reference is dropped, the map data is
265291 * freed; this allows the sysadmin to change the pool
266292 * mode using the pool_mode module option without
267293 * rebooting or re-loading sunrpc.ko.
268294 */
269−void
270−svc_pool_map_put(void)
295+static void
296+svc_pool_map_put(int npools)
271297 {
272298 struct svc_pool_map *m = &svc_pool_map;
273299
300+ if (npools <= 1)
301+ return;
274302 mutex_lock(&svc_pool_map_mutex);
275303
276304 if (!--m->count) {
@@ -283,7 +311,6 @@ svc_pool_map_put(void) · 6 unmodified lines
283311
284312 mutex_unlock(&svc_pool_map_mutex);
285313 }
286−EXPORT_SYMBOL_GPL(svc_pool_map_put);
287314
288315 static int svc_pool_map_get_node(unsigned int pidx)
289316 {
@@ -340,21 +367,18 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu) · 50 unmodified lines
340367 struct svc_pool_map *m = &svc_pool_map;
341368 unsigned int pidx = 0;
342369
343− /*
344− * An uninitialised map happens in a pure client when
345− * lockd is brought up, so silently treat it the
346− * same as SVC_POOL_GLOBAL.
347− */
348− if (svc_serv_is_pooled(serv)) {
349− switch (m->mode) {
350− case SVC_POOL_PERCPU:
351− pidx = m->to_pool[cpu];
352− break;
353− case SVC_POOL_PERNODE:
354− pidx = m->to_pool[cpu_to_node(cpu)];
355− break;
356− }
370+ if (serv->sv_nrpools <= 1)
371+ return serv->sv_pools;
372+
373+ switch (m->mode) {
374+ case SVC_POOL_PERCPU:
375+ pidx = m->to_pool[cpu];
376+ break;
377+ case SVC_POOL_PERNODE:
378+ pidx = m->to_pool[cpu_to_node(cpu)];
379+ break;
357380 }
381+
358382 return &serv->sv_pools[pidx % serv->sv_nrpools];
359383 }
360384
@@ -435,7 +459,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, · 74 unmodified lines
435459 return NULL;
436460 serv->sv_name = prog->pg_name;
437461 serv->sv_program = prog;
438− serv->sv_nrthreads = 1;
462+ kref_init(&serv->sv_refcnt);
439463 serv->sv_stats = prog->pg_stats;
440464 if (bufsize > RPCSVC_MAXPAYLOAD)
441465 bufsize = RPCSVC_MAXPAYLOAD;
@@ -507,7 +531,7 @@ svc_create_pooled(struct svc_program *prog, unsigned int bufsize, · 65 unmodified lines
507531 goto out_err;
508532 return serv;
509533 out_err:
510− svc_pool_map_put();
534+ svc_pool_map_put(npools);
511535 return NULL;
512536 }
513537 EXPORT_SYMBOL_GPL(svc_create_pooled);
@@ -523,23 +547,14 @@ EXPORT_SYMBOL_GPL(svc_shutdown_net); · 9 unmodified lines
523547
524548 /*
525549 * Destroy an RPC service. Should be called with appropriate locking to
526− * protect the sv_nrthreads, sv_permsocks and sv_tempsocks.
550+ * protect sv_permsocks and sv_tempsocks.
527551 */
528552 void
529−svc_destroy(struct svc_serv *serv)
553+svc_destroy(struct kref *ref)
530554 {
531− dprintk("svc: svc_destroy(%s, %d)\n",
532− serv->sv_program->pg_name,
533− serv->sv_nrthreads);
534−
535− if (serv->sv_nrthreads) {
536− if (--(serv->sv_nrthreads) != 0) {
537− svc_sock_update_bufs(serv);
538− return;
539− }
540− } else
541− printk("svc_destroy: no threads for serv=%p!\n", serv);
555+ struct svc_serv *serv = container_of(ref, struct svc_serv, sv_refcnt);
542556
557+ dprintk("svc: svc_destroy(%s)\n", serv->sv_program->pg_name);
543558 del_timer_sync(&serv->sv_temptimer);
544559
545560 /*
@@ -551,8 +566,7 @@ svc_destroy(struct svc_serv *serv) · 5 unmodified lines
551566
552567 cache_clean_deferred(serv);
553568
554− if (svc_serv_is_pooled(serv))
555− svc_pool_map_put();
569+ svc_pool_map_put(serv->sv_nrpools);
556570
557571 kfree(serv->sv_pools);
558572 kfree(serv);
@@ -638,7 +652,7 @@ out_enomem: · 79 unmodified lines
638652 }
639653 EXPORT_SYMBOL_GPL(svc_rqst_alloc);
640654
641−struct svc_rqst *
655+static struct svc_rqst *
642656 svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node)
643657 {
644658 struct svc_rqst *rqstp;
@@ -647,14 +661,17 @@ svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node) · 2 unmodified lines
647661 if (!rqstp)
648662 return ERR_PTR(-ENOMEM);
649663
650− serv->sv_nrthreads++;
664+ svc_get(serv);
665+ spin_lock_bh(&serv->sv_lock);
666+ serv->sv_nrthreads += 1;
667+ spin_unlock_bh(&serv->sv_lock);
668+
651669 spin_lock_bh(&pool->sp_lock);
652670 pool->sp_nrthreads++;
653671 list_add_rcu(&rqstp->rq_all, &pool->sp_all_threads);
654672 spin_unlock_bh(&pool->sp_lock);
655673 return rqstp;
656674 }
657−EXPORT_SYMBOL_GPL(svc_prepare_thread);
658675
659676 /*
660677 * Choose a pool in which to create a new thread, for svc_set_num_threads
@@ -748,59 +765,13 @@ svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) · 87 unmodified lines
748765 return 0;
749766 }
750767
751−
752−/* destroy old threads */
753−static int
754−svc_signal_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
755−{
756− struct task_struct *task;
757− unsigned int state = serv->sv_nrthreads-1;
758−
759− /* destroy old threads */
760− do {
761− task = choose_victim(serv, pool, &state);
762− if (task == NULL)
763− break;
764− send_sig(SIGINT, task, 1);
765− nrservs++;
766− } while (nrservs < 0);
767−
768− return 0;
769−}
770−
771768 /*
772769 * Create or destroy enough new threads to make the number
773770 * of threads the given number. If `pool' is non-NULL, applies
774771 * only to threads in that pool, otherwise round-robins between
775772 * all pools. Caller must ensure that mutual exclusion between this and
776773 * server startup or shutdown.
777− *
778− * Destroying threads relies on the service threads filling in
779− * rqstp->rq_task, which only the nfs ones do. Assumes the serv
780− * has been created using svc_create_pooled().
781− *
782− * Based on code that used to be in nfsd_svc() but tweaked
783− * to be pool-aware.
784774 */
785−int
786−svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
787−{
788− if (pool == NULL) {
789− /* The -1 assumes caller has done a svc_get() */
790− nrservs -= (serv->sv_nrthreads-1);
791− } else {
792− spin_lock_bh(&pool->sp_lock);
793− nrservs -= pool->sp_nrthreads;
794− spin_unlock_bh(&pool->sp_lock);
795− }
796−
797− if (nrservs > 0)
798− return svc_start_kthreads(serv, pool, nrservs);
799− if (nrservs < 0)
800− return svc_signal_kthreads(serv, pool, nrservs);
801− return 0;
802−}
803−EXPORT_SYMBOL_GPL(svc_set_num_threads);
804775
805776 /* destroy old threads */
806777 static int
@@ -821,11 +792,10 @@ svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) · 14 unmodified lines
821792 }
822793
823794 int
824−svc_set_num_threads_sync(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
795+svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
825796 {
826797 if (pool == NULL) {
827− /* The -1 assumes caller has done a svc_get() */
828− nrservs -= (serv->sv_nrthreads-1);
798+ nrservs -= serv->sv_nrthreads;
829799 } else {
830800 spin_lock_bh(&pool->sp_lock);
831801 nrservs -= pool->sp_nrthreads;
@@ -838,7 +808,7 @@ svc_set_num_threads_sync(struct svc_serv *serv, struct svc_pool *pool, int nrser · 6 unmodified lines
838808 return svc_stop_kthreads(serv, pool, nrservs);
839809 return 0;
840810 }
841−EXPORT_SYMBOL_GPL(svc_set_num_threads_sync);
811+EXPORT_SYMBOL_GPL(svc_set_num_threads);
842812
843813 /**
844814 * svc_rqst_replace_page - Replace one page in rq_pages[]
@@ -890,11 +860,14 @@ svc_exit_thread(struct svc_rqst *rqstp) · 45 unmodified lines
890860 list_del_rcu(&rqstp->rq_all);
891861 spin_unlock_bh(&pool->sp_lock);
892862
863+ spin_lock_bh(&serv->sv_lock);
864+ serv->sv_nrthreads -= 1;
865+ spin_unlock_bh(&serv->sv_lock);
866+ svc_sock_update_bufs(serv);
867+
893868 svc_rqst_free(rqstp);
894869
895− /* Release the server */
896− if (serv)
897− svc_destroy(serv);
870+ svc_put(serv);
898871 }
899872 EXPORT_SYMBOL_GPL(svc_exit_thread);
900873
net/sunrpc/svc_xprt.c+3−5
@@ -244,7 +244,7 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, · 243 unmodified lines
244244 xprt = xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
245245 if (IS_ERR(xprt))
246246 trace_svc_xprt_create_err(serv->sv_program->pg_name,
247− xcl->xcl_name, sap, xprt);
247+ xcl->xcl_name, sap, len, xprt);
248248 return xprt;
249249 }
250250
@@ -265,8 +265,6 @@ void svc_xprt_received(struct svc_xprt *xprt) · 14 unmodified lines
265265 return;
266266 }
267267
268− trace_svc_xprt_received(xprt);
269−
270268 /* As soon as we clear busy, the xprt could be closed and
271269 * 'put', so we need a reference to call svc_enqueue_xprt with:
272270 */
@@ -467,7 +465,7 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt) · 194 unmodified lines
467465 out_unlock:
468466 rcu_read_unlock();
469467 put_cpu();
470− trace_svc_xprt_do_enqueue(xprt, rqstp);
468+ trace_svc_xprt_enqueue(xprt, rqstp);
471469 }
472470 EXPORT_SYMBOL_GPL(svc_xprt_do_enqueue);
473471
@@ -843,8 +841,8 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt) · 369 unmodified lines
843841 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
844842 } else
845843 svc_xprt_received(xprt);
844+
846845 out:
847− trace_svc_handle_xprt(xprt, len);
848846 return len;
849847 }
850848