]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fuse: support FSCONFIG_SET_FD for "fd" option
authorMiklos Szeredi <mszeredi@redhat.com>
Thu, 12 Mar 2026 19:30:08 +0000 (20:30 +0100)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 2 Apr 2026 18:53:00 +0000 (20:53 +0200)
This is not only cleaner to use in userspace (no need to sprintf the fd to
a string) but also allows userspace to detect that the devfd can be closed
after the fsconfig call.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
fs/fuse/inode.c

index ffe068b13a1e1a6bede149d356609360fcb6157f..702a1c619d36961feb4e3e611e6b0ee1cf83e895 100644 (file)
@@ -791,7 +791,7 @@ enum {
 
 static const struct fs_parameter_spec fuse_fs_parameters[] = {
        fsparam_string  ("source",              OPT_SOURCE),
-       fsparam_u32     ("fd",                  OPT_FD),
+       fsparam_fd      ("fd",                  OPT_FD),
        fsparam_u32oct  ("rootmode",            OPT_ROOTMODE),
        fsparam_uid     ("user_id",             OPT_USER_ID),
        fsparam_gid     ("group_id",            OPT_GROUP_ID),
@@ -803,13 +803,9 @@ static const struct fs_parameter_spec fuse_fs_parameters[] = {
        {}
 };
 
-static int fuse_opt_fd(struct fs_context *fsc, int fd)
+static int fuse_opt_fd(struct fs_context *fsc, struct file *file)
 {
        struct fuse_fs_context *ctx = fsc->fs_private;
-       struct file *file __free(fput) = fget(fd);
-
-       if (!file)
-               return -EBADF;
 
        if (file->f_op != &fuse_dev_operations)
                return invalfc(fsc, "fd is not a fuse device");
@@ -865,7 +861,15 @@ static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param)
                return 0;
 
        case OPT_FD:
-               return fuse_opt_fd(fsc, result.uint_32);
+               if (param->type == fs_value_is_file) {
+                       return fuse_opt_fd(fsc, param->file);
+               } else {
+                       struct file *file __free(fput) = fget(result.uint_32);
+                       if (!file)
+                               return -EBADF;
+
+                       return fuse_opt_fd(fsc, file);
+               }
 
        case OPT_ROOTMODE:
                if (!fuse_valid_type(result.uint_32))