summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Layton <jlayton@kernel.org>2026-05-21 09:25:40 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-04 13:45:08 +0200
commit80866c84137e624045e364da321a3c422fd7e964 (patch)
tree23805c240ef25a56b2a3cd789d35bb28fd4e896f
parenta5b42c1e4ff2befaa6b96f7cbf32174751eba083 (diff)
downloadlinux-stable-80866c84137e624045e364da321a3c422fd7e964.tar.gz
linux-stable-80866c84137e624045e364da321a3c422fd7e964.zip
nfsd: fix inverted cp_ttl check in async copy reaper
commit 0150459b05490b88b7e7378a31550a9e07b5517c upstream. nfsd4_async_copy_reaper() is supposed to keep completed async copy state around for NFSD_COPY_INITIAL_TTL (10) laundromat ticks so that OFFLOAD_STATUS can report the result, then reap the state once the countdown expires. The TTL predicate is inverted: `if (--copy->cp_ttl)` is true while ticks remain and false when the counter reaches zero. This causes the copy to be reaped on the very first tick (cp_ttl goes from 10 to 9, which is non-zero) instead of after all 10 ticks elapse. Once reaped, OFFLOAD_STATUS returns NFS4ERR_BAD_STATEID because the copy state has already been freed. Fix by negating the test so that cleanup runs when the TTL expires. Fixes: aa0ebd21df9c ("NFSD: Add nfsd4_copy time-to-live") Cc: stable@vger.kernel.org Reported-by: Chris Mason <clm@meta.com> Assisted-by: kres:claude-opus-4-6 Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/nfsd/nfs4proc.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index ab39ec885440..972a6eefce7c 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1470,7 +1470,7 @@ void nfsd4_async_copy_reaper(struct nfsd_net *nn)
list_for_each_safe(pos, next, &clp->async_copies) {
copy = list_entry(pos, struct nfsd4_copy, copies);
if (test_bit(NFSD4_COPY_F_OFFLOAD_DONE, &copy->cp_flags)) {
- if (--copy->cp_ttl) {
+ if (!--copy->cp_ttl) {
list_del_init(&copy->copies);
list_add(&copy->copies, &reaplist);
}