Skip to content

Commit 4586f6e

Browse files
trondmypdamschuma-ntap
authored andcommitted
NFSv4.1: Add a helper function to deal with expired stateids
In NFSv4.1 and newer, if the server decides to revoke some or all of the protocol state, the client is required to iterate through all the stateids that it holds and call TEST_STATEID to determine which stateids still correspond to valid state, and then call FREE_STATEID on the others. Signed-off-by: Trond Myklebust <[email protected]> Tested-by: Oleg Drokin <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 43912bb commit 4586f6e

File tree

1 file changed

+24
-21
lines changed

1 file changed

+24
-21
lines changed

fs/nfs/nfs4proc.c

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2408,6 +2408,26 @@ static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
24082408
}
24092409

24102410
#if defined(CONFIG_NFS_V4_1)
2411+
static int nfs41_test_and_free_expired_stateid(struct nfs_server *server,
2412+
nfs4_stateid *stateid,
2413+
struct rpc_cred *cred)
2414+
{
2415+
int status;
2416+
2417+
status = nfs41_test_stateid(server, stateid, cred);
2418+
2419+
switch (status) {
2420+
case -NFS4ERR_EXPIRED:
2421+
case -NFS4ERR_ADMIN_REVOKED:
2422+
case -NFS4ERR_DELEG_REVOKED:
2423+
/* Ack the revoked state to the server */
2424+
nfs41_free_stateid(server, stateid, cred);
2425+
case -NFS4ERR_BAD_STATEID:
2426+
return status;
2427+
}
2428+
return NFS_OK;
2429+
}
2430+
24112431
static void nfs41_check_delegation_stateid(struct nfs4_state *state)
24122432
{
24132433
struct nfs_server *server = NFS_SERVER(state->inode);
@@ -2432,16 +2452,10 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
24322452
nfs4_stateid_copy(&stateid, &delegation->stateid);
24332453
cred = get_rpccred(delegation->cred);
24342454
rcu_read_unlock();
2435-
status = nfs41_test_stateid(server, &stateid, cred);
2455+
status = nfs41_test_and_free_expired_stateid(server, &stateid, cred);
24362456
trace_nfs4_test_delegation_stateid(state, NULL, status);
2437-
2438-
if (status != NFS_OK) {
2439-
/* Free the stateid unless the server explicitly
2440-
* informs us the stateid is unrecognized. */
2441-
if (status != -NFS4ERR_BAD_STATEID)
2442-
nfs41_free_stateid(server, &stateid, cred);
2457+
if (status != NFS_OK)
24432458
nfs_finish_clear_delegation_stateid(state);
2444-
}
24452459

24462460
put_rpccred(cred);
24472461
}
@@ -2467,14 +2481,9 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
24672481
(test_bit(NFS_O_RDWR_STATE, &state->flags) == 0))
24682482
return -NFS4ERR_BAD_STATEID;
24692483

2470-
status = nfs41_test_stateid(server, stateid, cred);
2484+
status = nfs41_test_and_free_expired_stateid(server, stateid, cred);
24712485
trace_nfs4_test_open_stateid(state, NULL, status);
24722486
if (status != NFS_OK) {
2473-
/* Free the stateid unless the server explicitly
2474-
* informs us the stateid is unrecognized. */
2475-
if (status != -NFS4ERR_BAD_STATEID)
2476-
nfs41_free_stateid(server, stateid, cred);
2477-
24782487
clear_bit(NFS_O_RDONLY_STATE, &state->flags);
24792488
clear_bit(NFS_O_WRONLY_STATE, &state->flags);
24802489
clear_bit(NFS_O_RDWR_STATE, &state->flags);
@@ -6090,17 +6099,11 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
60906099
if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
60916100
struct rpc_cred *cred = lsp->ls_state->owner->so_cred;
60926101

6093-
status = nfs41_test_stateid(server,
6102+
status = nfs41_test_and_free_expired_stateid(server,
60946103
&lsp->ls_stateid,
60956104
cred);
60966105
trace_nfs4_test_lock_stateid(state, lsp, status);
60976106
if (status != NFS_OK) {
6098-
/* Free the stateid unless the server
6099-
* informs us the stateid is unrecognized. */
6100-
if (status != -NFS4ERR_BAD_STATEID)
6101-
nfs41_free_stateid(server,
6102-
&lsp->ls_stateid,
6103-
cred);
61046107
clear_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags);
61056108
ret = status;
61066109
}

0 commit comments

Comments
 (0)