]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
NFSv4: Handle NFS4ERR_NOTSUPP errors for directory delegations
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 3 Dec 2025 16:17:25 +0000 (11:17 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Sat, 6 Dec 2025 00:34:29 +0000 (19:34 -0500)
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 <trond.myklebust@hammerspace.com>
fs/nfs/nfs4proc.c

index c53ddb185aa3438780fdc228b2e8cf3038ca3d28..ec1ce593dea2bfc3b123bcd748d79404ce2d49ad 100644 (file)
@@ -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;
 }