diff options
| author | Chuck Lever <cel@kernel.org> | 2026-08-17 21:08:36 -0400 |
|---|---|---|
| committer | Chuck Lever <cel@kernel.org> | 2026-09-13 20:36:54 -0400 |
| commit | c507e82621cc4efb882fd6055b417768434286d0 (patch) | |
| tree | b16a7f3a4d098c39722c6536f8462fc1931ac3de | |
| parent | 241848cc774eb1172fa867bb6a28c32cf1869c0d (diff) | |
| download | linux-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.c | 2 |
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)) |
