From: Olga Kornievskaia okorniev@redhat.com
[ Upstream commit be390f95242785adbf37d7b8a5101dd2f2ba891b ]
RFC7530 states that clients should be prepared for the return of NFS4ERR_GRACE errors for non-reclaim lock and I/O requests.
Signed-off-by: Olga Kornievskaia okorniev@redhat.com Signed-off-by: Anna Schumaker anna.schumaker@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES **Key Points** - The change at `fs/nfs/nfs4proc.c:7876-7880` extends the recall retry loop so that `-NFS4ERR_GRACE` is treated exactly like `-NFS4ERR_DELAY`, matching RFC 7530’s requirement that non-reclaim requests retry during the server’s grace period; without it we prematurely exit the loop. - When the old code bailed out on `-NFS4ERR_GRACE`, control returned up the stack, causing `nfs_delegation_claim_locks()` to propagate `-EAGAIN` (`fs/nfs/delegation.c:176-178`), which in turn made `nfs_end_delegation_return()` fall into the client-recovery path or abort the delegation (`fs/nfs/delegation.c:584-596`), disrupting otherwise healthy delegations after a server restart. - Other lock paths already retry on `-NFS4ERR_GRACE` (see `fs/nfs/nfs4proc.c:7594-7604`), so this patch simply aligns the delegation-recall path with existing, well-tested behaviour and prevents unnecessary recovery storms. - The fix is tiny, localized to the NFS client delegation logic, and carries minimal regression risk while addressing a real-world failure mode observed during grace periods; it is an ideal candidate for stable backporting.
fs/nfs/nfs4proc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 611e6283c194f..4de3e4bd724b7 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7872,10 +7872,10 @@ int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, return err; do { err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW); - if (err != -NFS4ERR_DELAY) + if (err != -NFS4ERR_DELAY && err != -NFS4ERR_GRACE) break; ssleep(1); - } while (err == -NFS4ERR_DELAY); + } while (err == -NFS4ERR_DELAY || err == -NFSERR_GRACE); return nfs4_handle_delegation_recall_error(server, state, stateid, fl, err); }