aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-05-04 04:49:41 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-05-31 20:29:40 -0400
commit786185b5f8abefa6a8a16695bb4a59c164d5a071 (patch)
tree780eafd98f98a093fda540898595b47b4261764c
parent9793f7c88937e7ac07305ab1af1a519225836823 (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.c27
-rw-r--r--fs/nfs/callback.c3
-rw-r--r--fs/nfsd/nfsctl.c12
-rw-r--r--fs/nfsd/nfssvc.c14
-rw-r--r--net/sunrpc/svc.c4
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)
272err_socks: 272err_socks:
273 svc_rpcb_cleanup(serv, net); 273 svc_rpcb_cleanup(serv, net);
274err_rpcb: 274err_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)
368destroy_and_out: 372destroy_and_out:
369 svc_destroy(serv); 373 svc_destroy(serv);
370out: 374out:
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
380err_start:
381 lockd_down_net(net);
382 goto destroy_and_out;
379} 383}
380EXPORT_SYMBOL_GPL(lockd_up); 384EXPORT_SYMBOL_GPL(lockd_up);
381 385
@@ -386,11 +390,10 @@ void
386lockd_down(struct net *net) 390lockd_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;
736out_close: 740out_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 }
742out_err: 746out_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();
475out_destroy: 480out_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 */
477out: 484out:
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
558out: 565out:
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)
668int nfsd_pool_stats_release(struct inode *inode, struct file *file) 678int 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);
537void 537void
538svc_destroy(struct svc_serv *serv) 538svc_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.