aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2012-07-11 16:29:56 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-07-16 14:48:10 -0400
commit89af2739589365bf0dd2023c6a076b22ccd530f9 (patch)
tree91608923b32aa16c7bf013bfb25d6006266c89a1
parent377e507d1572eca6372c862483f4ce4680ad310a (diff)
NFS: Don't free a state ID the server does not recognize
The result of a TEST_STATEID operation can indicate a few different things: o If NFS_OK is returned, then the client can continue using the state ID under test, and skip recovery. o RFC 5661 says that if the state ID was revoked, then the client must perform an explicit FREE_STATEID before trying to re-open. o If the server doesn't recognize the state ID at all, then no FREE_STATEID is needed, and the client can immediately continue with open recovery. Let's err on the side of caution: if the server clearly tells us the state ID is unknown, we skip the FREE_STATEID. For any other error, we issue a FREE_STATEID. Sometimes that FREE_STATEID will be unnecessary, but leaving unused state IDs on the server needlessly ties up resources. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index af3abf957f2c..afd61d72837d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1764,7 +1764,8 @@ static int nfs41_check_expired_stateid(struct nfs4_state *state, nfs4_stateid *s
1764 if (state->flags & flags) { 1764 if (state->flags & flags) {
1765 status = nfs41_test_stateid(server, stateid); 1765 status = nfs41_test_stateid(server, stateid);
1766 if (status != NFS_OK) { 1766 if (status != NFS_OK) {
1767 nfs41_free_stateid(server, stateid); 1767 if (status != -NFS4ERR_BAD_STATEID)
1768 nfs41_free_stateid(server, stateid);
1768 state->flags &= ~flags; 1769 state->flags &= ~flags;
1769 } 1770 }
1770 } 1771 }
@@ -4697,7 +4698,9 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
4697 if (lsp->ls_flags & NFS_LOCK_INITIALIZED) { 4698 if (lsp->ls_flags & NFS_LOCK_INITIALIZED) {
4698 status = nfs41_test_stateid(server, &lsp->ls_stateid); 4699 status = nfs41_test_stateid(server, &lsp->ls_stateid);
4699 if (status != NFS_OK) { 4700 if (status != NFS_OK) {
4700 nfs41_free_stateid(server, &lsp->ls_stateid); 4701 if (status != -NFS4ERR_BAD_STATEID)
4702 nfs41_free_stateid(server,
4703 &lsp->ls_stateid);
4701 lsp->ls_flags &= ~NFS_LOCK_INITIALIZED; 4704 lsp->ls_flags &= ~NFS_LOCK_INITIALIZED;
4702 ret = status; 4705 ret = status;
4703 } 4706 }