From: Miklos Szeredi Date: Tue, 17 Mar 2026 11:00:29 +0000 (+0100) Subject: fuse: add struct fuse_chan X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a73a7883b40ea0a123409ef39a072218401ac5d8;p=thirdparty%2Flinux.git fuse: add struct fuse_chan 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 --- diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index 3d38828af41fc..e0616604d81ae 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c @@ -51,6 +51,7 @@ #include #include +#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); diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 0359a7b10393d..c3d7eb4819743 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -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) + diff --git a/fs/fuse/dev.h b/fs/fuse/dev.h index f7db15c33cf97..70e4a75e6942c 100644 --- a/fs/fuse/dev.h +++ b/fs/fuse/dev.h @@ -3,7 +3,14 @@ #ifndef _FS_FUSE_DEV_H #define _FS_FUSE_DEV_H +#include + 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); diff --git a/fs/fuse/fuse_dev_i.h b/fs/fuse/fuse_dev_i.h index 1853940fe80a5..256d973aa6c01 100644 --- a/fs/fuse/fuse_dev_i.h +++ b/fs/fuse/fuse_dev_i.h @@ -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; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 111fb6f3ebc43..deaffe2452844 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -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 diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 8c0ad401a0b50..65f11108c81a1 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -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; diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 12300651a0f1a..f6d41b760210b 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -19,6 +19,7 @@ #include #include #include +#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;