Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Stanislav Kinsbursky and committed by
J. Bruce Fields
786185b5 9793f7c8

+41 -19
+15 -12
fs/lockd/svc.c
··· 257 257 struct svc_serv *serv = nlmsvc_rqst->rq_server; 258 258 int error; 259 259 260 - if (ln->nlmsvc_users) 260 + if (ln->nlmsvc_users++) 261 261 return 0; 262 262 263 263 error = svc_rpcb_setup(serv, net); ··· 272 272 err_socks: 273 273 svc_rpcb_cleanup(serv, net); 274 274 err_rpcb: 275 + ln->nlmsvc_users--; 275 276 return error; 276 277 } 277 278 ··· 300 299 { 301 300 struct svc_serv *serv; 302 301 int error = 0; 302 + struct lockd_net *ln = net_generic(net, lockd_net_id); 303 303 304 304 mutex_lock(&nlmsvc_mutex); 305 305 /* ··· 332 330 goto destroy_and_out; 333 331 } 334 332 333 + ln->nlmsvc_users++; 334 + 335 335 error = make_socks(serv, net); 336 336 if (error < 0) 337 - goto destroy_and_out; 337 + goto err_start; 338 338 339 339 /* 340 340 * Create the kernel thread and wait for it to start. ··· 348 344 printk(KERN_WARNING 349 345 "lockd_up: svc_rqst allocation failed, error=%d\n", 350 346 error); 351 - goto destroy_and_out; 347 + goto err_start; 352 348 } 353 349 354 350 svc_sock_update_bufs(serv); ··· 362 358 nlmsvc_rqst = NULL; 363 359 printk(KERN_WARNING 364 360 "lockd_up: kthread_run failed, error=%d\n", error); 365 - goto destroy_and_out; 361 + goto err_start; 366 362 } 367 363 368 364 /* ··· 372 368 destroy_and_out: 373 369 svc_destroy(serv); 374 370 out: 375 - if (!error) { 376 - struct lockd_net *ln = net_generic(net, lockd_net_id); 377 - 378 - ln->nlmsvc_users++; 371 + if (!error) 379 372 nlmsvc_users++; 380 - } 381 373 mutex_unlock(&nlmsvc_mutex); 382 374 return error; 375 + 376 + err_start: 377 + lockd_down_net(net); 378 + goto destroy_and_out; 383 379 } 384 380 EXPORT_SYMBOL_GPL(lockd_up); 385 381 ··· 390 386 lockd_down(struct net *net) 391 387 { 392 388 mutex_lock(&nlmsvc_mutex); 389 + lockd_down_net(net); 393 390 if (nlmsvc_users) { 394 - if (--nlmsvc_users) { 395 - lockd_down_net(net); 391 + if (--nlmsvc_users) 396 392 goto out; 397 - } 398 393 } else { 399 394 printk(KERN_ERR "lockd_down: no users! task=%p\n", 400 395 nlmsvc_task);
+3
fs/nfs/callback.c
··· 314 314 dprintk("NFS: Couldn't create callback socket or server thread; " 315 315 "err = %d\n", ret); 316 316 cb_info->users--; 317 + if (serv) 318 + svc_shutdown_net(serv, net); 317 319 goto out; 318 320 } 319 321 ··· 330 328 cb_info->users--; 331 329 if (cb_info->users == 0 && cb_info->task != NULL) { 332 330 kthread_stop(cb_info->task); 331 + svc_shutdown_net(cb_info->serv, current->nsproxy->net_ns); 333 332 svc_exit_thread(cb_info->rqst); 334 333 cb_info->serv = NULL; 335 334 cb_info->rqst = NULL;
+9 -3
fs/nfsd/nfsctl.c
··· 661 661 { 662 662 char *mesg = buf; 663 663 int fd, err; 664 + struct net *net = &init_net; 664 665 665 666 err = get_int(&mesg, &fd); 666 667 if (err != 0 || fd < 0) ··· 673 672 674 673 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); 675 674 if (err < 0) { 675 + if (nfsd_serv->sv_nrthreads == 1) 676 + svc_shutdown_net(nfsd_serv, net); 676 677 svc_destroy(nfsd_serv); 677 678 return err; 678 679 } ··· 712 709 char transport[16]; 713 710 struct svc_xprt *xprt; 714 711 int port, err; 712 + struct net *net = &init_net; 715 713 716 714 if (sscanf(buf, "%15s %4u", transport, &port) != 2) 717 715 return -EINVAL; ··· 724 720 if (err != 0) 725 721 return err; 726 722 727 - err = svc_create_xprt(nfsd_serv, transport, &init_net, 723 + err = svc_create_xprt(nfsd_serv, transport, net, 728 724 PF_INET, port, SVC_SOCK_ANONYMOUS); 729 725 if (err < 0) 730 726 goto out_err; 731 727 732 - err = svc_create_xprt(nfsd_serv, transport, &init_net, 728 + err = svc_create_xprt(nfsd_serv, transport, net, 733 729 PF_INET6, port, SVC_SOCK_ANONYMOUS); 734 730 if (err < 0 && err != -EAFNOSUPPORT) 735 731 goto out_close; ··· 738 734 nfsd_serv->sv_nrthreads--; 739 735 return 0; 740 736 out_close: 741 - xprt = svc_find_xprt(nfsd_serv, transport, &init_net, PF_INET, port); 737 + xprt = svc_find_xprt(nfsd_serv, transport, net, PF_INET, port); 742 738 if (xprt != NULL) { 743 739 svc_close_xprt(xprt); 744 740 svc_xprt_put(xprt); 745 741 } 746 742 out_err: 743 + if (nfsd_serv->sv_nrthreads == 1) 744 + svc_shutdown_net(nfsd_serv, net); 747 745 svc_destroy(nfsd_serv); 748 746 return err; 749 747 }
+14
fs/nfsd/nfssvc.c
··· 382 382 int i = 0; 383 383 int tot = 0; 384 384 int err = 0; 385 + struct net *net = &init_net; 385 386 386 387 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 387 388 ··· 427 426 if (err) 428 427 break; 429 428 } 429 + 430 + if (nfsd_serv->sv_nrthreads == 1) 431 + svc_shutdown_net(nfsd_serv, net); 430 432 svc_destroy(nfsd_serv); 431 433 432 434 return err; ··· 445 441 { 446 442 int error; 447 443 bool nfsd_up_before; 444 + struct net *net = &init_net; 448 445 449 446 mutex_lock(&nfsd_mutex); 450 447 dprintk("nfsd: creating service\n"); ··· 478 473 if (error < 0 && !nfsd_up_before) 479 474 nfsd_shutdown(); 480 475 out_destroy: 476 + if (nfsd_serv->sv_nrthreads == 1) 477 + svc_shutdown_net(nfsd_serv, net); 481 478 svc_destroy(nfsd_serv); /* Release server */ 482 479 out: 483 480 mutex_unlock(&nfsd_mutex); ··· 563 556 nfsdstats.th_cnt --; 564 557 565 558 out: 559 + if (rqstp->rq_server->sv_nrthreads == 1) 560 + svc_shutdown_net(rqstp->rq_server, &init_net); 561 + 566 562 /* Release the thread */ 567 563 svc_exit_thread(rqstp); 568 564 ··· 678 668 int nfsd_pool_stats_release(struct inode *inode, struct file *file) 679 669 { 680 670 int ret = seq_release(inode, file); 671 + struct net *net = &init_net; 672 + 681 673 mutex_lock(&nfsd_mutex); 682 674 /* this function really, really should have been called svc_put() */ 675 + if (nfsd_serv->sv_nrthreads == 1) 676 + svc_shutdown_net(nfsd_serv, net); 683 677 svc_destroy(nfsd_serv); 684 678 mutex_unlock(&nfsd_mutex); 685 679 return ret;
-4
net/sunrpc/svc.c
··· 537 537 void 538 538 svc_destroy(struct svc_serv *serv) 539 539 { 540 - struct net *net = current->nsproxy->net_ns; 541 - 542 540 dprintk("svc: svc_destroy(%s, %d)\n", 543 541 serv->sv_program->pg_name, 544 542 serv->sv_nrthreads); ··· 550 552 printk("svc_destroy: no threads for serv=%p!\n", serv); 551 553 552 554 del_timer_sync(&serv->sv_temptimer); 553 - 554 - svc_shutdown_net(serv, net); 555 555 556 556 /* 557 557 * The last user is gone and thus all sockets have to be destroyed to