diff options
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 43 |
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 | ||
405 | static void nfs4_free_stid(struct kmem_cache *slab, struct nfs4_stid *s) | ||
406 | { | ||
407 | kmem_cache_free(slab, s); | ||
408 | } | ||
409 | |||
405 | void | 410 | void |
406 | nfs4_put_delegation(struct nfs4_delegation *dp) | 411 | nfs4_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) | |||
610 | static void free_generic_stateid(struct nfs4_ol_stateid *stp) | 615 | static 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 | ||
616 | static void release_lock_stateid(struct nfs4_ol_stateid *stp) | 621 | static void release_lock_stateid(struct nfs4_ol_stateid *stp) |
@@ -668,7 +673,6 @@ static void unhash_open_stateid(struct nfs4_ol_stateid *stp) | |||
668 | static void release_open_stateid(struct nfs4_ol_stateid *stp) | 673 | static 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; |
3156 | out_free: | 3164 | out_free: |
3157 | unhash_stid(&dp->dl_stid); | 3165 | remove_stid(&dp->dl_stid); |
3158 | nfs4_put_delegation(dp); | 3166 | nfs4_put_delegation(dp); |
3159 | out_no_deleg: | 3167 | out_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 */ | ||
5126 | void | 5129 | void |
5127 | nfs4_state_shutdown_net(struct net *net) | 5130 | nfs4_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 | ||
5152 | void | 5157 | void |