public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Bernd Schubert <bschubert@ddn.com>
Cc: Bernd Schubert <bernd@bsbernd.com>,
	"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
	Miklos Szeredi <miklos@szeredi.hu>,
	Joanne Koong <joannelkoong@gmail.com>, Kevin Chen <kchen@ddn.com>
Subject: Re: [PATCH 12/19] fuse mount: Support synchronous FUSE_INIT (privileged daemon)
Date: Tue, 24 Mar 2026 15:50:12 -0700	[thread overview]
Message-ID: <20260324225012.GY6202@frogsfrogsfrogs> (raw)
In-Reply-To: <e0d7b5ee-ffef-45a4-8c39-84cd79342bae@ddn.com>

On Tue, Mar 24, 2026 at 08:42:36PM +0000, Bernd Schubert wrote:
> On 3/24/26 01:03, Darrick J. Wong wrote:
> > On Mon, Mar 23, 2026 at 06:45:07PM +0100, Bernd Schubert wrote:
> >> From: Bernd Schubert <bschubert@ddn.com>
> >>
> >> Add synchronous FUSE_INIT processing during mount() to
> >> enable early daemonization with proper error reporting
> >> to the parent process.
> >>
> >> A new mount thread is needed that handles FUSE_INIT and
> >> possible other requests at mount time (like getxattr for selinux).
> >> The kernel sends FUSE_INIT during the mount() syscall. Without a thread
> >> to process it, mount() blocks forever.
> >>
> >> Mount thread lifetime:
> >> Created before mount() syscall in fuse_start_sync_init_worker()
> >> Processes requests until se->mount_finished is set (after mount() returns)
> >> Joined after successful mount in fuse_wait_sync_init_completion()
> >> Cancelled if mount fails (direct → fusermount3 fallback)
> > 
> > Hrmm, so the main thread (of the child process after daemonization)
> > calls mount(), having started a child thread to read and process
> > FUSE_INIT + any other mount-related fuse requests?
> > 
> > Later I see an eventfd being used to signal this background thread that
> > it should exit and (presumably) let the real request processing queues
> > take over.  I'm curious why an eventfd here when pipes were used
> > earlier?
> 
> We cannot use eventfds for anything possibly used by BSD - which is

(Yeah, I was wondering about eventfd, but I don't know how quickly
libfuse features get ported to BSD so for all I know it could be years
until BSD gets SYNC_INIT.)

> fuse_daemonize_ and fusermount. So far sync-init is only in the new
> mount API - linux only. We need to switch to a pipe if BSD ever gets that.

I wonder, are the socket communications between fusermount-libfuse
considered external interface?  I'm assuming it's not, and you can
change it as long as you don't break the other side?

> > 
> >> Key changes:
> >>
> >> Add init_thread, init_error, mount_finished to struct fuse_session
> >> Use FUSE_DEV_IOC_SYNC_INIT ioctl for kernel support
> >> Fall back to async FUSE_INIT if unsupported
> >> Auto-enabled when fuse_daemonize_active() or via
> >> fuse_session_want_sync_init()
> >> Allows parent to report mount/init failures instead of
> >> exiting immediately after fork.
> >>
> >> Note: For now synchronous FUSE_INIT is only supported for privileged
> >> mounts.
> >>
> >> Signed-off-by: Bernd Schubert <bschubert@ddn.com>
> >> ---
> >>  include/fuse_lowlevel.h |  12 +++
> >>  lib/fuse_daemonize.c    |   8 ++
> >>  lib/fuse_i.h            |  16 ++++
> >>  lib/fuse_lowlevel.c     | 192 ++++++++++++++++++++++++++++++++++++++++++++++--
> >>  lib/mount.c             |   5 +-
> >>  lib/mount_fsmount.c     |   5 +-
> >>  6 files changed, 229 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
> >> index ee0bd8d71d95e4d57ebb4873dca0f2b36e22a649..d8626f85bdaf497534cd2835a589e30f1f4e2466 100644
> >> --- a/include/fuse_lowlevel.h
> >> +++ b/include/fuse_lowlevel.h
> >> @@ -2429,6 +2429,18 @@ void fuse_session_process_buf(struct fuse_session *se,
> >>   */
> >>  int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf);
> >>  
> >> +/**
> >> + * Request synchronous FUSE_INIT, i.e. FUSE_INIT is handled by the
> >> + * kernel before mount is returned.
> >> + *
> >> + * As FUSE_INIT also starts io-uring ring threads, fork() must not be
> >> + * called after this if io-uring is enabled. Also see
> >> + * fuse_session_daemonize_start().
> >> + *
> >> + * This must be called before fuse_session_mount() to have any effect.
> >> + */
> >> +void fuse_session_want_sync_init(struct fuse_session *se);
> >> +
> >>  /**
> >>   * Check if the request is submitted through fuse-io-uring
> >>   */
> >> diff --git a/lib/fuse_daemonize.c b/lib/fuse_daemonize.c
> >> index 5d191e7d737d04876d02ef6bd526061c003d2ab7..1a32ef74093f231091b4f541e5b9136bff72024f 100644
> >> --- a/lib/fuse_daemonize.c
> >> +++ b/lib/fuse_daemonize.c
> >> @@ -9,6 +9,7 @@
> >>  #define _GNU_SOURCE
> >>  
> >>  #include "fuse_daemonize.h"
> >> +#include "fuse_i.h"
> >>  
> >>  #include <fcntl.h>
> >>  #include <poll.h>
> >> @@ -282,3 +283,10 @@ bool fuse_daemonize_active(void)
> >>  
> >>  	return dm != NULL && (dm->daemonized || dm->active);
> >>  }
> >> +
> >> +bool fuse_daemonize_set(void)
> >> +{
> >> +	struct fuse_daemonize *dm = atomic_load(&daemonize);
> >> +
> >> +	return dm != NULL;
> >> +}
> >> diff --git a/lib/fuse_i.h b/lib/fuse_i.h
> >> index 6d63c9fd2149eb4ae3b0e0170640a4ce2eed4705..93ab7ac2fadf9395af70487c7626cc57c2948d56 100644
> >> --- a/lib/fuse_i.h
> >> +++ b/lib/fuse_i.h
> >> @@ -112,6 +112,10 @@ struct fuse_session {
> >>  
> >>  	/* synchronous FUSE_INIT support */
> >>  	bool want_sync_init;
> >> +	pthread_t init_thread;
> >> +	int init_error;
> >> +	_Atomic bool terminate_mount_worker;
> >> +	int init_wakeup_fd;
> >>  
> >>  	/* io_uring */
> >>  	struct fuse_session_uring uring;
> >> @@ -221,7 +225,11 @@ void fuse_chan_put(struct fuse_chan *ch);
> >>  /* Mount-related functions */
> >>  void fuse_mount_version(void);
> >>  void fuse_kern_unmount(const char *mountpoint, int fd);
> >> +int fuse_kern_mount_get_base_mnt_opts(struct mount_opts *mo, char **mnt_optsp);
> >>  int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo);
> >> +int fuse_kern_mount_prepare(const char *mountpoint, struct mount_opts *mo);
> >> +int fuse_kern_do_mount(const char *mountpoint, struct mount_opts *mo,
> >> +		       const char *mnt_opts);
> >>  
> >>  int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
> >>  			       int count);
> >> @@ -255,6 +263,14 @@ int fuse_session_loop_mt_312(struct fuse_session *se, struct fuse_loop_config *c
> >>   */
> >>  int fuse_loop_cfg_verify(struct fuse_loop_config *config);
> >>  
> >> +/**
> >> + * Check if daemonization is set.
> >> + *
> >> + * @return true if set, false otherwise
> >> + */
> >> +bool fuse_daemonize_set(void);
> >> +
> >> +
> >>  
> >>  /*
> >>   * This can be changed dynamically on recent kernels through the
> >> diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
> >> index 626233df20f49fa89cd9327f94340169d7061f75..b10def03f3666757d312f87f177a560483691d6f 100644
> >> --- a/lib/fuse_lowlevel.c
> >> +++ b/lib/fuse_lowlevel.c
> >> @@ -4230,6 +4230,7 @@ fuse_session_new_versioned(struct fuse_args *args,
> >>  		goto out1;
> >>  	}
> >>  	se->fd = -1;
> >> +	se->init_wakeup_fd = -1;
> >>  	se->conn.max_write = FUSE_DEFAULT_MAX_PAGES_LIMIT * getpagesize();
> >>  	se->bufsize = se->conn.max_write + FUSE_BUFFER_HEADER_SIZE;
> >>  	se->conn.max_readahead = UINT_MAX;
> >> @@ -4402,6 +4403,167 @@ int fuse_session_custom_io_30(struct fuse_session *se,
> >>  }
> >>  
> >>  #if defined(HAVE_NEW_MOUNT_API)
> >> +
> >> +/* Worker thread for synchronous FUSE_INIT */
> >> +static void *session_sync_init_worker(void *data)
> >> +{
> >> +	struct fuse_session *se = (struct fuse_session *)data;
> >> +	struct fuse_buf fbuf = {
> >> +		.mem = NULL,
> >> +	};
> >> +	struct pollfd pfds[2];
> >> +	int res;
> >> +
> >> +	pfds[0].fd = se->fd;
> >> +	pfds[0].events = POLLIN;
> >> +	pfds[0].revents = 0;
> >> +	pfds[1].fd = se->init_wakeup_fd;
> >> +	pfds[1].events = POLLIN;
> >> +	pfds[1].revents = 0;
> >> +
> >> +	/*
> >> +	 * Process requests until mount completes. With SELinux there may be
> >> +	 * additional requests (like getattr) after FUSE_INIT before mount
> >> +	 * returns.
> >> +	 */
> >> +	while (!atomic_load(&se->terminate_mount_worker)) {
> > 
> > We don't ever *read* the init_wakeup_fd event, so I wonder if the
> > _Atomic flag here is really needed?  I gather we need acquire semantics
> > or something?
> 
> My lazyness. I had quickly updated the code yesterday morning to use
> poll and eventfd, because Kevin noticed issues with xfstests. Before it
> was a regular thread stopped with pthread_cancel and then actually
> terminated the thread when it already might have fetched a post-mount
> request - the request then got never handled.
> 
> Next on my list is to look into the fuse-io-uring issues that Kevin also
> reports with this patch series.

Heh, well, at least it isn't pthread_cancel anymore :)

> > 
> >> +		res = poll(pfds, 2, -1);
> >> +		if (res == -1) {
> >> +			if (errno == EINTR)
> >> +				continue;
> >> +			se->init_error = -errno;
> >> +			break;
> >> +		}
> >> +
> >> +		if (pfds[1].revents & POLLIN)
> >> +			break;
> >> +
> >> +		if (pfds[0].revents & POLLIN) {
> >> +			res = fuse_session_receive_buf_internal(se, &fbuf, NULL);
> >> +			if (res == -EINTR)
> >> +				continue;
> >> +			if (res <= 0) {
> >> +				se->init_error = res < 0 ? res : -EINVAL;
> >> +				break;
> >> +			}
> >> +
> >> +			fuse_session_process_buf_internal(se, &fbuf, NULL);
> >> +		}
> >> +	}
> >> +
> >> +	fuse_buf_free(&fbuf);
> >> +	return NULL;
> >> +}
> >> +
> >> +/* Enable synchronous FUSE_INIT and start worker thread */
> >> +static int session_start_sync_init(struct fuse_session *se, int fd)
> >> +{
> >> +	int err;
> >> +	int res;
> >> +
> >> +	if (!se->want_sync_init &&
> >> +		(se->uring.enable && !fuse_daemonize_set())) {
> >> +		if (se->debug)
> >> +			fuse_log(FUSE_LOG_DEBUG,
> >> +					"fuse: sync init not enabled\n");
> >> +		return 0;
> >> +	}
> >> +
> >> +	/* Try to enable synchronous FUSE_INIT */
> >> +	res = ioctl(fd, FUSE_DEV_IOC_SYNC_INIT);
> >> +	if (res) {
> >> +		/* ENOTTY means kernel doesn't support sync init - not an error */
> >> +		if (errno != ENOTTY) {
> >> +			fuse_log(
> >> +				FUSE_LOG_ERR,
> >> +				"fuse: failed to enable sync init: %s\n",
> >> +				strerror(errno));
> >> +		} else if (se->debug) {
> >> +			fuse_log(
> >> +				FUSE_LOG_DEBUG,
> >> +				"fuse: kernel doesn't support sync init\n");
> >> +		}
> >> +		return -ENOTTY;
> >> +	}
> >> +
> >> +	if (se->debug)
> >> +		fuse_log(FUSE_LOG_DEBUG,
> >> +				"fuse: synchronous FUSE_INIT enabled\n");
> >> +
> >> +	se->init_error = 0;
> >> +	se->terminate_mount_worker = false;
> >> +
> >> +	se->init_wakeup_fd = eventfd(0, EFD_CLOEXEC);
> >> +	if (se->init_wakeup_fd == -1) {
> >> +		fuse_log(
> >> +			FUSE_LOG_ERR,
> >> +			"fuse: failed to create eventfd for init worker: %s\n",
> >> +			strerror(errno));
> >> +		return -EIO;
> >> +	}
> >> +
> >> +	err = pthread_create(&se->init_thread, NULL,
> >> +				session_sync_init_worker, se);
> >> +	if (err != 0) {
> >> +		fuse_log(
> >> +			FUSE_LOG_ERR,
> >> +			"fuse: failed to create init worker thread: %s\n",
> >> +			strerror(err));
> >> +		close(se->init_wakeup_fd);
> >> +		se->init_wakeup_fd = -1;
> >> +		return -EIO;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +/* Wait for synchronous FUSE_INIT to complete */
> >> +static int session_wait_sync_init_completion(struct fuse_session *se)
> >> +{
> >> +	void *retval;
> >> +	int err;
> >> +	uint64_t val = 1;
> >> +
> >> +	if (se->init_thread == 0)
> > 
> > pthread_t is supposed to be an opaque datatype, so "0" could be a valid
> > value for a running thread.  For that matter, it could be a struct.  I
> > think you have to have a separate flag (or just use init_wakeup_fd >= 0)
> > to determine if we're doing a synchronous init.
> 
> Ah right. I'm using se->init_wakeup_fd as you suggested.

<nod>

> > 
> >> +		return 0;
> >> +
> >> +	se->terminate_mount_worker = true;
> >> +
> >> +	if (se->init_wakeup_fd != -1) {
> >> +		ssize_t res = write(se->init_wakeup_fd, &val, sizeof(val));
> >> +
> >> +		if (res != sizeof(val)) {
> >> +			fuse_log(FUSE_LOG_ERR,
> >> +				 "fuse: failed to signal init worker: %s\n",
> >> +				 strerror(errno));
> >> +		}
> >> +	}
> >> +
> >> +	err = pthread_join(se->init_thread, &retval);
> >> +	if (err != 0) {
> >> +		fuse_log(FUSE_LOG_ERR, "fuse: failed to join init worker thread: %s\n",
> >> +			 strerror(err));
> >> +		return -1;
> >> +	}
> >> +
> >> +	if (se->init_wakeup_fd != -1) {
> >> +		close(se->init_wakeup_fd);
> >> +		se->init_wakeup_fd = -1;
> >> +	}
> >> +
> >> +	if (se->init_error != 0) {
> >> +		fuse_log(FUSE_LOG_ERR, "fuse: init worker failed: %d\n", se->init_error);
> > 
> > Could you strerror(-se->init_error) to give the user a real error
> > message?
> > 
> >> +		return -1;
> >> +	}
> >> +
> >> +	if (fuse_session_exited(se)) {
> >> +		fuse_log(FUSE_LOG_ERR, "FUSE_INIT failed: session exited\n");
> >> +		return -1;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >>  /* Only linux supports sync FUSE_INIT so far */
> >>  static int fuse_session_mount_new_api(struct fuse_session *se,
> >>  				      const char *mountpoint)
> >> @@ -4414,8 +4576,7 @@ static int fuse_session_mount_new_api(struct fuse_session *se,
> >>  
> >>  	res = fuse_kern_mount_get_base_mnt_opts(se->mo, &mnt_opts);
> >>  	if (res == -1) {
> >> -		fuse_log(FUSE_LOG_ERR,
> >> -			 "fuse: failed to get base mount options\n");
> >> +		fuse_log(FUSE_LOG_ERR, "fuse: failed to get base mount options\n");
> > 
> > Unrelated change?
> 
> Removed here.
> 
> > 
> >>  		err = -EIO;
> >>  		goto err;
> >>  	}
> >> @@ -4427,6 +4588,17 @@ static int fuse_session_mount_new_api(struct fuse_session *se,
> >>  		goto err;
> >>  	}
> >>  
> >> +	/*
> >> +	 * Enable synchronous FUSE_INIT and start worker thread, sync init
> >> +	 * failure is not an error
> >> +	 */
> >> +	se->fd = fd;
> >> +	err = session_start_sync_init(se, fd);
> >> +	if (err) {
> >> +		/* ENOTTY means kernel doesn't support sync init - not an error */
> >> +		if (err != -ENOTTY)
> >> +			goto err;
> >> +	}
> > 
> > Perhaps session_start_sync_init should not return ENOTTY, since you
> > already check in session_wait_sync_init_completion if the synchronous
> > init worker has been started?
> 
> Good idea, done.
> 
> > 
> >>  	snprintf(fd_opt, sizeof(fd_opt), "fd=%i", fd);
> >>  	if (fuse_opt_add_opt(&mnt_opts_with_fd, mnt_opts) == -1 ||
> >>  	    fuse_opt_add_opt(&mnt_opts_with_fd, fd_opt) == -1) {
> >> @@ -4436,13 +4608,16 @@ static int fuse_session_mount_new_api(struct fuse_session *se,
> >>  
> >>  	err = fuse_kern_fsmount_mo(mountpoint, se->mo, mnt_opts_with_fd);
> >>  err:
> >> -	if (err) {
> >> +	if (err < 0) {
> >>  		if (fd >= 0)
> >>  			close(fd);
> >>  		fd = -1;
> >>  		se->fd = -1;
> >>  		se->error = -errno;
> >>  	}
> >> +	/* Wait for synchronous FUSE_INIT to complete */
> >> +	if (session_wait_sync_init_completion(se) < 0)
> >> +		fuse_log(FUSE_LOG_ERR, "fuse: sync init completion failed\n");
> >>  
> >>  	free(mnt_opts);
> >>  	free(mnt_opts_with_fd);
> >> @@ -4452,8 +4627,8 @@ err:
> >>  static int fuse_session_mount_new_api(struct fuse_session *se,
> >>  				      const char *mountpoint)
> >>  {
> >> -	(void)se;
> >> -	(void)mountpoint;
> >> +	(void) se;
> >> +	(void) mountpoint;
> >>  
> >>  	return -1;
> >>  }
> >> @@ -4825,3 +5000,10 @@ void fuse_session_stop_teardown_watchdog(void *data)
> >>  	pthread_join(tt->thread_id, NULL);
> >>  	fuse_tt_destruct(tt);
> >>  }
> >> +
> >> +void fuse_session_want_sync_init(struct fuse_session *se)
> >> +{
> >> +	if (se == NULL)
> >> +		return;
> >> +	se->want_sync_init = true;
> >> +}
> >> diff --git a/lib/mount.c b/lib/mount.c
> >> index 30fd4d2f9bbb84c817b2363b2075456acd1c1255..12df49d9109cf918cc41aa75c5fdf84231d4d5ff 100644
> >> --- a/lib/mount.c
> >> +++ b/lib/mount.c
> >> @@ -30,6 +30,7 @@
> >>  #include <sys/socket.h>
> >>  #include <sys/un.h>
> >>  #include <sys/wait.h>
> >> +#include <sys/ioctl.h>
> >>  
> >>  #include "fuse_mount_compat.h"
> >>  
> >> @@ -529,8 +530,8 @@ int fuse_kern_fsmount_mo(const char *mnt, struct mount_opts *mo,
> >>   * Returns: 0 on success, -1 on failure,
> >>   *          FUSE_MOUNT_FALLBACK_NEEDED if fusermount should be used
> >>   */
> >> -static int fuse_kern_do_mount(const char *mnt, struct mount_opts *mo,
> >> -				  const char *mnt_opts)
> >> +int fuse_kern_do_mount(const char *mnt, struct mount_opts *mo,
> >> +		       const char *mnt_opts)
> >>  {
> >>  	char *source = NULL;
> >>  	char *type = NULL;
> >> diff --git a/lib/mount_fsmount.c b/lib/mount_fsmount.c
> >> index cba998bc60c783a5edc0c16570f7e5512b7f1253..f1fec790bb80f8815d485a068dc7efdff1746309 100644
> >> --- a/lib/mount_fsmount.c
> >> +++ b/lib/mount_fsmount.c
> >> @@ -287,8 +287,9 @@ int fuse_kern_fsmount(const char *mnt, unsigned long flags, int blkdev,
> >>  	/* Try to open filesystem context */
> >>  	fsfd = fsopen(type, FSOPEN_CLOEXEC);
> >>  	if (fsfd == -1) {
> >> -		fprintf(stderr, "fuse: fsopen(%s) failed: %s\n", type,
> >> -			strerror(errno));
> >> +		if (errno != EPERM)
> >> +			fprintf(stderr, "fuse: fsopen(%s) failed: %s\n", type,
> >> +				strerror(errno));
> > 
> > More unrelated changes?
> 
> Right, moved one patch up.

<nod>

--D

  reply	other threads:[~2026-03-24 22:50 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-23 17:44 [PATCH 00/19] libfuse: Add support for synchronous init Bernd Schubert
2026-03-23 17:44 ` [PATCH 01/19] ci-build: Add environment logging Bernd Schubert
2026-03-23 17:44 ` [PATCH 02/19] Add 'STRCPY' to the checkpatch ignore option Bernd Schubert
2026-03-23 21:03   ` Darrick J. Wong
2026-03-23 17:44 ` [PATCH 03/19] checkpatch.pl: Add _Atomic to $Attribute patttern Bernd Schubert
2026-03-23 21:09   ` Darrick J. Wong
2026-03-23 17:44 ` [PATCH 04/19] Add a new daemonize API Bernd Schubert
2026-03-23 22:28   ` Darrick J. Wong
2026-03-24 17:36     ` Bernd Schubert
2026-03-24 22:20       ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 05/19] Sync fuse_kernel.h with linux-6.18 Bernd Schubert
2026-03-23 21:16   ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 06/19] mount.c: Split fuse_mount_sys to prepare privileged sync FUSE_INIT Bernd Schubert
2026-03-23 22:34   ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 07/19] Add FUSE_MOUNT_FALLBACK_NEEDED define for -2 mount errors Bernd Schubert
2026-03-23 22:36   ` Darrick J. Wong
2026-03-24 18:03     ` Bernd Schubert
2026-03-23 17:45 ` [PATCH 08/19] Refactor mount code / move common functions to mount_util.c Bernd Schubert
2026-03-23 22:40   ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 09/19] Move mount flags to mount_i.h Bernd Schubert
2026-03-23 22:45   ` Darrick J. Wong
2026-03-24 18:40     ` Bernd Schubert
2026-03-23 17:45 ` [PATCH 10/19] conftest.py: Add more valgrind filter patterns Bernd Schubert
2026-03-23 17:45 ` [PATCH 11/19] Add support for the new linux mount API Bernd Schubert
2026-03-23 23:42   ` Darrick J. Wong
2026-03-24 20:16     ` Bernd Schubert
2026-03-24 22:46       ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 12/19] fuse mount: Support synchronous FUSE_INIT (privileged daemon) Bernd Schubert
2026-03-24  0:03   ` Darrick J. Wong
2026-03-24 20:42     ` Bernd Schubert
2026-03-24 22:50       ` Darrick J. Wong [this message]
2026-03-25  7:52         ` Bernd Schubert
2026-03-25 16:42           ` Darrick J. Wong
2026-03-26 19:32         ` Bernd Schubert
2026-03-26 22:33           ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 13/19] Add fuse_session_set_debug() to enable debug output without foreground Bernd Schubert
2026-03-24  0:04   ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 14/19] Move more generic mount code to mount_util.{c,h} Bernd Schubert
2026-03-24  0:06   ` Darrick J. Wong
2026-03-24 20:57     ` Bernd Schubert
2026-03-23 17:45 ` [PATCH 15/19] Split the fusermount do_mount function Bernd Schubert
2026-03-24  0:14   ` Darrick J. Wong
2026-03-24 21:05     ` Bernd Schubert
2026-03-24 22:53       ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 16/19] fusermount: Refactor extract_x_options Bernd Schubert
2026-03-24  0:18   ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 17/19] Make fusermount work bidirectional for sync init Bernd Schubert
2026-03-24 19:35   ` Darrick J. Wong
2026-03-24 21:24     ` Bernd Schubert
2026-03-24 22:59       ` Darrick J. Wong
2026-03-25 19:48         ` Bernd Schubert
2026-03-25 22:03           ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 18/19] New mount API: Filter out "user=" Bernd Schubert
2026-03-24 19:51   ` Darrick J. Wong
2026-03-24 20:01     ` Bernd Schubert
2026-03-24 23:02       ` Darrick J. Wong
2026-03-23 17:45 ` [PATCH 19/19] Add support for sync-init of unprivileged daemons Bernd Schubert
2026-03-24 20:21   ` Darrick J. Wong
2026-03-24 21:53     ` Bernd Schubert
2026-03-24 23:13       ` Darrick J. Wong
2026-03-24  0:19 ` [PATCH 00/19] libfuse: Add support for synchronous init Darrick J. Wong

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=20260324225012.GY6202@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox