From: "Darrick J. Wong" <djwong@kernel.org>
To: Bernd Schubert <bernd@bsbernd.com>
Cc: linux-fsdevel@vger.kernel.org, Miklos Szeredi <miklos@szeredi.hu>,
Joanne Koong <joannelkoong@gmail.com>, Kevin Chen <kchen@ddn.com>,
Bernd Schubert <bschubert@ddn.com>
Subject: Re: [PATCH v2 13/25] Add support for the new linux mount API
Date: Mon, 20 Apr 2026 08:48:26 -0700 [thread overview]
Message-ID: <20260420154826.GJ7727@frogsfrogsfrogs> (raw)
In-Reply-To: <a83cb254-2b7f-4957-9e88-6f5d1dbc716a@bsbernd.com>
On Sun, Apr 19, 2026 at 07:45:39PM +0200, Bernd Schubert wrote:
>
>
> On 3/30/26 20:27, Darrick J. Wong wrote:
> > On Thu, Mar 26, 2026 at 10:34:46PM +0100, Bernd Schubert wrote:
> >> From: Bernd Schubert <bschubert@ddn.com>
> >>
> >> So far only supported for fuse_session_mount(), which is called
> >> from high and low level API, but not yet supported for
> >> fuse_open_channel(), which used for privilege drop through
> >> mount.fuse. Main goal for the new API is support for synchronous
> >> FUSE_INIT and I don't think that is going to work with
> >> fuse_open_channel(). At least not with io-uring support as long
> >> as it is started from FUSE_INIT.
> >>
> >> Signed-off-by: Bernd Schubert <bschubert@ddn.com>
<snip>
> >> +/*
> >> + * Apply VFS superblock flags to the filesystem context.
> >> + * Only handles flags that are filesystem parameters (ro, sync, dirsync).
> >> + * Mount attributes (nosuid, nodev, etc.) are handled separately via fsmount().
> >> + */
> >> +static int apply_mount_flags(int fsfd, unsigned long flags)
> >> +{
> >> + int res, save_errno;
> >> +
> >> + /* Handle read-only flag */
> >> + if (flags & MS_RDONLY) {
> >> + const char *flag = "ro";
> >> +
> >> + res = fsconfig(fsfd, FSCONFIG_SET_FLAG, flag, NULL, 0);
> >> + if (res == -1) {
> >> + save_errno = errno;
> >> + fprintf(stderr, "fuse: fsconfig SET_FLAG %s failed:", flag);
> >> + log_fsconfig_kmsg(fsfd);
> >> + return -save_errno;
> >> + }
> >> + }
> >> +
> >> + /* Handle sync flag */
> >> + if (flags & MS_SYNCHRONOUS) {
> >> + const char *flag = "sync";
> >> +
> >> + res = fsconfig(fsfd, FSCONFIG_SET_FLAG, flag, NULL, 0);
> >> + if (res == -1) {
> >> + save_errno = errno;
> >> + fprintf(stderr, "fuse: fsconfig SET_FLAG %s failed:", flag);
> >> + log_fsconfig_kmsg(fsfd);
> >> + return -save_errno;
> >> + }
> >> + }
> >> +
> >> +#ifndef __NetBSD__
> >
> > This is always true, right? Only Linux has fsmount.
> >
> >> + /* Handle dirsync flag */
> >> + if (flags & MS_DIRSYNC) {
> >> + const char *flag = "dirsync";
> >> +
> >> + res = fsconfig(fsfd, FSCONFIG_SET_FLAG, flag, NULL, 0);
> >> + if (res == -1) {
> >> + save_errno = errno;
> >> + fprintf(stderr, "fuse: fsconfig SET_FLAG %s failed:", flag);
> >> + log_fsconfig_kmsg(fsfd);
> >> + return -save_errno;
> >> + }
> >> + }
> >> +#endif
> >> +
> >> + return 0;
> >
> > I did this a bit differently:
> >
> >
> > static const struct ms_to_str_map strflags[] = {
> > { MS_SYNCHRONOUS, "sync" },
> > { MS_DIRSYNC, "dirsync" },
> > { MS_LAZYTIME, "lazytime" },
> > { 0, 0 },
> > };
> >
> > static int set_ms_flags(struct mount_service *mo, unsigned long ms_flags)
> > {
> > const struct ms_to_str_map *i;
> > int ret;
> >
> > for (i = strflags; i->ms_flag != 0; i++) {
> > if (!(ms_flags & i->ms_flag))
> > continue;
> >
> > ret = fsconfig(mo->fsopenfd, FSCONFIG_SET_FLAG, i->string,
> > NULL, 0);
> > if (ret) {
> > int error = errno;
> >
> > fprintf(stderr, "%s: set %s option: %s\n",
> > mo->msgtag, i->string, strerror(error));
> > emit_fsconfig_messages(mo);
> >
> > errno = error;
> > return -1;
> > }
> > ms_flags &= ~i->ms_flag;
> > }
> >
> > /*
> > * We can't translate all the supplied MS_ flags into MOUNT_ATTR_ flags
> > * or string flags! Return a magic code so the caller will fall back
> > * to regular mount(2).
> > */
> > return ms_flags ? -2 : 0;
> > }
> >
> > That way you can always fall back to classic mount() instead of quietly
> > dropping an MS_ flag here if one ever gets added without a corresponding
> > MOUNT_ATTR_ flag. AFAICT there aren't any that *would* get dropped and
> > you can verify via code inspection, but why not avoid the logic bomb?
>
> I took your function, just slightly modified it, like we can always fall
> back from new mount api to classic.
How does that work? If we fail midway through setting parameters with
fsconfig, then the user will see a bunch of error messages from that,
followed by a successful old-school mount(2)?
> >
> >> +}
> >> +
> >> +static int apply_opt_fd(int fsfd, const char *value)
> >> +{
> >> + int res, save_errno;
> >> +
> >> + /* The fd parameter is a u32 value, not a file descriptor to pass */
> >> + res = fsconfig(fsfd, FSCONFIG_SET_STRING, "fd", value, 0);
> >> + if (res == -1) {
> >> + save_errno = errno;
> >> + fprintf(stderr, "fuse: fsconfig SET_STRING fd=%s failed:",
> >> + value);
> >> + log_fsconfig_kmsg(fsfd);
> >> + return -save_errno;
> >> + }
> >> + return 0;
> >> +}
> >> +
> >> +static int apply_opt_string(int fsfd, const char *key, const char *value)
> >> +{
> >> + int res, save_errno;
> >> +
> >> + res = fsconfig(fsfd, FSCONFIG_SET_STRING, key, value, 0);
> >> + save_errno = errno;
> >> + if (res == -1) {
> >> + log_fsconfig_kmsg(fsfd);
> >> + fprintf(stderr, "fuse: fsconfig SET_STRING %s=%s failed: ",
> >> + key, value);
> >> + return -save_errno;
> >
> > I think this function should call fprintf and log_fsconfig_kmsg in the
> > same order as the other two apply_opt_* functions.
> >
> >> + }
> >> + return 0;
> >> +}
> >> +
> >> +static int apply_opt_flag(int fsfd, const char *opt)
> >> +{
> >> + int res, save_errno;
> >> +
> >> + res = fsconfig(fsfd, FSCONFIG_SET_FLAG, opt, NULL, 0);
> >> + if (res == -1) {
> >> + save_errno = errno;
> >> + fprintf(stderr, "fuse: fsconfig SET_FLAG %s failed:", opt);
> >> + log_fsconfig_kmsg(fsfd);
> >> + return -save_errno;
> >> + }
> >> + return 0;
> >> +}
> >> +
> >> +static int apply_opt_key_value(int fsfd, char *opt)
> >> +{
> >> + char *eq;
> >> + const char *key;
> >> + const char *value;
> >> +
> >> + eq = strchr(opt, '=');
> >> + if (!eq)
> >> + return apply_opt_flag(fsfd, opt);
> >> +
> >> + *eq = '\0';
> >> + key = opt;
> >> + value = eq + 1;
> >> +
> >> + if (strcmp(key, "fd") == 0)
> >> + return apply_opt_fd(fsfd, value);
> >> +
> >> + return apply_opt_string(fsfd, key, value);
> >> +}
> >> +
> >> +/**
> >> + * Check if an option is a mount attribute (handled by fsmount, not fsconfig)
> >> + */
> >> +static int is_mount_attr_opt(const char *opt)
> >> +{
> >> + /* These options are mount attributes passed to fsmount(), not fsconfig() */
> >> + return strcmp(opt, "nosuid") == 0 ||
> >> + strcmp(opt, "suid") == 0 ||
> >> + strcmp(opt, "nodev") == 0 ||
> >> + strcmp(opt, "dev") == 0 ||
> >> + strcmp(opt, "noexec") == 0 ||
> >> + strcmp(opt, "exec") == 0 ||
> >> + strcmp(opt, "noatime") == 0 ||
> >> + strcmp(opt, "atime") == 0 ||
> >> + strcmp(opt, "nodiratime") == 0 ||
> >> + strcmp(opt, "diratime") == 0 ||
> >> + strcmp(opt, "relatime") == 0 ||
> >> + strcmp(opt, "norelatime") == 0 ||
> >> + strcmp(opt, "strictatime") == 0 ||
> >> + strcmp(opt, "nostrictatime") == 0 ||
> >> + strcmp(opt, "nosymfollow") == 0 ||
> >> + strcmp(opt, "symfollow") == 0;
> >
> > /me wonders if this should be walking the mount_flags array instead of
> > opencoding the strings here?
>
> Yes, much better, encoded into
>
> const struct mount_flags mount_flags[] = {
> /* opt flag on safe fsconfig/fsmount */
> {"rw", MS_RDONLY, 0, 1, 0}, /* fsconfig */
> {"ro", MS_RDONLY, 1, 1, 0}, /* fsconfig */
> {"suid", MS_NOSUID, 0, 0, 1}, /* fsmount */
> ...
>
> as preparation patch.
Nice!
--D
>
> Thanks,
> Bernd
>
next prev parent reply other threads:[~2026-04-20 15:48 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-26 21:34 [PATCH v2 00/25] libfuse: Add support for synchronous init Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 01/25] ci-build: Add environment logging Bernd Schubert
2026-03-27 3:20 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 02/25] Add 'STRCPY' to the checkpatch ignore option Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 03/25] checkpatch.pl: Add _Atomic to $Attribute patttern Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 04/25] Add a new daemonize API Bernd Schubert
2026-03-27 22:06 ` Darrick J. Wong
2026-03-27 23:07 ` Bernd Schubert
2026-03-28 4:01 ` Darrick J. Wong
2026-03-30 17:45 ` Darrick J. Wong
2026-03-30 18:26 ` Bernd Schubert
2026-03-30 21:25 ` Darrick J. Wong
2026-03-30 17:55 ` Darrick J. Wong
2026-04-18 18:26 ` Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 05/25] Sync fuse_kernel.h with linux-6.18 Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 06/25] mount.c: Split fuse_mount_sys to prepare privileged sync FUSE_INIT Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 07/25] Add FUSE_MOUNT_FALLBACK_NEEDED define for -2 mount errors Bernd Schubert
2026-03-27 3:20 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 08/25] Refactor mount code / move common functions to mount_util.c Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 09/25] Use asprintf() for fuse_mnt_build_{source,type} Bernd Schubert
2026-03-27 3:24 ` Darrick J. Wong
2026-03-30 15:34 ` Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 10/25] lib/mount.c: Remove some BSD ifdefs Bernd Schubert
2026-03-27 3:28 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 11/25] Move 'struct mount_flags' to util.h Bernd Schubert
2026-03-30 18:11 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 12/25] conftest.py: Add more valgrind filter patterns Bernd Schubert
2026-03-30 18:16 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 13/25] Add support for the new linux mount API Bernd Schubert
2026-03-30 18:27 ` Darrick J. Wong
2026-04-19 17:45 ` Bernd Schubert
2026-04-20 15:48 ` Darrick J. Wong [this message]
2026-03-26 21:34 ` [PATCH v2 14/25] fuse mount: Support synchronous FUSE_INIT (privileged daemon) Bernd Schubert
2026-03-30 18:44 ` Darrick J. Wong
2026-04-19 22:36 ` Bernd Schubert
2026-04-20 15:53 ` Darrick J. Wong
2026-04-20 16:40 ` Bernd Schubert
2026-04-20 16:43 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 15/25] Add fuse_session_set_debug() to enable debug output without foreground Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 16/25] Move more generic mount code to mount_util.{c,h} Bernd Schubert
2026-03-30 18:47 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 17/25] Split the fusermount do_mount function Bernd Schubert
2026-03-30 18:48 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 18/25] fusermout: Remove the large read check Bernd Schubert
2026-03-27 3:32 ` Darrick J. Wong
2026-03-30 15:26 ` Bernd Schubert
2026-03-30 17:57 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 19/25] fusermount: Refactor extract_x_options Bernd Schubert
2026-03-26 21:34 ` [PATCH v2 20/25] Make fusermount work bidirectional for sync init Bernd Schubert
2026-03-30 19:03 ` Darrick J. Wong
2026-04-19 23:18 ` Bernd Schubert
2026-04-20 15:55 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 21/25] New mount API: Filter out "user=" Bernd Schubert
2026-03-27 3:32 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 22/25] Add support for sync-init of unprivileged daemons Bernd Schubert
2026-03-31 0:54 ` Darrick J. Wong
2026-04-20 0:02 ` Bernd Schubert
2026-04-20 16:31 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 23/25] Move fuse_mnt_build_{source,type} to mount_util.c Bernd Schubert
2026-03-30 19:04 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 24/25] Add mount and daemonization README documents Bernd Schubert
2026-03-31 1:17 ` Darrick J. Wong
2026-04-20 0:21 ` Bernd Schubert
2026-04-20 16:39 ` Darrick J. Wong
2026-03-26 21:34 ` [PATCH v2 25/25] Add a background debug option to passthrough hp Bernd Schubert
2026-03-30 19:04 ` Darrick J. Wong
2026-04-07 12:04 ` fuse-devel list on kernel.org Amir Goldstein
2026-04-07 12:25 ` Bernd Schubert
2026-04-07 12:29 ` Amir Goldstein
2026-04-07 18:05 ` Bernd Schubert
2026-04-07 19:10 ` Darrick J. Wong
2026-04-08 8:21 ` Amir Goldstein
2026-04-13 12:23 ` Amir Goldstein
2026-04-13 12:36 ` Bernd Schubert
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=20260420154826.GJ7727@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=bernd@bsbernd.com \
--cc=bschubert@ddn.com \
--cc=joannelkoong@gmail.com \
--cc=kchen@ddn.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=miklos@szeredi.hu \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.