Skip to content

Commit 246afc0

Browse files
author
Trond Myklebust
committed
NFSv4: Handle NFS4ERR_OLD_STATEID in delegreturn
If the server returns NFS4ERR_OLD_STATEID in response to our delegreturn, we want to sync to the most recent seqid for the delegation stateid. However if we are already at the most recent, we have two possibilities: - an OPEN reply is still outstanding and will return a new seqid - an earlier OPEN reply was dropped on the floor due to a timeout. In the latter case, we may end up unable to complete the delegreturn, so we want to bump the seqid to a value greater than the cached value. While this may cause us to lose the delegation in the former case, it should now be safe to assume that the client will replay the OPEN if necessary in order to get a new valid stateid. Signed-off-by: Trond Myklebust <[email protected]>
1 parent ee05f45 commit 246afc0

File tree

2 files changed

+4
-4
lines changed

2 files changed

+4
-4
lines changed

fs/nfs/delegation.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,7 @@ bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
12521252
delegation = rcu_dereference(NFS_I(inode)->delegation);
12531253
if (delegation != NULL &&
12541254
nfs4_stateid_match_other(dst, &delegation->stateid) &&
1255+
nfs4_stateid_is_newer(&delegation->stateid, dst) &&
12551256
!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
12561257
dst->seqid = delegation->stateid.seqid;
12571258
ret = true;

fs/nfs/nfs4proc.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6196,10 +6196,9 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
61966196
task->tk_status = 0;
61976197
break;
61986198
case -NFS4ERR_OLD_STATEID:
6199-
if (nfs4_refresh_delegation_stateid(&data->stateid, data->inode))
6200-
goto out_restart;
6201-
task->tk_status = 0;
6202-
break;
6199+
if (!nfs4_refresh_delegation_stateid(&data->stateid, data->inode))
6200+
nfs4_stateid_seqid_inc(&data->stateid);
6201+
goto out_restart;
62036202
case -NFS4ERR_ACCESS:
62046203
if (data->args.bitmask) {
62056204
data->args.bitmask = NULL;

0 commit comments

Comments
 (0)