diff mbox

[02/15] NFS: Don't free a state ID the server does not recognize

Message ID 20120711202955.3767.78152.stgit@degas.1015granger.net (mailing list archive)
State New, archived
Headers show

Commit Message

Chuck Lever III July 11, 2012, 8:29 p.m. UTC
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>
---

 fs/nfs/nfs4proc.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9a0397c..2986e65 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
 	if (state->flags & flags) {
 		status = nfs41_test_stateid(server, stateid);
 		if (status != NFS_OK) {
-			nfs41_free_stateid(server, stateid);
+			if (status != -NFS4ERR_BAD_STATEID)
+				nfs41_free_stateid(server, stateid);
 			state->flags &= ~flags;
 		}
 	}
@@ -4708,7 +4709,9 @@  static int nfs41_check_expired_locks(struct nfs4_state *state)
 		if (lsp->ls_flags & NFS_LOCK_INITIALIZED) {
 			status = nfs41_test_stateid(server, &lsp->ls_stateid);
 			if (status != NFS_OK) {
-				nfs41_free_stateid(server, &lsp->ls_stateid);
+				if (status != -NFS4ERR_BAD_STATEID)
+					nfs41_free_stateid(server,
+							&lsp->ls_stateid);
 				lsp->ls_flags &= ~NFS_LOCK_INITIALIZED;
 				ret = status;
 			}