]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fuse: add struct fuse_chan
authorMiklos Szeredi <mszeredi@redhat.com>
Tue, 17 Mar 2026 11:00:29 +0000 (12:00 +0100)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 15 Jun 2026 12:06:15 +0000 (14:06 +0200)
The goal is to separate transport layer stuff out from struct fuse_conn,
leaving just the filesystem related members.

Add a new object referenced from fuse_conn.  This patch just implements the
allocation and freeing of this object.

Following patches will move transport related members from fuse_conn to
fuse_chan.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/cuse.c
fs/fuse/dev.c
fs/fuse/dev.h
fs/fuse/fuse_dev_i.h
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/fuse/virtio_fs.c

index 3d38828af41fc261e32479938f7cf5ad2b61a251..e0616604d81ae6a71b6827c246919e6c2181a4f0 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/uio.h>
 #include <linux/user_namespace.h>
 
+#include "dev.h"
 #include "fuse_i.h"
 #include "fuse_dev_i.h"
 
@@ -504,8 +505,12 @@ static int cuse_channel_open(struct inode *inode, struct file *file)
 {
        struct fuse_dev *fud;
        struct cuse_conn *cc;
+       struct fuse_chan *fch __free(fuse_chan_free) = fuse_chan_new();
        int rc;
 
+       if (!fch)
+               return -ENOMEM;
+
        /* set up cuse_conn */
        cc = kzalloc_obj(*cc);
        if (!cc)
@@ -516,7 +521,7 @@ static int cuse_channel_open(struct inode *inode, struct file *file)
         * be represented in file->f_cred->user_ns.
         */
        fuse_conn_init(&cc->fc, &cc->fm, file->f_cred->user_ns,
-                      &fuse_dev_fiq_ops, NULL);
+                      &fuse_dev_fiq_ops, NULL, no_free_ptr(fch));
 
        cc->fc.release = cuse_fc_release;
        fud = fuse_dev_alloc_install(&cc->fc);
index 0359a7b10393da48ef14bdce8378e135020580f5..c3d7eb48197436f9742dd6292fef15fc4d17d372 100644 (file)
@@ -6,6 +6,7 @@
   See the file COPYING.
 */
 
+#include "dev.h"
 #include "dev_uring_i.h"
 #include "fuse_i.h"
 #include "fuse_dev_i.h"
@@ -320,6 +321,18 @@ const struct fuse_iqueue_ops fuse_dev_fiq_ops = {
 };
 EXPORT_SYMBOL_GPL(fuse_dev_fiq_ops);
 
+void fuse_chan_free(struct fuse_chan *fch)
+{
+       kfree(fch);
+}
+EXPORT_SYMBOL_GPL(fuse_chan_free);
+
+struct fuse_chan *fuse_chan_new(void)
+{
+       return kzalloc_obj(struct fuse_chan);
+}
+EXPORT_SYMBOL_GPL(fuse_chan_new);
+
 static void fuse_send_one(struct fuse_iqueue *fiq, struct fuse_req *req)
 {
        req->in.h.len = sizeof(struct fuse_in_header) +
index f7db15c33cf97985e4d85b582614f8143cb436ed..70e4a75e6942c9be292746acc98f1e74ded88826 100644 (file)
@@ -3,7 +3,14 @@
 #ifndef _FS_FUSE_DEV_H
 #define _FS_FUSE_DEV_H
 
+#include <linux/cleanup.h>
+
 struct fuse_conn;
+struct fuse_chan;
+
+struct fuse_chan *fuse_chan_new(void);
+void fuse_chan_free(struct fuse_chan *fch);
+DEFINE_FREE(fuse_chan_free, struct fuse_chan *, if (_T) fuse_chan_free(_T))
 
 void fuse_init_server_timeout(struct fuse_conn *fc, unsigned int timeout);
 
index 1853940fe80a5550bd0c630ee0c4de2f65f4b484..256d973aa6c013c9fe471806ecf8e84433f56392 100644 (file)
@@ -21,6 +21,10 @@ struct fuse_req;
 struct fuse_iqueue;
 struct fuse_forget_link;
 
+struct fuse_chan {
+       /* will move stuff from struct fuse_conn */
+};
+
 struct fuse_copy_state {
        struct fuse_req *req;
        struct iov_iter *iter;
index 111fb6f3ebc43bfeb9a9c1aaac265b5e44ab2444..deaffe2452844d0fd48f74c0db25832125a5b68f 100644 (file)
@@ -668,6 +668,9 @@ struct fuse_conn {
        /** Input queue */
        struct fuse_iqueue iq;
 
+       /* transport layer object */
+       struct fuse_chan *chan;
+
        /** The next unique kernel file handle */
        atomic64_t khctr;
 
@@ -1313,7 +1316,8 @@ void fuse_pqueue_init(struct fuse_pqueue *fpq);
  */
 void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
                    struct user_namespace *user_ns,
-                   const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv);
+                   const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv,
+                   struct fuse_chan *fch);
 
 /**
  * Release reference to fuse_conn
index 8c0ad401a0b5061c05c3f9e17ef4dc7064bf701f..65f11108c81a14860bd52c6f2e1170da4bfa0add 100644 (file)
@@ -997,7 +997,7 @@ void fuse_pqueue_init(struct fuse_pqueue *fpq)
 
 void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
                    struct user_namespace *user_ns,
-                   const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv)
+                   const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv, struct fuse_chan *fch)
 {
        memset(fc, 0, sizeof(*fc));
        spin_lock_init(&fc->lock);
@@ -1035,6 +1035,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
        INIT_LIST_HEAD(&fc->mounts);
        list_add(&fm->fc_entry, &fc->mounts);
        fm->fc = fc;
+       fc->chan = fch;
 }
 EXPORT_SYMBOL_GPL(fuse_conn_init);
 
@@ -1043,6 +1044,7 @@ static void delayed_release(struct rcu_head *p)
        struct fuse_conn *fc = container_of(p, struct fuse_conn, rcu);
 
        fuse_uring_destruct(fc);
+       fuse_chan_free(fc->chan);
 
        put_user_ns(fc->user_ns);
        fc->release(fc);
@@ -1983,8 +1985,12 @@ static int fuse_get_tree(struct fs_context *fsc)
        struct fuse_conn *fc;
        struct fuse_mount *fm;
        struct super_block *sb;
+       struct fuse_chan *fch __free(fuse_chan_free) = fuse_chan_new();
        int err;
 
+       if (!fch)
+               return -ENOMEM;
+
        fc = kmalloc_obj(*fc);
        if (!fc)
                return -ENOMEM;
@@ -1995,7 +2001,7 @@ static int fuse_get_tree(struct fs_context *fsc)
                return -ENOMEM;
        }
 
-       fuse_conn_init(fc, fm, fsc->user_ns, &fuse_dev_fiq_ops, NULL);
+       fuse_conn_init(fc, fm, fsc->user_ns, &fuse_dev_fiq_ops, NULL, no_free_ptr(fch));
        fc->release = fuse_free_conn;
 
        fsc->s_fs_info = fm;
index 12300651a0f1ac81d631c7358fa5a39cc0db928f..f6d41b760210b198629c31d26874610a412f2dc4 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/highmem.h>
 #include <linux/cleanup.h>
 #include <linux/uio.h>
+#include "dev.h"
 #include "fuse_i.h"
 #include "fuse_dev_i.h"
 
@@ -1683,8 +1684,12 @@ static int virtio_fs_get_tree(struct fs_context *fsc)
        struct fuse_conn *fc = NULL;
        struct fuse_mount *fm;
        unsigned int virtqueue_size;
+       struct fuse_chan *fch __free(fuse_chan_free) = fuse_chan_new();
        int err = -EIO;
 
+       if (!fch)
+               return -ENOMEM;
+
        if (!fsc->source)
                return invalf(fsc, "No source specified");
 
@@ -1711,7 +1716,8 @@ static int virtio_fs_get_tree(struct fs_context *fsc)
        if (!fm)
                goto out_err;
 
-       fuse_conn_init(fc, fm, fsc->user_ns, &virtio_fs_fiq_ops, fs);
+       fuse_conn_init(fc, fm, fsc->user_ns, &virtio_fs_fiq_ops, fs, no_free_ptr(fch));
+
        fc->release = fuse_free_conn;
        fc->delete_stale = true;
        fc->auto_submounts = true;