aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 5051ade30dfb..adc51d10d435 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -198,6 +198,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
198 atomic_set(&dp->dl_count, 1); 198 atomic_set(&dp->dl_count, 1);
199 list_add(&dp->dl_perfile, &fp->fi_delegations); 199 list_add(&dp->dl_perfile, &fp->fi_delegations);
200 list_add(&dp->dl_perclnt, &clp->cl_delegations); 200 list_add(&dp->dl_perclnt, &clp->cl_delegations);
201 INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc);
201 return dp; 202 return dp;
202} 203}
203 204
@@ -679,21 +680,6 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
679 return clp; 680 return clp;
680} 681}
681 682
682static void
683shutdown_callback_client(struct nfs4_client *clp)
684{
685 struct rpc_clnt *clnt = clp->cl_cb_conn.cb_client;
686
687 if (clnt) {
688 /*
689 * Callback threads take a reference on the client, so there
690 * should be no outstanding callbacks at this point.
691 */
692 clp->cl_cb_conn.cb_client = NULL;
693 rpc_shutdown_client(clnt);
694 }
695}
696
697static inline void 683static inline void
698free_client(struct nfs4_client *clp) 684free_client(struct nfs4_client *clp)
699{ 685{
@@ -746,7 +732,7 @@ expire_client(struct nfs4_client *clp)
746 se_perclnt); 732 se_perclnt);
747 release_session(ses); 733 release_session(ses);
748 } 734 }
749 shutdown_callback_client(clp); 735 nfsd4_set_callback_client(clp, NULL);
750 if (clp->cl_cb_xprt) 736 if (clp->cl_cb_xprt)
751 svc_xprt_put(clp->cl_cb_xprt); 737 svc_xprt_put(clp->cl_cb_xprt);
752 put_nfs4_client(clp); 738 put_nfs4_client(clp);
@@ -1392,7 +1378,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
1392 spin_unlock(&sessionid_lock); 1378 spin_unlock(&sessionid_lock);
1393 1379
1394 /* wait for callbacks */ 1380 /* wait for callbacks */
1395 shutdown_callback_client(ses->se_client); 1381 nfsd4_set_callback_client(ses->se_client, NULL);
1396 nfsd4_put_session(ses); 1382 nfsd4_put_session(ses);
1397 status = nfs_ok; 1383 status = nfs_ok;
1398out: 1384out:
@@ -4004,16 +3990,27 @@ set_max_delegations(void)
4004static int 3990static int
4005__nfs4_state_start(void) 3991__nfs4_state_start(void)
4006{ 3992{
3993 int ret;
3994
4007 boot_time = get_seconds(); 3995 boot_time = get_seconds();
4008 locks_start_grace(&nfsd4_manager); 3996 locks_start_grace(&nfsd4_manager);
4009 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 3997 printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
4010 nfsd4_grace); 3998 nfsd4_grace);
3999 ret = set_callback_cred();
4000 if (ret)
4001 return -ENOMEM;
4011 laundry_wq = create_singlethread_workqueue("nfsd4"); 4002 laundry_wq = create_singlethread_workqueue("nfsd4");
4012 if (laundry_wq == NULL) 4003 if (laundry_wq == NULL)
4013 return -ENOMEM; 4004 return -ENOMEM;
4005 ret = nfsd4_create_callback_queue();
4006 if (ret)
4007 goto out_free_laundry;
4014 queue_delayed_work(laundry_wq, &laundromat_work, nfsd4_grace * HZ); 4008 queue_delayed_work(laundry_wq, &laundromat_work, nfsd4_grace * HZ);
4015 set_max_delegations(); 4009 set_max_delegations();
4016 return set_callback_cred(); 4010 return 0;
4011out_free_laundry:
4012 destroy_workqueue(laundry_wq);
4013 return ret;
4017} 4014}
4018 4015
4019int 4016int
@@ -4075,6 +4072,7 @@ nfs4_state_shutdown(void)
4075 nfs4_lock_state(); 4072 nfs4_lock_state();
4076 nfs4_release_reclaim(); 4073 nfs4_release_reclaim();
4077 __nfs4_state_shutdown(); 4074 __nfs4_state_shutdown();
4075 nfsd4_destroy_callback_queue();
4078 nfs4_unlock_state(); 4076 nfs4_unlock_state();
4079} 4077}
4080 4078