]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fuse: implement ->tmpfile()
authorMiklos Szeredi <mszeredi@redhat.com>
Sat, 24 Sep 2022 05:00:00 +0000 (07:00 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Sat, 24 Sep 2022 05:00:00 +0000 (07:00 +0200)
This is basically equivalent to the FUSE_CREATE operation which creates and
opens a regular file.

Add a new FUSE_TMPFILE operation, otherwise just reuse the protocol and the
code for FUSE_CREATE.

Acked-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/dir.c
fs/fuse/fuse_i.h
include/uapi/linux/fuse.h

index b585b04e815e0fa74276c315e941c74a4eb9c8f5..bb97a384dc5dd8b8caeba91c3e9bc6f21fefc342 100644 (file)
@@ -529,7 +529,7 @@ out_err:
  */
 static int fuse_create_open(struct inode *dir, struct dentry *entry,
                            struct file *file, unsigned int flags,
-                           umode_t mode)
+                           umode_t mode, u32 opcode)
 {
        int err;
        struct inode *inode;
@@ -573,7 +573,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
                inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID;
        }
 
-       args.opcode = FUSE_CREATE;
+       args.opcode = opcode;
        args.nodeid = get_node_id(dir);
        args.in_numargs = 2;
        args.in_args[0].size = sizeof(inarg);
@@ -676,7 +676,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
        if (fc->no_create)
                goto mknod;
 
-       err = fuse_create_open(dir, entry, file, flags, mode);
+       err = fuse_create_open(dir, entry, file, flags, mode, FUSE_CREATE);
        if (err == -ENOSYS) {
                fc->no_create = 1;
                goto mknod;
@@ -802,6 +802,23 @@ static int fuse_create(struct user_namespace *mnt_userns, struct inode *dir,
        return fuse_mknod(&init_user_ns, dir, entry, mode, 0);
 }
 
+static int fuse_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
+                       struct file *file, umode_t mode)
+{
+       struct fuse_conn *fc = get_fuse_conn(dir);
+       int err;
+
+       if (fc->no_tmpfile)
+               return -EOPNOTSUPP;
+
+       err = fuse_create_open(dir, file->f_path.dentry, file, file->f_flags, mode, FUSE_TMPFILE);
+       if (err == -ENOSYS) {
+               fc->no_tmpfile = 1;
+               err = -EOPNOTSUPP;
+       }
+       return err;
+}
+
 static int fuse_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
                      struct dentry *entry, umode_t mode)
 {
@@ -1913,6 +1930,7 @@ static const struct inode_operations fuse_dir_inode_operations = {
        .setattr        = fuse_setattr,
        .create         = fuse_create,
        .atomic_open    = fuse_atomic_open,
+       .tmpfile        = fuse_tmpfile,
        .mknod          = fuse_mknod,
        .permission     = fuse_permission,
        .getattr        = fuse_getattr,
index 488b460e046f4c679cf7b9c328bca6d9e9528774..98a9cf53187311e3ceb1c90b0db516bd73389485 100644 (file)
@@ -784,6 +784,9 @@ struct fuse_conn {
        /* Does the filesystem support per inode DAX? */
        unsigned int inode_dax:1;
 
+       /* Is tmpfile not implemented by fs? */
+       unsigned int no_tmpfile:1;
+
        /** The number of requests waiting for completion */
        atomic_t num_waiting;
 
index d6ccee9618917f0ef3e9eb5007cabc17c1596f70..76ee8f9e024af596d39665debcb50b509aff5dad 100644 (file)
  *  - add FUSE_SECURITY_CTX init flag
  *  - add security context to create, mkdir, symlink, and mknod requests
  *  - add FUSE_HAS_INODE_DAX, FUSE_ATTR_DAX
+ *
+ *  7.37
+ *  - add FUSE_TMPFILE
  */
 
 #ifndef _LINUX_FUSE_H
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 36
+#define FUSE_KERNEL_MINOR_VERSION 37
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -537,6 +540,7 @@ enum fuse_opcode {
        FUSE_SETUPMAPPING       = 48,
        FUSE_REMOVEMAPPING      = 49,
        FUSE_SYNCFS             = 50,
+       FUSE_TMPFILE            = 51,
 
        /* CUSE specific operations */
        CUSE_INIT               = 4096,