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.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 0874998a49cd..105d6fa7c514 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -402,11 +402,16 @@ static void remove_stid(struct nfs4_stid *s)
402 idr_remove(stateids, s->sc_stateid.si_opaque.so_id); 402 idr_remove(stateids, s->sc_stateid.si_opaque.so_id);
403} 403}
404 404
405static void nfs4_free_stid(struct kmem_cache *slab, struct nfs4_stid *s)
406{
407 kmem_cache_free(slab, s);
408}
409
405void 410void
406nfs4_put_delegation(struct nfs4_delegation *dp) 411nfs4_put_delegation(struct nfs4_delegation *dp)
407{ 412{
408 if (atomic_dec_and_test(&dp->dl_count)) { 413 if (atomic_dec_and_test(&dp->dl_count)) {
409 kmem_cache_free(deleg_slab, dp); 414 nfs4_free_stid(deleg_slab, &dp->dl_stid);
410 num_delegations--; 415 num_delegations--;
411 } 416 }
412} 417}
@@ -610,7 +615,7 @@ static void close_generic_stateid(struct nfs4_ol_stateid *stp)
610static void free_generic_stateid(struct nfs4_ol_stateid *stp) 615static void free_generic_stateid(struct nfs4_ol_stateid *stp)
611{ 616{
612 remove_stid(&stp->st_stid); 617 remove_stid(&stp->st_stid);
613 kmem_cache_free(stateid_slab, stp); 618 nfs4_free_stid(stateid_slab, &stp->st_stid);
614} 619}
615 620
616static void release_lock_stateid(struct nfs4_ol_stateid *stp) 621static void release_lock_stateid(struct nfs4_ol_stateid *stp)
@@ -668,7 +673,6 @@ static void unhash_open_stateid(struct nfs4_ol_stateid *stp)
668static void release_open_stateid(struct nfs4_ol_stateid *stp) 673static void release_open_stateid(struct nfs4_ol_stateid *stp)
669{ 674{
670 unhash_open_stateid(stp); 675 unhash_open_stateid(stp);
671 unhash_stid(&stp->st_stid);
672 free_generic_stateid(stp); 676 free_generic_stateid(stp);
673} 677}
674 678
@@ -690,7 +694,6 @@ static void release_last_closed_stateid(struct nfs4_openowner *oo)
690 struct nfs4_ol_stateid *s = oo->oo_last_closed_stid; 694 struct nfs4_ol_stateid *s = oo->oo_last_closed_stid;
691 695
692 if (s) { 696 if (s) {
693 unhash_stid(&s->st_stid);
694 free_generic_stateid(s); 697 free_generic_stateid(s);
695 oo->oo_last_closed_stid = NULL; 698 oo->oo_last_closed_stid = NULL;
696 } 699 }
@@ -1127,6 +1130,11 @@ destroy_client(struct nfs4_client *clp)
1127 dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); 1130 dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1128 destroy_delegation(dp); 1131 destroy_delegation(dp);
1129 } 1132 }
1133 list_splice_init(&clp->cl_revoked, &reaplist);
1134 while (!list_empty(&reaplist)) {
1135 dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1136 destroy_revoked_delegation(dp);
1137 }
1130 while (!list_empty(&clp->cl_openowners)) { 1138 while (!list_empty(&clp->cl_openowners)) {
1131 oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); 1139 oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
1132 release_openowner(oo); 1140 release_openowner(oo);
@@ -3008,7 +3016,7 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int f
3008 return NULL; 3016 return NULL;
3009 locks_init_lock(fl); 3017 locks_init_lock(fl);
3010 fl->fl_lmops = &nfsd_lease_mng_ops; 3018 fl->fl_lmops = &nfsd_lease_mng_ops;
3011 fl->fl_flags = FL_LEASE; 3019 fl->fl_flags = FL_DELEG;
3012 fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK; 3020 fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
3013 fl->fl_end = OFFSET_MAX; 3021 fl->fl_end = OFFSET_MAX;
3014 fl->fl_owner = (fl_owner_t)(dp->dl_file); 3022 fl->fl_owner = (fl_owner_t)(dp->dl_file);
@@ -3154,7 +3162,7 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
3154 open->op_delegate_type = NFS4_OPEN_DELEGATE_READ; 3162 open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
3155 return; 3163 return;
3156out_free: 3164out_free:
3157 unhash_stid(&dp->dl_stid); 3165 remove_stid(&dp->dl_stid);
3158 nfs4_put_delegation(dp); 3166 nfs4_put_delegation(dp);
3159out_no_deleg: 3167out_no_deleg:
3160 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE; 3168 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
@@ -3843,9 +3851,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3843 struct nfs4_ol_stateid *stp; 3851 struct nfs4_ol_stateid *stp;
3844 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 3852 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
3845 3853
3846 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", 3854 dprintk("NFSD: nfsd4_open_confirm on file %pd\n",
3847 (int)cstate->current_fh.fh_dentry->d_name.len, 3855 cstate->current_fh.fh_dentry);
3848 cstate->current_fh.fh_dentry->d_name.name);
3849 3856
3850 status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0); 3857 status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0);
3851 if (status) 3858 if (status)
@@ -3922,9 +3929,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3922 struct nfs4_ol_stateid *stp; 3929 struct nfs4_ol_stateid *stp;
3923 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 3930 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
3924 3931
3925 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 3932 dprintk("NFSD: nfsd4_open_downgrade on file %pd\n",
3926 (int)cstate->current_fh.fh_dentry->d_name.len, 3933 cstate->current_fh.fh_dentry);
3927 cstate->current_fh.fh_dentry->d_name.name);
3928 3934
3929 /* We don't yet support WANT bits: */ 3935 /* We don't yet support WANT bits: */
3930 if (od->od_deleg_want) 3936 if (od->od_deleg_want)
@@ -3980,9 +3986,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3980 struct net *net = SVC_NET(rqstp); 3986 struct net *net = SVC_NET(rqstp);
3981 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 3987 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
3982 3988
3983 dprintk("NFSD: nfsd4_close on file %.*s\n", 3989 dprintk("NFSD: nfsd4_close on file %pd\n",
3984 (int)cstate->current_fh.fh_dentry->d_name.len, 3990 cstate->current_fh.fh_dentry);
3985 cstate->current_fh.fh_dentry->d_name.name);
3986 3991
3987 nfs4_lock_state(); 3992 nfs4_lock_state();
3988 status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid, 3993 status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid,
@@ -3998,10 +4003,9 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3998 4003
3999 nfsd4_close_open_stateid(stp); 4004 nfsd4_close_open_stateid(stp);
4000 4005
4001 if (cstate->minorversion) { 4006 if (cstate->minorversion)
4002 unhash_stid(&stp->st_stid);
4003 free_generic_stateid(stp); 4007 free_generic_stateid(stp);
4004 } else 4008 else
4005 oo->oo_last_closed_stid = stp; 4009 oo->oo_last_closed_stid = stp;
4006 4010
4007 if (list_empty(&oo->oo_owner.so_stateids)) { 4011 if (list_empty(&oo->oo_owner.so_stateids)) {
@@ -5122,7 +5126,6 @@ out_recovery:
5122 return ret; 5126 return ret;
5123} 5127}
5124 5128
5125/* should be called with the state lock held */
5126void 5129void
5127nfs4_state_shutdown_net(struct net *net) 5130nfs4_state_shutdown_net(struct net *net)
5128{ 5131{
@@ -5133,6 +5136,7 @@ nfs4_state_shutdown_net(struct net *net)
5133 cancel_delayed_work_sync(&nn->laundromat_work); 5136 cancel_delayed_work_sync(&nn->laundromat_work);
5134 locks_end_grace(&nn->nfsd4_manager); 5137 locks_end_grace(&nn->nfsd4_manager);
5135 5138
5139 nfs4_lock_state();
5136 INIT_LIST_HEAD(&reaplist); 5140 INIT_LIST_HEAD(&reaplist);
5137 spin_lock(&recall_lock); 5141 spin_lock(&recall_lock);
5138 list_for_each_safe(pos, next, &nn->del_recall_lru) { 5142 list_for_each_safe(pos, next, &nn->del_recall_lru) {
@@ -5147,6 +5151,7 @@ nfs4_state_shutdown_net(struct net *net)
5147 5151
5148 nfsd4_client_tracking_exit(net); 5152 nfsd4_client_tracking_exit(net);
5149 nfs4_state_destroy_net(net); 5153 nfs4_state_destroy_net(net);
5154 nfs4_unlock_state();
5150} 5155}
5151 5156
5152void 5157void