diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2012-05-04 04:49:41 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-05-31 20:29:40 -0400 |
commit | 786185b5f8abefa6a8a16695bb4a59c164d5a071 (patch) | |
tree | 780eafd98f98a093fda540898595b47b4261764c | |
parent | 9793f7c88937e7ac07305ab1af1a519225836823 (diff) |
SUNRPC: move per-net operations from svc_destroy()
The idea is to separate service destruction and per-net operations,
because these are two different things and the mix looks ugly.
Notes:
1) For NFS server this patch looks ugly (sorry for that). But these
place will be rewritten soon during NFSd containerization.
2) LockD per-net counter increase int lockd_up() was moved prior to
make_socks() to make lockd_down_net() call safe in case of error.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r-- | fs/lockd/svc.c | 27 | ||||
-rw-r--r-- | fs/nfs/callback.c | 3 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 12 | ||||
-rw-r--r-- | fs/nfsd/nfssvc.c | 14 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 4 |
5 files changed, 41 insertions, 19 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index b7e92ed56885..3250f280a171 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -257,7 +257,7 @@ static int lockd_up_net(struct net *net) | |||
257 | struct svc_serv *serv = nlmsvc_rqst->rq_server; | 257 | struct svc_serv *serv = nlmsvc_rqst->rq_server; |
258 | int error; | 258 | int error; |
259 | 259 | ||
260 | if (ln->nlmsvc_users) | 260 | if (ln->nlmsvc_users++) |
261 | return 0; | 261 | return 0; |
262 | 262 | ||
263 | error = svc_rpcb_setup(serv, net); | 263 | error = svc_rpcb_setup(serv, net); |
@@ -272,6 +272,7 @@ static int lockd_up_net(struct net *net) | |||
272 | err_socks: | 272 | err_socks: |
273 | svc_rpcb_cleanup(serv, net); | 273 | svc_rpcb_cleanup(serv, net); |
274 | err_rpcb: | 274 | err_rpcb: |
275 | ln->nlmsvc_users--; | ||
275 | return error; | 276 | return error; |
276 | } | 277 | } |
277 | 278 | ||
@@ -299,6 +300,7 @@ int lockd_up(struct net *net) | |||
299 | { | 300 | { |
300 | struct svc_serv *serv; | 301 | struct svc_serv *serv; |
301 | int error = 0; | 302 | int error = 0; |
303 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
302 | 304 | ||
303 | mutex_lock(&nlmsvc_mutex); | 305 | mutex_lock(&nlmsvc_mutex); |
304 | /* | 306 | /* |
@@ -330,9 +332,11 @@ int lockd_up(struct net *net) | |||
330 | goto destroy_and_out; | 332 | goto destroy_and_out; |
331 | } | 333 | } |
332 | 334 | ||
335 | ln->nlmsvc_users++; | ||
336 | |||
333 | error = make_socks(serv, net); | 337 | error = make_socks(serv, net); |
334 | if (error < 0) | 338 | if (error < 0) |
335 | goto destroy_and_out; | 339 | goto err_start; |
336 | 340 | ||
337 | /* | 341 | /* |
338 | * Create the kernel thread and wait for it to start. | 342 | * Create the kernel thread and wait for it to start. |
@@ -344,7 +348,7 @@ int lockd_up(struct net *net) | |||
344 | printk(KERN_WARNING | 348 | printk(KERN_WARNING |
345 | "lockd_up: svc_rqst allocation failed, error=%d\n", | 349 | "lockd_up: svc_rqst allocation failed, error=%d\n", |
346 | error); | 350 | error); |
347 | goto destroy_and_out; | 351 | goto err_start; |
348 | } | 352 | } |
349 | 353 | ||
350 | svc_sock_update_bufs(serv); | 354 | svc_sock_update_bufs(serv); |
@@ -358,7 +362,7 @@ int lockd_up(struct net *net) | |||
358 | nlmsvc_rqst = NULL; | 362 | nlmsvc_rqst = NULL; |
359 | printk(KERN_WARNING | 363 | printk(KERN_WARNING |
360 | "lockd_up: kthread_run failed, error=%d\n", error); | 364 | "lockd_up: kthread_run failed, error=%d\n", error); |
361 | goto destroy_and_out; | 365 | goto err_start; |
362 | } | 366 | } |
363 | 367 | ||
364 | /* | 368 | /* |
@@ -368,14 +372,14 @@ int lockd_up(struct net *net) | |||
368 | destroy_and_out: | 372 | destroy_and_out: |
369 | svc_destroy(serv); | 373 | svc_destroy(serv); |
370 | out: | 374 | out: |
371 | if (!error) { | 375 | if (!error) |
372 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
373 | |||
374 | ln->nlmsvc_users++; | ||
375 | nlmsvc_users++; | 376 | nlmsvc_users++; |
376 | } | ||
377 | mutex_unlock(&nlmsvc_mutex); | 377 | mutex_unlock(&nlmsvc_mutex); |
378 | return error; | 378 | return error; |
379 | |||
380 | err_start: | ||
381 | lockd_down_net(net); | ||
382 | goto destroy_and_out; | ||
379 | } | 383 | } |
380 | EXPORT_SYMBOL_GPL(lockd_up); | 384 | EXPORT_SYMBOL_GPL(lockd_up); |
381 | 385 | ||
@@ -386,11 +390,10 @@ void | |||
386 | lockd_down(struct net *net) | 390 | lockd_down(struct net *net) |
387 | { | 391 | { |
388 | mutex_lock(&nlmsvc_mutex); | 392 | mutex_lock(&nlmsvc_mutex); |
393 | lockd_down_net(net); | ||
389 | if (nlmsvc_users) { | 394 | if (nlmsvc_users) { |
390 | if (--nlmsvc_users) { | 395 | if (--nlmsvc_users) |
391 | lockd_down_net(net); | ||
392 | goto out; | 396 | goto out; |
393 | } | ||
394 | } else { | 397 | } else { |
395 | printk(KERN_ERR "lockd_down: no users! task=%p\n", | 398 | printk(KERN_ERR "lockd_down: no users! task=%p\n", |
396 | nlmsvc_task); | 399 | nlmsvc_task); |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 26b38fb8102e..cff39406f965 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -314,6 +314,8 @@ out_err: | |||
314 | dprintk("NFS: Couldn't create callback socket or server thread; " | 314 | dprintk("NFS: Couldn't create callback socket or server thread; " |
315 | "err = %d\n", ret); | 315 | "err = %d\n", ret); |
316 | cb_info->users--; | 316 | cb_info->users--; |
317 | if (serv) | ||
318 | svc_shutdown_net(serv, net); | ||
317 | goto out; | 319 | goto out; |
318 | } | 320 | } |
319 | 321 | ||
@@ -328,6 +330,7 @@ void nfs_callback_down(int minorversion) | |||
328 | cb_info->users--; | 330 | cb_info->users--; |
329 | if (cb_info->users == 0 && cb_info->task != NULL) { | 331 | if (cb_info->users == 0 && cb_info->task != NULL) { |
330 | kthread_stop(cb_info->task); | 332 | kthread_stop(cb_info->task); |
333 | svc_shutdown_net(cb_info->serv, current->nsproxy->net_ns); | ||
331 | svc_exit_thread(cb_info->rqst); | 334 | svc_exit_thread(cb_info->rqst); |
332 | cb_info->serv = NULL; | 335 | cb_info->serv = NULL; |
333 | cb_info->rqst = NULL; | 336 | cb_info->rqst = NULL; |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 72699885ac48..c55298ed5772 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -661,6 +661,7 @@ static ssize_t __write_ports_addfd(char *buf) | |||
661 | { | 661 | { |
662 | char *mesg = buf; | 662 | char *mesg = buf; |
663 | int fd, err; | 663 | int fd, err; |
664 | struct net *net = &init_net; | ||
664 | 665 | ||
665 | err = get_int(&mesg, &fd); | 666 | err = get_int(&mesg, &fd); |
666 | if (err != 0 || fd < 0) | 667 | if (err != 0 || fd < 0) |
@@ -672,6 +673,8 @@ static ssize_t __write_ports_addfd(char *buf) | |||
672 | 673 | ||
673 | err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); | 674 | err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); |
674 | if (err < 0) { | 675 | if (err < 0) { |
676 | if (nfsd_serv->sv_nrthreads == 1) | ||
677 | svc_shutdown_net(nfsd_serv, net); | ||
675 | svc_destroy(nfsd_serv); | 678 | svc_destroy(nfsd_serv); |
676 | return err; | 679 | return err; |
677 | } | 680 | } |
@@ -709,6 +712,7 @@ static ssize_t __write_ports_addxprt(char *buf) | |||
709 | char transport[16]; | 712 | char transport[16]; |
710 | struct svc_xprt *xprt; | 713 | struct svc_xprt *xprt; |
711 | int port, err; | 714 | int port, err; |
715 | struct net *net = &init_net; | ||
712 | 716 | ||
713 | if (sscanf(buf, "%15s %4u", transport, &port) != 2) | 717 | if (sscanf(buf, "%15s %4u", transport, &port) != 2) |
714 | return -EINVAL; | 718 | return -EINVAL; |
@@ -720,12 +724,12 @@ static ssize_t __write_ports_addxprt(char *buf) | |||
720 | if (err != 0) | 724 | if (err != 0) |
721 | return err; | 725 | return err; |
722 | 726 | ||
723 | err = svc_create_xprt(nfsd_serv, transport, &init_net, | 727 | err = svc_create_xprt(nfsd_serv, transport, net, |
724 | PF_INET, port, SVC_SOCK_ANONYMOUS); | 728 | PF_INET, port, SVC_SOCK_ANONYMOUS); |
725 | if (err < 0) | 729 | if (err < 0) |
726 | goto out_err; | 730 | goto out_err; |
727 | 731 | ||
728 | err = svc_create_xprt(nfsd_serv, transport, &init_net, | 732 | err = svc_create_xprt(nfsd_serv, transport, net, |
729 | PF_INET6, port, SVC_SOCK_ANONYMOUS); | 733 | PF_INET6, port, SVC_SOCK_ANONYMOUS); |
730 | if (err < 0 && err != -EAFNOSUPPORT) | 734 | if (err < 0 && err != -EAFNOSUPPORT) |
731 | goto out_close; | 735 | goto out_close; |
@@ -734,12 +738,14 @@ static ssize_t __write_ports_addxprt(char *buf) | |||
734 | nfsd_serv->sv_nrthreads--; | 738 | nfsd_serv->sv_nrthreads--; |
735 | return 0; | 739 | return 0; |
736 | out_close: | 740 | out_close: |
737 | xprt = svc_find_xprt(nfsd_serv, transport, &init_net, PF_INET, port); | 741 | xprt = svc_find_xprt(nfsd_serv, transport, net, PF_INET, port); |
738 | if (xprt != NULL) { | 742 | if (xprt != NULL) { |
739 | svc_close_xprt(xprt); | 743 | svc_close_xprt(xprt); |
740 | svc_xprt_put(xprt); | 744 | svc_xprt_put(xprt); |
741 | } | 745 | } |
742 | out_err: | 746 | out_err: |
747 | if (nfsd_serv->sv_nrthreads == 1) | ||
748 | svc_shutdown_net(nfsd_serv, net); | ||
743 | svc_destroy(nfsd_serv); | 749 | svc_destroy(nfsd_serv); |
744 | return err; | 750 | return err; |
745 | } | 751 | } |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 0762f3c9e0fb..ee709fc8f58b 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -382,6 +382,7 @@ int nfsd_set_nrthreads(int n, int *nthreads) | |||
382 | int i = 0; | 382 | int i = 0; |
383 | int tot = 0; | 383 | int tot = 0; |
384 | int err = 0; | 384 | int err = 0; |
385 | struct net *net = &init_net; | ||
385 | 386 | ||
386 | WARN_ON(!mutex_is_locked(&nfsd_mutex)); | 387 | WARN_ON(!mutex_is_locked(&nfsd_mutex)); |
387 | 388 | ||
@@ -426,6 +427,9 @@ int nfsd_set_nrthreads(int n, int *nthreads) | |||
426 | if (err) | 427 | if (err) |
427 | break; | 428 | break; |
428 | } | 429 | } |
430 | |||
431 | if (nfsd_serv->sv_nrthreads == 1) | ||
432 | svc_shutdown_net(nfsd_serv, net); | ||
429 | svc_destroy(nfsd_serv); | 433 | svc_destroy(nfsd_serv); |
430 | 434 | ||
431 | return err; | 435 | return err; |
@@ -441,6 +445,7 @@ nfsd_svc(unsigned short port, int nrservs) | |||
441 | { | 445 | { |
442 | int error; | 446 | int error; |
443 | bool nfsd_up_before; | 447 | bool nfsd_up_before; |
448 | struct net *net = &init_net; | ||
444 | 449 | ||
445 | mutex_lock(&nfsd_mutex); | 450 | mutex_lock(&nfsd_mutex); |
446 | dprintk("nfsd: creating service\n"); | 451 | dprintk("nfsd: creating service\n"); |
@@ -473,6 +478,8 @@ out_shutdown: | |||
473 | if (error < 0 && !nfsd_up_before) | 478 | if (error < 0 && !nfsd_up_before) |
474 | nfsd_shutdown(); | 479 | nfsd_shutdown(); |
475 | out_destroy: | 480 | out_destroy: |
481 | if (nfsd_serv->sv_nrthreads == 1) | ||
482 | svc_shutdown_net(nfsd_serv, net); | ||
476 | svc_destroy(nfsd_serv); /* Release server */ | 483 | svc_destroy(nfsd_serv); /* Release server */ |
477 | out: | 484 | out: |
478 | mutex_unlock(&nfsd_mutex); | 485 | mutex_unlock(&nfsd_mutex); |
@@ -556,6 +563,9 @@ nfsd(void *vrqstp) | |||
556 | nfsdstats.th_cnt --; | 563 | nfsdstats.th_cnt --; |
557 | 564 | ||
558 | out: | 565 | out: |
566 | if (rqstp->rq_server->sv_nrthreads == 1) | ||
567 | svc_shutdown_net(rqstp->rq_server, &init_net); | ||
568 | |||
559 | /* Release the thread */ | 569 | /* Release the thread */ |
560 | svc_exit_thread(rqstp); | 570 | svc_exit_thread(rqstp); |
561 | 571 | ||
@@ -668,8 +678,12 @@ int nfsd_pool_stats_open(struct inode *inode, struct file *file) | |||
668 | int nfsd_pool_stats_release(struct inode *inode, struct file *file) | 678 | int nfsd_pool_stats_release(struct inode *inode, struct file *file) |
669 | { | 679 | { |
670 | int ret = seq_release(inode, file); | 680 | int ret = seq_release(inode, file); |
681 | struct net *net = &init_net; | ||
682 | |||
671 | mutex_lock(&nfsd_mutex); | 683 | mutex_lock(&nfsd_mutex); |
672 | /* this function really, really should have been called svc_put() */ | 684 | /* this function really, really should have been called svc_put() */ |
685 | if (nfsd_serv->sv_nrthreads == 1) | ||
686 | svc_shutdown_net(nfsd_serv, net); | ||
673 | svc_destroy(nfsd_serv); | 687 | svc_destroy(nfsd_serv); |
674 | mutex_unlock(&nfsd_mutex); | 688 | mutex_unlock(&nfsd_mutex); |
675 | return ret; | 689 | return ret; |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index e6d542cee0f3..b7210f5cc893 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -537,8 +537,6 @@ EXPORT_SYMBOL_GPL(svc_shutdown_net); | |||
537 | void | 537 | void |
538 | svc_destroy(struct svc_serv *serv) | 538 | svc_destroy(struct svc_serv *serv) |
539 | { | 539 | { |
540 | struct net *net = current->nsproxy->net_ns; | ||
541 | |||
542 | dprintk("svc: svc_destroy(%s, %d)\n", | 540 | dprintk("svc: svc_destroy(%s, %d)\n", |
543 | serv->sv_program->pg_name, | 541 | serv->sv_program->pg_name, |
544 | serv->sv_nrthreads); | 542 | serv->sv_nrthreads); |
@@ -553,8 +551,6 @@ svc_destroy(struct svc_serv *serv) | |||
553 | 551 | ||
554 | del_timer_sync(&serv->sv_temptimer); | 552 | del_timer_sync(&serv->sv_temptimer); |
555 | 553 | ||
556 | svc_shutdown_net(serv, net); | ||
557 | |||
558 | /* | 554 | /* |
559 | * The last user is gone and thus all sockets have to be destroyed to | 555 | * The last user is gone and thus all sockets have to be destroyed to |
560 | * the point. Check this. | 556 | * the point. Check this. |