Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89af2739 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

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: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 377e507d
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -1764,6 +1764,7 @@ 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) {
			if (status != -NFS4ERR_BAD_STATEID)
				nfs41_free_stateid(server, stateid);
			state->flags &= ~flags;
		}
@@ -4697,7 +4698,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;
			}