summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuck Lever <cel@kernel.org>2026-08-17 21:08:36 -0400
committerChuck Lever <cel@kernel.org>2026-09-13 20:36:54 -0400
commitc507e82621cc4efb882fd6055b417768434286d0 (patch)
treeb16a7f3a4d098c39722c6536f8462fc1931ac3de
parent241848cc774eb1172fa867bb6a28c32cf1869c0d (diff)
downloadlinux-next-c507e82621cc4efb882fd6055b417768434286d0.tar.gz
linux-next-c507e82621cc4efb882fd6055b417768434286d0.zip
NFSD: Do not send CB_RECALL_ANY to NFSv4.0 clients
deleg_reaper() sends CB_RECALL_ANY to every ACTIVE client holding delegations, but CB_RECALL_ANY is an NFSv4.1 operation. An NFSv4.0 client's callback service accepts only CB_GETATTR and CB_RECALL, so it replies OP_ILLEGAL. The decoder maps the unexpected opnum to -EIO, and nfsd4_cb_done() marks the client's callback channel down. Nothing brings the channel back. nfsd4_run_cb_work() sets NFSD4_CB_UP only for a minor version above zero, and the only nfsd4_probe_callback() call site an NFSv4.0 client reaches is nfsd4_setclientid_confirm(). One visit from the reaper therefore leaves the channel marked down until the client re-establishes its clientid. RENEW then returns NFS4ERR_CB_PATH_DOWN for as long as the client holds delegations. nfsd4_cb_channel_good() stops returning true, so the client is granted no further delegations. Skip clients at minor version zero. Fixes: 44df6f439a17 ("NFSD: add delegation reaper to react to low memory condition") Cc: stable@vger.kernel.org Reviewed-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260817-recall-any-keep-count-v5-1-3b2cffce701e@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
-rw-r--r--fs/nfsd/nfs4state.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d33fb48e1f89..3bcfcef417bb 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -7962,6 +7962,8 @@ deleg_reaper(struct nfsd_net *nn)
list_for_each_safe(pos, next, &nn->client_lru) {
clp = list_entry(pos, struct nfs4_client, cl_lru);
+ if (clp->cl_minorversion == 0)
+ continue;
if (clp->cl_state != NFSD4_ACTIVE)
continue;
if (list_empty(&clp->cl_delegations))