diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-16 15:04:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-16 15:04:02 -0500 |
commit | 449bf8d03c5b94f00cc014ff601c2fe2eebb5a6e (patch) | |
tree | 8f17959c0a20d9ca3061d28036855813c775c783 /fs/nfsd/nfs4state.c | |
parent | ffd3c0260aeeb1fd4d36378d2e06e6410661dd0f (diff) | |
parent | aea240f4162d50e0f2d8bd5ea3ba11b5f072add8 (diff) |
Merge branch 'nfsd-next' of git://linux-nfs.org/~bfields/linux
Pull nfsd changes from Bruce Fields:
"This includes miscellaneous bugfixes and cleanup and a performance fix
for write-heavy NFSv4 workloads.
(The most significant nfsd-relevant change this time is actually in
the delegation patches that went through Viro, fixing a long-standing
bug that can cause NFSv4 clients to miss updates made by non-nfs users
of the filesystem. Those enable some followup nfsd patches which I
have queued locally, but those can wait till 3.14)"
* 'nfsd-next' of git://linux-nfs.org/~bfields/linux: (24 commits)
nfsd: export proper maximum file size to the client
nfsd4: improve write performance with better sendspace reservations
svcrpc: remove an unnecessary assignment
sunrpc: comment typo fix
Revert "nfsd: remove_stid can be incorporated into nfs4_put_delegation"
nfsd4: fix discarded security labels on setattr
NFSD: Add support for NFS v4.2 operation checking
nfsd4: nfsd_shutdown_net needs state lock
NFSD: Combine decode operations for v4 and v4.1
nfsd: -EINVAL on invalid anonuid/gid instead of silent failure
nfsd: return better errors to exportfs
nfsd: fh_update should error out in unexpected cases
nfsd4: need to destroy revoked delegations in destroy_client
nfsd: no need to unhash_stid before free
nfsd: remove_stid can be incorporated into nfs4_put_delegation
nfsd: nfs4_open_delegation needs to remove_stid rather than unhash_stid
nfsd: nfs4_free_stid
nfsd: fix Kconfig syntax
sunrpc: trim off EC bytes in GSSAPI v2 unwrap
gss_krb5: document that we ignore sequence number
...
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f36a30a9f2d1..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); |
@@ -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; |
@@ -3995,10 +4003,9 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3995 | 4003 | ||
3996 | nfsd4_close_open_stateid(stp); | 4004 | nfsd4_close_open_stateid(stp); |
3997 | 4005 | ||
3998 | if (cstate->minorversion) { | 4006 | if (cstate->minorversion) |
3999 | unhash_stid(&stp->st_stid); | ||
4000 | free_generic_stateid(stp); | 4007 | free_generic_stateid(stp); |
4001 | } else | 4008 | else |
4002 | oo->oo_last_closed_stid = stp; | 4009 | oo->oo_last_closed_stid = stp; |
4003 | 4010 | ||
4004 | if (list_empty(&oo->oo_owner.so_stateids)) { | 4011 | if (list_empty(&oo->oo_owner.so_stateids)) { |
@@ -5119,7 +5126,6 @@ out_recovery: | |||
5119 | return ret; | 5126 | return ret; |
5120 | } | 5127 | } |
5121 | 5128 | ||
5122 | /* should be called with the state lock held */ | ||
5123 | void | 5129 | void |
5124 | nfs4_state_shutdown_net(struct net *net) | 5130 | nfs4_state_shutdown_net(struct net *net) |
5125 | { | 5131 | { |
@@ -5130,6 +5136,7 @@ nfs4_state_shutdown_net(struct net *net) | |||
5130 | cancel_delayed_work_sync(&nn->laundromat_work); | 5136 | cancel_delayed_work_sync(&nn->laundromat_work); |
5131 | locks_end_grace(&nn->nfsd4_manager); | 5137 | locks_end_grace(&nn->nfsd4_manager); |
5132 | 5138 | ||
5139 | nfs4_lock_state(); | ||
5133 | INIT_LIST_HEAD(&reaplist); | 5140 | INIT_LIST_HEAD(&reaplist); |
5134 | spin_lock(&recall_lock); | 5141 | spin_lock(&recall_lock); |
5135 | list_for_each_safe(pos, next, &nn->del_recall_lru) { | 5142 | list_for_each_safe(pos, next, &nn->del_recall_lru) { |
@@ -5144,6 +5151,7 @@ nfs4_state_shutdown_net(struct net *net) | |||
5144 | 5151 | ||
5145 | nfsd4_client_tracking_exit(net); | 5152 | nfsd4_client_tracking_exit(net); |
5146 | nfs4_state_destroy_net(net); | 5153 | nfs4_state_destroy_net(net); |
5154 | nfs4_unlock_state(); | ||
5147 | } | 5155 | } |
5148 | 5156 | ||
5149 | void | 5157 | void |