.. | .. |
---|
426 | 426 | { |
---|
427 | 427 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
---|
428 | 428 | |
---|
429 | | - nfsd_file_cache_shutdown_net(net); |
---|
430 | 429 | nfs4_state_shutdown_net(net); |
---|
| 430 | + nfsd_file_cache_shutdown_net(net); |
---|
431 | 431 | if (nn->lockd_up) { |
---|
432 | 432 | lockd_down(net); |
---|
433 | 433 | nn->lockd_up = false; |
---|
.. | .. |
---|
600 | 600 | .svo_module = THIS_MODULE, |
---|
601 | 601 | }; |
---|
602 | 602 | |
---|
| 603 | +static void nfsd_complete_shutdown(struct net *net) |
---|
| 604 | +{ |
---|
| 605 | + struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
---|
| 606 | + |
---|
| 607 | + WARN_ON(!mutex_is_locked(&nfsd_mutex)); |
---|
| 608 | + |
---|
| 609 | + nn->nfsd_serv = NULL; |
---|
| 610 | + complete(&nn->nfsd_shutdown_complete); |
---|
| 611 | +} |
---|
| 612 | + |
---|
| 613 | +void nfsd_shutdown_threads(struct net *net) |
---|
| 614 | +{ |
---|
| 615 | + struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
---|
| 616 | + struct svc_serv *serv; |
---|
| 617 | + |
---|
| 618 | + mutex_lock(&nfsd_mutex); |
---|
| 619 | + serv = nn->nfsd_serv; |
---|
| 620 | + if (serv == NULL) { |
---|
| 621 | + mutex_unlock(&nfsd_mutex); |
---|
| 622 | + return; |
---|
| 623 | + } |
---|
| 624 | + |
---|
| 625 | + svc_get(serv); |
---|
| 626 | + /* Kill outstanding nfsd threads */ |
---|
| 627 | + serv->sv_ops->svo_setup(serv, NULL, 0); |
---|
| 628 | + nfsd_destroy(net); |
---|
| 629 | + mutex_unlock(&nfsd_mutex); |
---|
| 630 | + /* Wait for shutdown of nfsd_serv to complete */ |
---|
| 631 | + wait_for_completion(&nn->nfsd_shutdown_complete); |
---|
| 632 | +} |
---|
| 633 | + |
---|
603 | 634 | bool i_am_nfsd(void) |
---|
604 | 635 | { |
---|
605 | 636 | return kthread_func(current) == nfsd; |
---|
.. | .. |
---|
622 | 653 | &nfsd_thread_sv_ops); |
---|
623 | 654 | if (nn->nfsd_serv == NULL) |
---|
624 | 655 | return -ENOMEM; |
---|
| 656 | + init_completion(&nn->nfsd_shutdown_complete); |
---|
625 | 657 | |
---|
626 | 658 | nn->nfsd_serv->sv_maxconn = nn->max_connections; |
---|
627 | 659 | error = svc_bind(nn->nfsd_serv, net); |
---|
628 | 660 | if (error < 0) { |
---|
629 | 661 | svc_destroy(nn->nfsd_serv); |
---|
| 662 | + nfsd_complete_shutdown(net); |
---|
630 | 663 | return error; |
---|
631 | 664 | } |
---|
632 | 665 | |
---|
.. | .. |
---|
675 | 708 | svc_shutdown_net(nn->nfsd_serv, net); |
---|
676 | 709 | svc_destroy(nn->nfsd_serv); |
---|
677 | 710 | if (destroy) |
---|
678 | | - nn->nfsd_serv = NULL; |
---|
| 711 | + nfsd_complete_shutdown(net); |
---|
679 | 712 | } |
---|
680 | 713 | |
---|
681 | 714 | int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) |
---|