All of lore.kernel.org
 help / color / mirror / Atom feed
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>
Subject: Re: [PATCH v2 04/25] Add a new daemonize API
Date: Mon, 30 Mar 2026 10:55:48 -0700	[thread overview]
Message-ID: <20260330175548.GS6202@frogsfrogsfrogs> (raw)
In-Reply-To: <20260326-fuse-init-before-mount-v2-4-b1ca8fcbf60f@bsbernd.com>

On Thu, Mar 26, 2026 at 10:34:37PM +0100, Bernd Schubert wrote:
> Existing example/ file systems do the fuse_daemonize() after
> fuse_session_mount() - i.e. after the mount point is already
> established. Though, these example/ daemons do not start
> extra threads and do not need network initialization either.
> 
> fuse_daemonize() also does not allow to return notification
> from the forked child to the parent.
> 
> Complex fuse file system daemons often want the order of
> 1) fork - parent watches, child does the work
> 
> Child:
>     2) start extra threads and system initialization (like network
>        connection and RDMA memory registration) from the fork child.
>     3) Start the fuse session after everything else succeeded
> 
> Parent:
>     Report child initialization success or failure
> 
> A new API is introduced to overcome the limitations of
> fuse_daemonize()
> 
> fuse_daemonize_start() - fork, but foreground process does not
> terminate yet and watches the background.
> 
> fuse_daemonize_success() / fuse_daemonize_fail() - background
> daemon signals to the foreground process success or failure.
> 
> fuse_daemonize_active() - helper function for the high level
> interface, which needs to handle both APIs. fuse_daemonize()
> is called within fuse_main(), which now needs to know if the caller
> actually already used the new API itself.
> 
> The object 'struct fuse_daemonize *' is allocated dynamically
> and stored a global variable in fuse_daemonize.c, because
> - high level fuse_main_real_versioned() needs to know
> if already daemonized
> - high level daemons do not have access to struct fuse_session
> - FUSE_SYNC_INIT in later commits can only be done if the new
> API (or a file system internal) daemonization is used.
> 
> Signed-off-by: Bernd Schubert <bernd@bsbernd.com>

Only a couple nitpicks now...

> ---
>  example/passthrough_hp.cc   |  18 ++-
>  include/fuse_daemonize.h    |  74 +++++++++++
>  include/meson.build         |   3 +-
>  lib/fuse_daemonize.c        | 292 ++++++++++++++++++++++++++++++++++++++++++++
>  lib/fuse_i.h                |   4 +-
>  lib/fuse_lowlevel.c         |   3 +
>  lib/fuse_versionscript      |   4 +
>  lib/helper.c                |  13 +-
>  lib/meson.build             |   3 +-
>  test/test_want_conversion.c |   1 +
>  10 files changed, 404 insertions(+), 11 deletions(-)
> 
> diff --git a/example/passthrough_hp.cc b/example/passthrough_hp.cc
> index 9f795c5546ee8312e1393c5b8fcebfd77724fb49..bad435077697e8832cf5a5195c17f2f873f2dfe6 100644
> --- a/example/passthrough_hp.cc
> +++ b/example/passthrough_hp.cc
> @@ -55,6 +55,7 @@
>  #include <errno.h>
>  #include <ftw.h>
>  #include <fuse_lowlevel.h>
> +#include <fuse_daemonize.h>
>  #include <inttypes.h>
>  #include <string.h>
>  #include <sys/file.h>
> @@ -243,6 +244,9 @@ static void sfs_init(void *userdata, fuse_conn_info *conn)
>  
>  	/* Try a large IO by default */
>  	conn->max_write = 4 * 1024 * 1024;
> +
> +	/* Signal successful init to parent */
> +	fuse_daemonize_success();
>  }
>  
>  static void sfs_getattr(fuse_req_t req, fuse_ino_t ino, fuse_file_info *fi)
> @@ -1580,6 +1584,7 @@ int main(int argc, char *argv[])
>  {
>  	struct fuse_loop_config *loop_config = NULL;
>  	void *teardown_watchog = NULL;
> +	unsigned int daemon_flags = 0;
>  
>  	// Parse command line options
>  	auto options{ parse_options(argc, argv) };
> @@ -1638,10 +1643,14 @@ int main(int argc, char *argv[])
>  
>  	fuse_loop_cfg_set_clone_fd(loop_config, fs.clone_fd);
>  
> -	if (fuse_session_mount(se, argv[2]) != 0)
> +	/* Start daemonization before mount so parent can report mount failure */
> +	if (fs.foreground)
> +		daemon_flags |= FUSE_DAEMONIZE_NO_BACKGROUND;
> +	if (fuse_daemonize_start(daemon_flags) != 0)
>  		goto err_out3;
>  
> -	fuse_daemonize(fs.foreground);

Should the old fuse_daemonize() no-op (or complain) if the client has
already called fuse_daemonize_start()?  You've done something like that
in fuse_main_real_versioned, so maybe it should be automatic.

> +	if (fuse_session_mount(se, argv[2]) != 0)
> +		goto err_out4;
>  
>  	if (!fs.foreground)
>  		fuse_log_enable_syslog("passthrough-hp", LOG_PID | LOG_CONS,
> @@ -1650,7 +1659,7 @@ int main(int argc, char *argv[])
>  	teardown_watchog = fuse_session_start_teardown_watchdog(
>  		se, fs.root.stop_timeout_secs, NULL, NULL);
>  	if (teardown_watchog == NULL)
> -		goto err_out3;
> +		goto err_out4;
>  
>  	if (options.count("single"))
>  		ret = fuse_session_loop(se);
> @@ -1659,6 +1668,9 @@ int main(int argc, char *argv[])
>  
>  	fuse_session_unmount(se);
>  
> +err_out4:
> +	if (fuse_daemonize_is_active())
> +		fuse_daemonize_fail(ret);
>  err_out3:
>  	fuse_remove_signal_handlers(se);
>  err_out2:
> diff --git a/include/fuse_daemonize.h b/include/fuse_daemonize.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..c35dddd668b399535c53b44ab06c65fc0b3ddefa
> --- /dev/null
> +++ b/include/fuse_daemonize.h
> @@ -0,0 +1,74 @@
> +/*
> + * FUSE: Filesystem in Userspace
> + * Copyright (C) 2026 Bernd Schubert <bsbernd.com>
> + *
> + * This program can be distributed under the terms of the GNU LGPLv2.
> + * See the file COPYING.LIB.
> + *
> + */
> +
> +#ifndef FUSE_DAEMONIZE_H_
> +#define FUSE_DAEMONIZE_H_
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * Flags for fuse_daemonize_start()
> + */
> +#define FUSE_DAEMONIZE_NO_CHDIR      (1 << 0)
> +#define FUSE_DAEMONIZE_NO_BACKGROUND (1 << 1)
> +
> +/**
> + * Start daemonization process.
> + *
> + * Unless FUSE_DAEMONIZE_NO_BACKGROUND is set, this forks the process.
> + * The parent waits for a signal from the child via fuse_daemonize_success()
> + * or fuse_daemonize_fail().
> + * The child returns from this call and continues setup.
> + *
> + * Unless FUSE_DAEMONIZE_NO_CHDIR is set, changes directory to "/".
> + *
> + * Must be called before fuse_session_mount().
> + *
> + * @param flags combination of FUSE_DAEMONIZE_* flags
> + * @return 0 on success, negative errno on error
> + */
> +int fuse_daemonize_start(unsigned int flags);
> +
> +/**
> + * Signal daemonization success to parent and cleanup.
> + */
> +void fuse_daemonize_success(void);
> +
> +/**
> + * Signal daemonization failure to parent and cleanup.
> + *
> + * @param err error code to pass to parent

I think this should say explicitly that @err will become the exit code
of the parent process.

It might also be useful to state that except for fuse_daemonize_start,
all the other APIs must only be called from the child process.

--D

> + */
> +void fuse_daemonize_fail(int err);
> +
> +/**
> + * Check if daemonization is active and waiting for signal.
> + *
> + * @return true if active, false otherwise
> + */
> +bool fuse_daemonize_is_active(void);
> +
> +/**
> + * Set mounted flag.
> + *
> + * Called from fuse_session_mount().
> + */
> +void fuse_daemonize_set_mounted(void);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* FUSE_DAEMONIZE_H_ */
> +
> diff --git a/include/meson.build b/include/meson.build
> index bf671977a5a6a9142bd67aceabd8a919e3d968d0..cfbaf52ac5d84369e92948c631e2fcfdd04ac2eb 100644
> --- a/include/meson.build
> +++ b/include/meson.build
> @@ -1,4 +1,5 @@
>  libfuse_headers = [ 'fuse.h', 'fuse_common.h', 'fuse_lowlevel.h',
> -	            'fuse_opt.h', 'cuse_lowlevel.h', 'fuse_log.h' ]
> +	            'fuse_opt.h', 'cuse_lowlevel.h', 'fuse_log.h',
> +	            'fuse_daemonize.h' ]
>  
>  install_headers(libfuse_headers, subdir: 'fuse3')
> diff --git a/lib/fuse_daemonize.c b/lib/fuse_daemonize.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..865acad7db56dbe5ed8a1bee52e7353627e89b75
> --- /dev/null
> +++ b/lib/fuse_daemonize.c
> @@ -0,0 +1,292 @@
> +/*
> + * FUSE: Filesystem in Userspace
> + * Copyright (C) 2026 Bernd Schubert <bsbernd.com>
> + *
> + * This program can be distributed under the terms of the GNU LGPLv2.
> + * See the file COPYING.LIB.
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include "fuse_daemonize.h"
> +
> +#include <fcntl.h>
> +#include <poll.h>
> +#include <pthread.h>
> +#include <stdatomic.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <unistd.h>
> +#include <stdbool.h>
> +#include <errno.h>
> +
> +/**
> + * Status values for fuse_daemonize_success() and fuse_daemonize_fail()
> + */
> +#define FUSE_DAEMONIZE_SUCCESS 0
> +#define FUSE_DAEMONIZE_FAILURE 1
> +
> +/* Private/internal data  */
> +struct fuse_daemonize {
> +	unsigned int flags;
> +	int signal_pipe_wr;	/* write end for signaling parent */
> +	int death_pipe_rd;	/* read end, POLLHUP when parent dies */
> +	int stop_pipe_rd;	/* read end for stop signal */
> +	int stop_pipe_wr;	/* write end for stop signal */
> +	pthread_t watcher;
> +	bool watcher_started;
> +	_Atomic bool active;
> +	_Atomic bool daemonized;
> +	_Atomic bool mounted;
> +};
> +
> +/* Global daemonization object pointer */
> +static struct fuse_daemonize daemonize = {
> +	.signal_pipe_wr = -1,
> +	.death_pipe_rd = -1,
> +	.stop_pipe_rd = -1,
> +	.stop_pipe_wr = -1,
> +};
> +
> +/* Watcher thread: polls for parent death or stop signal */
> +static void *parent_watcher_thread(void *arg)
> +{
> +	struct fuse_daemonize *di = arg;
> +	struct pollfd pfd[2];
> +
> +	pfd[0].fd = di->death_pipe_rd;
> +	pfd[0].events = POLLIN;
> +	pfd[1].fd = di->stop_pipe_rd;
> +	pfd[1].events = POLLIN;
> +
> +	while (1) {
> +		int rc = poll(pfd, 2, -1);
> +
> +		if (rc < 0)
> +			continue;
> +
> +		/* Parent died - death pipe write end closed */
> +		if (pfd[0].revents & (POLLHUP | POLLERR))
> +			_exit(EXIT_FAILURE);
> +
> +		/* Stop signal received */
> +		if (pfd[1].revents & POLLIN)
> +			break;
> +	}
> +	return NULL;
> +}
> +
> +static int start_parent_watcher(struct fuse_daemonize *daemonize)
> +{
> +	int rc;
> +
> +	rc = pthread_create(&daemonize->watcher, NULL, parent_watcher_thread,
> +			    daemonize);
> +	if (rc != 0) {
> +		fprintf(stderr, "fuse_daemonize: pthread_create: %s\n",
> +			strerror(rc));
> +		return -rc;
> +	}
> +	daemonize->watcher_started = true;
> +	return 0;
> +}
> +
> +static void stop_parent_watcher(struct fuse_daemonize *daemonize)
> +{
> +	char byte = 0;
> +
> +	if (daemonize && daemonize->watcher_started) {
> +		/* Signal watcher to stop */
> +		if (write(daemonize->stop_pipe_wr, &byte, 1) != 1)
> +			perror("fuse_daemonize: stop write");
> +		pthread_join(daemonize->watcher, NULL);
> +		daemonize->watcher_started = false;
> +	}
> +}
> +
> +static int daemonize_child(struct fuse_daemonize *daemonize)
> +{
> +	int stop_pipe[2], err = 0;
> +
> +	if (pipe(stop_pipe) == -1) {
> +		err = -errno;
> +		perror("fuse_daemonize_start: stop pipe");
> +		return err;
> +	}
> +	daemonize->stop_pipe_rd = stop_pipe[0];
> +	daemonize->stop_pipe_wr = stop_pipe[1];
> +
> +	if (setsid() == -1) {
> +		err = -errno;
> +		perror("fuse_daemonize_start: setsid");
> +		goto err_close_stop;
> +	}
> +
> +	/* Close stdin immediately */
> +	int nullfd = open("/dev/null", O_RDWR, 0);
> +
> +	if (nullfd != -1) {
> +		(void)dup2(nullfd, 0);
> +		if (nullfd > 0)
> +			close(nullfd);
> +	}
> +
> +	/* Start watcher thread to detect parent death */
> +	err = start_parent_watcher(daemonize);
> +	if (err)
> +		goto err_close_stop;
> +
> +	daemonize->daemonized = true;
> +	return 0;
> +
> +err_close_stop:
> +	close(daemonize->stop_pipe_rd);
> +	close(daemonize->stop_pipe_wr);
> +	return err;
> +}
> +
> +/* Fork and daemonize. Returns 0 in child, never returns in parent. */
> +static int do_daemonize(struct fuse_daemonize *daemonize)
> +{
> +	int signal_pipe[2], death_pipe[2], err;
> +
> +	if (pipe(signal_pipe) == -1) {
> +		err = -errno;
> +		perror("fuse_daemonize_start: signal pipe");
> +		return err;
> +	}
> +
> +	if (pipe(death_pipe) == -1) {
> +		err = -errno;
> +		perror("fuse_daemonize_start: death pipe");
> +		close(signal_pipe[0]);
> +		close(signal_pipe[1]);
> +		return err;
> +	}
> +
> +	switch (fork()) {
> +	case -1:
> +		err = -errno;
> +		perror("fuse_daemonize_start: fork");
> +		close(signal_pipe[0]);
> +		close(signal_pipe[1]);
> +		close(death_pipe[0]);
> +		close(death_pipe[1]);
> +		return err;
> +
> +	case 0:
> +		/* Child: signal write end, death read end */
> +		close(signal_pipe[0]);
> +		close(death_pipe[1]);
> +		daemonize->signal_pipe_wr = signal_pipe[1];
> +		daemonize->death_pipe_rd = death_pipe[0];
> +		return daemonize_child(daemonize);
> +
> +	default: {
> +		/* Parent: signal read end, death write end (kept open) */
> +		int status;
> +		ssize_t res;
> +
> +		close(signal_pipe[1]);
> +		close(death_pipe[0]);
> +
> +		res = read(signal_pipe[0], &status, sizeof(status));
> +		close(signal_pipe[0]);
> +		close(death_pipe[1]);
> +
> +		if (res != sizeof(status))
> +			_exit(EXIT_FAILURE);
> +		_exit(status);
> +	}
> +	}
> +}
> +
> +int fuse_daemonize_start(unsigned int flags)
> +{
> +	struct fuse_daemonize *dm = &daemonize;
> +	int err = 0;
> +
> +	dm->flags = flags;
> +	dm->signal_pipe_wr = -1;
> +	dm->death_pipe_rd = -1;
> +	dm->stop_pipe_rd = -1;
> +	dm->stop_pipe_wr = -1;
> +	dm->active = true;
> +
> +	if (!(flags & FUSE_DAEMONIZE_NO_CHDIR))
> +		(void)chdir("/");
> +
> +	if (!(flags & FUSE_DAEMONIZE_NO_BACKGROUND))
> +		err = do_daemonize(dm);
> +
> +	return err;
> +}
> +
> +static void close_if_valid(int *fd)
> +{
> +	if (*fd != -1) {
> +		close(*fd);
> +		*fd = -1;
> +	}
> +}
> +
> +static void fuse_daemonize_signal(int status)
> +{
> +	struct fuse_daemonize *dm = &daemonize;
> +	int rc;
> +
> +	/* Warn because there might be races */
> +	if (status == FUSE_DAEMONIZE_SUCCESS && !dm->mounted)
> +		fprintf(stderr, "fuse daemonize success without being mounted\n");
> +
> +	dm->active = false;
> +
> +	/* Stop watcher before signaling - parent will exit after this */
> +	stop_parent_watcher(dm);
> +
> +	/* Signal status to parent */
> +	if (dm->signal_pipe_wr != -1) {
> +		rc = write(dm->signal_pipe_wr, &status, sizeof(status));
> +		if (rc != sizeof(status))
> +			fprintf(stderr, "%s: write failed\n", __func__);
> +	}
> +
> +	/* Redirect stdout/stderr to /dev/null on success */
> +	if (status == FUSE_DAEMONIZE_SUCCESS && dm->daemonized) {
> +		int nullfd = open("/dev/null", O_RDWR, 0);
> +
> +		if (nullfd != -1) {
> +			(void)dup2(nullfd, 1);
> +			(void)dup2(nullfd, 2);
> +			if (nullfd > 2)
> +				close(nullfd);
> +		}
> +	}
> +
> +	close_if_valid(&dm->signal_pipe_wr);
> +	close_if_valid(&dm->death_pipe_rd);
> +	close_if_valid(&dm->stop_pipe_rd);
> +	close_if_valid(&dm->stop_pipe_wr);
> +}
> +
> +void fuse_daemonize_success(void)
> +{
> +	fuse_daemonize_signal(FUSE_DAEMONIZE_SUCCESS);
> +}
> +
> +void fuse_daemonize_fail(int err)
> +{
> +	fuse_daemonize_signal(err);
> +}
> +
> +bool fuse_daemonize_is_active(void)
> +{
> +	return daemonize.daemonized || daemonize.active;
> +}
> +
> +void fuse_daemonize_set_mounted(void)
> +{
> +	daemonize.mounted = true;
> +}
> diff --git a/lib/fuse_i.h b/lib/fuse_i.h
> index 65d2f68f7f30918a3c3ee4d473796cb013428a8f..9e3c5dc5021e210a2778e975a37ab609af324010 100644
> --- a/lib/fuse_i.h
> +++ b/lib/fuse_i.h
> @@ -17,7 +17,6 @@
>  #include <semaphore.h>
>  #include <stdint.h>
>  #include <stdbool.h>
> -#include <errno.h>
>  #include <stdatomic.h>
>  
>  #define MIN(a, b) \
> @@ -110,6 +109,9 @@ struct fuse_session {
>  	/* true if reading requests from /dev/fuse are handled internally */
>  	bool buf_reallocable;
>  
> +	/* synchronous FUSE_INIT support */
> +	bool want_sync_init;
> +
>  	/* io_uring */
>  	struct fuse_session_uring uring;
>  
> diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
> index 3234f0ce3b246a4c2c40dc0757177de91b6608b2..ccff6a768f0b8c32469abda9405ff29623f3fff7 100644
> --- a/lib/fuse_lowlevel.c
> +++ b/lib/fuse_lowlevel.c
> @@ -19,6 +19,7 @@
>  #include "mount_util.h"
>  #include "util.h"
>  #include "fuse_uring_i.h"
> +#include "fuse_daemonize.h"
>  
>  #include <pthread.h>
>  #include <stdatomic.h>
> @@ -4451,6 +4452,8 @@ int fuse_session_mount(struct fuse_session *se, const char *_mountpoint)
>  	/* Save mountpoint */
>  	se->mountpoint = mountpoint;
>  
> +	fuse_daemonize_set_mounted();
> +
>  	return 0;
>  
>  error_out:
> diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
> index cce09610316f4b0b1d6836dd0e63686342b70037..dc6ed0135fb8d82937c756c3fb04a7fcb48fe1f4 100644
> --- a/lib/fuse_versionscript
> +++ b/lib/fuse_versionscript
> @@ -227,6 +227,10 @@ FUSE_3.19 {
>  		fuse_session_start_teardown_watchdog;
>  		fuse_session_stop_teardown_watchdog;
>  		fuse_lowlevel_notify_prune;
> +		fuse_daemonize_start;
> +		fuse_daemonize_success;
> +		fuse_daemonize_fail;
> +		fuse_daemonize_is_active;
>  } FUSE_3.18;
>  
>  # Local Variables:
> diff --git a/lib/helper.c b/lib/helper.c
> index 5c13b93a473181f027eba01e0bfefd78875ede3e..35285be19aa0cc390a432d16701b9eefa16ec12a 100644
> --- a/lib/helper.c
> +++ b/lib/helper.c
> @@ -15,6 +15,7 @@
>  #include "fuse_misc.h"
>  #include "fuse_opt.h"
>  #include "fuse_lowlevel.h"
> +#include "fuse_daemonize.h"
>  #include "mount_util.h"
>  
>  #include <stdio.h>
> @@ -352,17 +353,19 @@ int fuse_main_real_versioned(int argc, char *argv[],
>  		goto out1;
>  	}
>  
> +	struct fuse_session *se = fuse_get_session(fuse);
>  	if (fuse_mount(fuse,opts.mountpoint) != 0) {
>  		res = 4;
>  		goto out2;
>  	}
>  
> -	if (fuse_daemonize(opts.foreground) != 0) {
> -		res = 5;
> -		goto out3;
> +	if (!fuse_daemonize_is_active()) {
> +		/* Avoid daemonizing if we are already daemonized by the newer API */
> +		if (fuse_daemonize(opts.foreground) != 0) {
> +			res = 5;
> +			goto out3;
> +		}
>  	}
> -
> -	struct fuse_session *se = fuse_get_session(fuse);
>  	if (fuse_set_signal_handlers(se) != 0) {
>  		res = 6;
>  		goto out3;
> diff --git a/lib/meson.build b/lib/meson.build
> index fcd95741c9d3748fa01d9ec52b417aca66745f26..5bd449ebffe7c9229df904d647d990c6c47f80b5 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -2,7 +2,8 @@ libfuse_sources = ['fuse.c', 'fuse_i.h', 'fuse_loop.c', 'fuse_loop_mt.c',
>                     'fuse_lowlevel.c', 'fuse_misc.h', 'fuse_opt.c',
>                     'fuse_signals.c', 'buffer.c', 'cuse_lowlevel.c',
>                     'helper.c', 'modules/subdir.c', 'mount_util.c',
> -                   'fuse_log.c', 'compat.c', 'util.c', 'util.h' ]
> +                   'fuse_log.c', 'compat.c', 'util.c', 'util.h',
> +                   'fuse_daemonize.c' ]
>  
>  if host_machine.system().startswith('linux')
>     libfuse_sources += [ 'mount.c' ]
> diff --git a/test/test_want_conversion.c b/test/test_want_conversion.c
> index db731edbfe1be8230ae16b422f798603b4a3bb82..48e6dd2dc6084425a0462bba000563c6083160be 100644
> --- a/test/test_want_conversion.c
> +++ b/test/test_want_conversion.c
> @@ -8,6 +8,7 @@
>  #include <inttypes.h>
>  #include <stdbool.h>
>  #include <err.h>
> +#include <errno.h>
>  
>  static void print_conn_info(const char *prefix, struct fuse_conn_info *conn)
>  {
> 
> -- 
> 2.43.0
> 
> 

  parent reply	other threads:[~2026-03-30 17:55 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 [this message]
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
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=20260330175548.GS6202@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=bernd@bsbernd.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.