]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
fuse: add internal open/release helpers
authorMiklos Szeredi <mszeredi@redhat.com>
Wed, 7 Apr 2021 12:36:45 +0000 (14:36 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 12 Apr 2021 13:04:30 +0000 (15:04 +0200)
Clean out 'struct file' from internal helpers.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/file.c
fs/fuse/fuse_i.h

index d49fad6bdc292e7a8b0b9f26b3958962f88de53c..e8aa5337eb290c9c5fe7a85ba21b49ec488bab3c 100644 (file)
 #include <linux/uio.h>
 #include <linux/fs.h>
 
-static int fuse_send_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
-                         int opcode, struct fuse_open_out *outargp)
+static int fuse_send_open(struct fuse_mount *fm, u64 nodeid,
+                         unsigned int open_flags, int opcode,
+                         struct fuse_open_out *outargp)
 {
        struct fuse_open_in inarg;
        FUSE_ARGS(args);
 
        memset(&inarg, 0, sizeof(inarg));
-       inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
+       inarg.flags = open_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
        if (!fm->fc->atomic_o_trunc)
                inarg.flags &= ~O_TRUNC;
 
@@ -123,8 +124,8 @@ static void fuse_file_put(struct fuse_file *ff, bool sync, bool isdir)
        }
 }
 
-int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
-                bool isdir)
+struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
+                                unsigned int open_flags, bool isdir)
 {
        struct fuse_conn *fc = fm->fc;
        struct fuse_file *ff;
@@ -132,7 +133,7 @@ int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
 
        ff = fuse_file_alloc(fm);
        if (!ff)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        ff->fh = 0;
        /* Default for no-open */
@@ -141,14 +142,14 @@ int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
                struct fuse_open_out outarg;
                int err;
 
-               err = fuse_send_open(fm, nodeid, file, opcode, &outarg);
+               err = fuse_send_open(fm, nodeid, open_flags, opcode, &outarg);
                if (!err) {
                        ff->fh = outarg.fh;
                        ff->open_flags = outarg.open_flags;
 
                } else if (err != -ENOSYS) {
                        fuse_file_free(ff);
-                       return err;
+                       return ERR_PTR(err);
                } else {
                        if (isdir)
                                fc->no_opendir = 1;
@@ -161,9 +162,19 @@ int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
                ff->open_flags &= ~FOPEN_DIRECT_IO;
 
        ff->nodeid = nodeid;
-       file->private_data = ff;
 
-       return 0;
+       return ff;
+}
+
+int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
+                bool isdir)
+{
+       struct fuse_file *ff = fuse_file_open(fm, nodeid, file->f_flags, isdir);
+
+       if (!IS_ERR(ff))
+               file->private_data = ff;
+
+       return PTR_ERR_OR_ZERO(ff);
 }
 EXPORT_SYMBOL_GPL(fuse_do_open);
 
@@ -284,22 +295,21 @@ static void fuse_prepare_release(struct fuse_inode *fi, struct fuse_file *ff,
        ra->args.nocreds = true;
 }
 
-void fuse_release_common(struct file *file, bool isdir)
+void fuse_file_release(struct inode *inode, struct fuse_file *ff,
+                      unsigned int open_flags, fl_owner_t id, bool isdir)
 {
-       struct fuse_inode *fi = get_fuse_inode(file_inode(file));
-       struct fuse_file *ff = file->private_data;
+       struct fuse_inode *fi = get_fuse_inode(inode);
        struct fuse_release_args *ra = ff->release_args;
        int opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
 
-       fuse_prepare_release(fi, ff, file->f_flags, opcode);
+       fuse_prepare_release(fi, ff, open_flags, opcode);
 
        if (ff->flock) {
                ra->inarg.release_flags |= FUSE_RELEASE_FLOCK_UNLOCK;
-               ra->inarg.lock_owner = fuse_lock_owner_id(ff->fm->fc,
-                                                         (fl_owner_t) file);
+               ra->inarg.lock_owner = fuse_lock_owner_id(ff->fm->fc, id);
        }
        /* Hold inode until release is finished */
-       ra->inode = igrab(file_inode(file));
+       ra->inode = igrab(inode);
 
        /*
         * Normally this will send the RELEASE request, however if
@@ -313,6 +323,12 @@ void fuse_release_common(struct file *file, bool isdir)
        fuse_file_put(ff, ff->fm->fc->destroy, isdir);
 }
 
+void fuse_release_common(struct file *file, bool isdir)
+{
+       fuse_file_release(file_inode(file), file->private_data, file->f_flags,
+                         (fl_owner_t) file, isdir);
+}
+
 static int fuse_open(struct inode *inode, struct file *file)
 {
        return fuse_open_common(inode, file, false);
index 5f98a1f76821e3d355a78bceb0a8b130d354f514..42b611c9ede0315f37b611b2d64e936c06d73ecb 100644 (file)
@@ -1242,4 +1242,11 @@ long fuse_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 long fuse_file_compat_ioctl(struct file *file, unsigned int cmd,
                            unsigned long arg);
 
+/* file.c */
+
+struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
+                                unsigned int open_flags, bool isdir);
+void fuse_file_release(struct inode *inode, struct fuse_file *ff,
+                      unsigned int open_flags, fl_owner_t id, bool isdir);
+
 #endif /* _FS_FUSE_I_H */