Skip to content

Commit 175398a

Browse files
committed
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 ...
2 parents 49ad227 + 1672086 commit 175398a

33 files changed

+702
-749
lines changed

MAINTAINERS

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7417,7 +7417,6 @@ F: include/uapi/scsi/fc/
74177417

74187418
FILE LOCKING (flock() and fcntl()/lockf())
74197419
M: Jeff Layton <[email protected]>
7420-
M: "J. Bruce Fields" <[email protected]>
74217420
74227421
S: Maintained
74237422
F: fs/fcntl.c
@@ -10428,12 +10427,11 @@ S: Odd Fixes
1042810427
W: http://kernelnewbies.org/KernelJanitors
1042910428

1043010429
KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
10431-
M: "J. Bruce Fields" <[email protected]>
1043210430
M: Chuck Lever <[email protected]>
1043310431
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

Lines changed: 61 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,9 @@ EXPORT_SYMBOL_GPL(nlmsvc_ops);
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)
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)
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,
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,
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 = {
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,51 +383,63 @@ static struct svc_serv *lockd_create_svc(void)
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
/*
468424
* Bring up the lockd process if it's not already up.
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
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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,10 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
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,
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
}

0 commit comments

Comments
 (0)