From bd3b04b46c7a9940989ff4b29376e899e93d3a4a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 3 Dec 2025 11:17:25 -0500 Subject: [PATCH] NFSv4: Handle NFS4ERR_NOTSUPP errors for directory delegations The error NFS4ERR_NOTSUPP will be returned for operations that are legal, but not supported by the server. Fixes: 156b09482933 ("NFS: Request a directory delegation on ACCESS, CREATE, and UNLINK") Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index c53ddb185aa3..ec1ce593dea2 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4533,12 +4533,17 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, status = nfs4_do_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, task_flags); if (args.get_dir_deleg) { - if (status == -EOPNOTSUPP) { + switch (status) { + case 0: + if (gdd_res.status != GDD4_OK) + break; + status = nfs_inode_set_delegation( + inode, current_cred(), FMODE_READ, + &gdd_res.deleg, 0, NFS4_OPEN_DELEGATE_READ); + break; + case -ENOTSUPP: + case -EOPNOTSUPP: server->caps &= ~NFS_CAP_DIR_DELEG; - } else if (status == 0 && gdd_res.status == GDD4_OK) { - status = nfs_inode_set_delegation(inode, current_cred(), - FMODE_READ, &gdd_res.deleg, - 0, NFS4_OPEN_DELEGATE_READ); } } return status; @@ -4554,10 +4559,14 @@ int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, do { err = _nfs4_proc_getattr(server, fhandle, fattr, inode); trace_nfs4_getattr(server, fhandle, fattr, err); - if (err == -EOPNOTSUPP) - exception.retry = true; - else + switch (err) { + default: err = nfs4_handle_exception(server, err, &exception); + break; + case -ENOTSUPP: + case -EOPNOTSUPP: + exception.retry = true; + } } while (exception.retry); return err; } -- 2.47.3