From: Horst Birthelmer <horst@birthelmer.de>
To: Miklos Szeredi <mszeredi@redhat.com>
Cc: fuse-devel@lists.linux.dev, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH] fuse: add fusex filesystem
Date: Fri, 8 May 2026 19:29:44 +0200 [thread overview]
Message-ID: <af4clh11ik-DYbiF@fedora.fritz.box> (raw)
In-Reply-To: <20260429102058.1362965-1-mszeredi@redhat.com>
On Wed, Apr 29, 2026 at 12:20:57PM +0200, Miklos Szeredi wrote:
> This stands for "fuse extended/experimental".
>
> The purpose is to provide a clean base for big features like the FUSE_IOMAP
> api.
>
> It's also a good way to try new stuff like file handles and compound
> requests without the risk of breaking something in the large and complex
> fuse codebase.
>
> Whether these features will be migrated back into the main fuse codebase,
> or fusex is going to end up as a major version update is still up in the
> air.
>
> Major differences from regular fuse:
>
> - local filesystem mode only
> - only synchronous FUSE_INIT is supported
> - only no-open mode
> - new requests:
> + FUSE_LOOKUP_ROOT - return nodeid of root
> + FUSE_LOOKUPX - FUSE_LOOKUP without the getattr
> + FUSE_MKOBJX - merged FUSE_MKNOD, MKDIR, SYMLINK and TMPFILE
> + FUSE_SETSTATX - extended version of FUSE_SETATTR
>
> Missing features:
>
> - file handles / export ops
> - compound requests
> - xattr caching
> - fileattr
> - fiemap
> - ioctl
> - copy_file_range
> - lazy dir open
>
> Test server can be found at:
>
> https://github.com/szmi/fuse-utils
>
> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> ---
>
> Patch is against
>
> git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git#for-next
>
> fs/fuse/Makefile | 2 +-
> fs/fuse/args.h | 1 +
> fs/fuse/dev.c | 13 +-
> fs/fuse/dir.c | 4 +-
> fs/fuse/fuse_i.h | 8 +
> fs/fuse/fusex.c | 1751 +++++++++++++++++++++++++++++++++++++
> fs/fuse/fusex.h | 4 +
> fs/fuse/inode.c | 16 +-
> include/uapi/linux/fuse.h | 36 +
> 9 files changed, 1826 insertions(+), 9 deletions(-)
> create mode 100644 fs/fuse/fusex.c
> create mode 100644 fs/fuse/fusex.h
>
> diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile
> index 245e67852b03..d9963e411b62 100644
> --- a/fs/fuse/Makefile
> +++ b/fs/fuse/Makefile
> @@ -12,7 +12,7 @@ obj-$(CONFIG_VIRTIO_FS) += virtiofs.o
>
> fuse-y := trace.o # put trace.o first so we see ftrace errors sooner
> fuse-y += dev.o dir.o file.o inode.o control.o xattr.o acl.o readdir.o ioctl.o req_timeout.o req.o
> -fuse-y += poll.o notify.o
> +fuse-y += poll.o notify.o fusex.o
> fuse-y += iomode.o
> fuse-$(CONFIG_FUSE_DAX) += dax.o
> fuse-$(CONFIG_FUSE_PASSTHROUGH) += passthrough.o backing.o
> diff --git a/fs/fuse/args.h b/fs/fuse/args.h
> index ecfe51a192af..1c1e0a25ea07 100644
> --- a/fs/fuse/args.h
> +++ b/fs/fuse/args.h
> @@ -35,6 +35,7 @@ struct fuse_args {
> bool out_pages:1;
> bool user_pages:1;
> bool out_argvar:1;
> + bool out_var_alloc:1;
> bool page_zeroing:1;
> bool page_replace:1;
> bool may_block:1;
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> index 6fe0d8c263df..134572b1a9af 100644
> --- a/fs/fuse/dev.c
> +++ b/fs/fuse/dev.c
> @@ -1847,15 +1847,24 @@ int fuse_copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
>
> reqsize += fuse_len_args(args->out_numargs, args->out_args);
>
> - if (reqsize < nbytes || (reqsize > nbytes && !args->out_argvar))
> + if (reqsize < nbytes)
> return -EINVAL;
> - else if (reqsize > nbytes) {
> +
> + if (args->out_argvar) {
> struct fuse_arg *lastarg = &args->out_args[args->out_numargs-1];
> unsigned diffsize = reqsize - nbytes;
>
> if (diffsize > lastarg->size)
> return -EINVAL;
> lastarg->size -= diffsize;
> +
> + if (args->out_var_alloc) {
> + lastarg->value = kvmalloc(lastarg->size, GFP_KERNEL);
> + if (!lastarg->value)
> + return -ENOMEM;
> + }
> + } else if (reqsize > nbytes) {
> + return -EINVAL;
> }
> return fuse_copy_args(cs, args->out_numargs, args->out_pages,
> args->out_args, args->page_zeroing);
> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> index be41c14ef329..cbe0d4b65d49 100644
> --- a/fs/fuse/dir.c
> +++ b/fs/fuse/dir.c
> @@ -542,7 +542,7 @@ int fuse_valid_type(int m)
> S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
> }
>
> -static bool fuse_valid_size(u64 size)
> +bool fuse_valid_size(u64 size)
> {
> return size <= LLONG_MAX;
> }
> @@ -2485,7 +2485,7 @@ static int fuse_symlink_read_folio(struct file *null, struct folio *folio)
> return err;
> }
>
> -static const struct address_space_operations fuse_symlink_aops = {
> +const struct address_space_operations fuse_symlink_aops = {
> .read_folio = fuse_symlink_read_folio,
> };
>
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> index 3a7ac74a23ed..fe66281b7554 100644
> --- a/fs/fuse/fuse_i.h
> +++ b/fs/fuse/fuse_i.h
> @@ -69,6 +69,9 @@ extern struct mutex fuse_mutex;
> extern unsigned int max_user_bgreq;
> extern unsigned int max_user_congthresh;
>
> +extern struct kmem_cache *fuse_inode_cachep;
> +extern const struct address_space_operations fuse_symlink_aops;
> +
> struct fuse_forget_link;
>
> /**
> @@ -911,6 +914,8 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
> int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
> struct fuse_entry_out *outarg, struct inode **inode);
>
> +void fuse_umount_begin(struct super_block *sb);
> +
> /*
> * Initialize READ or READDIR request
> */
> @@ -1102,6 +1107,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc);
> * Is file type valid?
> */
> int fuse_valid_type(int m);
> +bool fuse_valid_size(u64 size);
>
> bool fuse_invalid_attr(struct fuse_attr *attr);
>
> @@ -1204,6 +1210,8 @@ struct posix_acl *fuse_get_acl(struct mnt_idmap *idmap,
> int fuse_set_acl(struct mnt_idmap *, struct dentry *dentry,
> struct posix_acl *acl, int type);
>
> +void fuse_convert_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr);
> +
> /* readdir.c */
> int fuse_readdir(struct file *file, struct dir_context *ctx);
>
> diff --git a/fs/fuse/fusex.c b/fs/fuse/fusex.c
> new file mode 100644
> index 000000000000..98e239e7e00e
> --- /dev/null
> +++ b/fs/fuse/fusex.c
> @@ -0,0 +1,1751 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include "fusex.h"
> +#include "dev.h"
> +#include "fuse_i.h"
> +
> +#include <linux/fs_context.h>
> +#include <linux/miscdevice.h>
> +#include <linux/xxhash.h>
> +#include <linux/pagemap.h>
> +#include <linux/exportfs.h>
> +#include <linux/iversion.h>
> +#include <linux/posix_acl_xattr.h>
> +#include <linux/statfs.h>
> +#include <linux/falloc.h>
> +#include <linux/fs_parser.h>
> +
I think you're missing
#include <uapi/linux/magic.h>
here for FUSE_SUPER_MAGIC
next prev parent reply other threads:[~2026-05-08 17:36 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-29 10:20 [PATCH] fuse: add fusex filesystem Miklos Szeredi
2026-05-07 8:31 ` Horst Birthelmer
2026-05-08 13:01 ` Amir Goldstein
2026-05-12 8:17 ` Miklos Szeredi
2026-05-12 13:08 ` Amir Goldstein
2026-05-12 13:46 ` Bernd Schubert
2026-05-12 8:11 ` Miklos Szeredi
2026-05-12 10:29 ` Horst Birthelmer
2026-05-08 17:29 ` Horst Birthelmer [this message]
2026-05-12 8:20 ` Miklos Szeredi
2026-05-11 8:50 ` Horst Birthelmer
2026-05-12 8:34 ` Miklos Szeredi
2026-05-12 5:05 ` Joanne Koong
2026-05-12 9:18 ` Miklos Szeredi
2026-05-12 13:22 ` Amir Goldstein
2026-05-12 19:22 ` Joanne Koong
2026-05-12 17:33 ` Joanne Koong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=af4clh11ik-DYbiF@fedora.fritz.box \
--to=horst@birthelmer.de \
--cc=fuse-devel@lists.linux.dev \
--cc=linux-fsdevel@vger.kernel.org \
--cc=mszeredi@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox