public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: Bernd Schubert <bernd@bsbernd.com>
To: linux-fsdevel@vger.kernel.org
Cc: Miklos Szeredi <miklos@szeredi.hu>,
	 Joanne Koong <joannelkoong@gmail.com>,
	 "Darrick J. Wong" <djwong@kernel.org>,
	Bernd Schubert <bernd@bsbernd.com>,
	 Bernd Schubert <bschubert@ddn.com>
Subject: [PATCH 19/19] Add support for sync-init of unprivileged daemons
Date: Mon, 23 Mar 2026 18:45:14 +0100	[thread overview]
Message-ID: <20260323-fuse-init-before-mount-v1-19-a52d3040af69@bsbernd.com> (raw)
In-Reply-To: <20260323-fuse-init-before-mount-v1-0-a52d3040af69@bsbernd.com>

From: Bernd Schubert <bschubert@ddn.com>

This makes use of the bidirectional fusermount. Added is
doc/README.mount, which explains the new bidirectional
communication with fusermount.

Signed-off-by: Bernd Schubert <bschubert@ddn.com>
---
 doc/README.mount     |  86 ++++++++++++++++++++++++
 doc/README.sync-init | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/fuse_lowlevel.c  | 115 ++++++++++++++++++++++++++------
 lib/mount.c          | 126 ++++++++++++++++++++++++++++++++++-
 lib/mount_i_linux.h  |   7 ++
 util/fusermount.c    |   2 -
 6 files changed, 494 insertions(+), 26 deletions(-)

diff --git a/doc/README.mount b/doc/README.mount
new file mode 100644
index 0000000000000000000000000000000000000000..526382ad8a5f6b405a7cb1927b79bacd6c2c2c5c
--- /dev/null
+++ b/doc/README.mount
@@ -0,0 +1,86 @@
+FUSE Mount API Flowcharts
+=========================
+
+Old Mount API
+-------------
+
+fuse_kern_mount()
+  |
+  +-- fuse_mount_sys()
+  |     +-- Try direct mount → mount() syscall
+  |     +-- On EPERM: fuse_mount_fusermount()
+  |           +-- socketpair()
+  |           +-- spawn fusermount3 (no --sync-init)
+  |           +-- fusermount3: open /dev/fuse, mount(), send fd
+  |           +-- receive_fd() → return fd
+  |
+  +-- Worker threads started AFTER mount
+  └─> FUSE_INIT asynchronous (queued in kernel)
+
+
+New Mount API - Privileged Mount
+---------------------------------
+
+fuse_session_mount_new_api()
+  |
+  +-- fuse_kern_mount_prepare() → open /dev/fuse → fd
+  |
+  +-- session_start_sync_init(se, fd)
+  |     +-- ioctl(fd, FUSE_DEV_IOC_SYNC_INIT)
+  |     +-- pthread_create(worker) → ready to process FUSE_INIT
+  |
+  +-- fuse_kern_fsmount_mo()
+  |     +-- fsopen/fsconfig/fsmount (BLOCKS until FUSE_INIT completes)
+  |     +-- Worker processes FUSE_INIT during fsmount()
+  |     +-- move_mount()
+  |
+  +-- session_wait_sync_init_completion(se) → pthread_join
+  └─> return fd
+
+
+New Mount API - EPERM Fallback (fusermount3 with sync-init)
+------------------------------------------------------------
+
+fuse_session_mount_new_api()
+  |
+  +-- fuse_kern_mount_prepare() → open /dev/fuse → fd1
+  |
+  +-- session_start_sync_init(se, fd1)
+  |     +-- ioctl(fd1, FUSE_DEV_IOC_SYNC_INIT)
+  |     +-- pthread_create(worker) → ready with fd1
+  |
+  +-- fuse_kern_fsmount_mo() → EPERM
+  |
+  +-- *** FALLBACK TO FUSERMOUNT3 WITH SYNC-INIT ***
+  |
+  +-- session_wait_sync_init_completion(se)
+  |     +-- pthread_cancel/join → terminate worker with wrong fd1
+  |
+  +-- close(fd1)
+  |
+  +-- fuse_mount_fusermount_sync_init()  [NEW]
+  |     +-- socketpair()
+  |     +-- spawn fusermount3 --sync-init
+  |     +-- fusermount3: open /dev/fuse → fd2, send fd2
+  |     +-- receive_fd() → fd2
+  |     +-- fusermount3 waits for signal
+  |     └─> return fd2, sock
+  |
+  +-- session_start_sync_init(se, fd2)
+  |     +-- ioctl(fd2, FUSE_DEV_IOC_SYNC_INIT)
+  |     +-- pthread_create(worker) → ready with fd2
+  |
+  +-- send_proceed_signal(sock)  [NEW]
+  |     +-- send(sock, "\0", 1) → signal fusermount3
+  |
+  +-- fusermount3: mount() (BLOCKS)
+  |     +-- Kernel sends FUSE_INIT to fd2
+  |     +-- Worker processes FUSE_INIT
+  |     +-- mount() returns
+  |
+  +-- close(sock)
+  |
+  +-- session_wait_sync_init_completion(se) → pthread_join
+  |
+  └─> return fd2
+
diff --git a/doc/README.sync-init b/doc/README.sync-init
new file mode 100644
index 0000000000000000000000000000000000000000..44e47a2eef2c45026abaa19562537eef37f256b9
--- /dev/null
+++ b/doc/README.sync-init
@@ -0,0 +1,184 @@
+FUSE Synchronous vs Asynchronous FUSE_INIT
+============================================
+
+This document explains the difference between asynchronous and synchronous
+FUSE_INIT processing, and when each mode is used.
+
+
+Overview
+--------
+
+FUSE_INIT is the initial handshake between the kernel FUSE module and the
+userspace filesystem daemon. During this handshake, the kernel and daemon
+negotiate capabilities, protocol version, and various feature flags.
+
+Asynchronous FUSE_INIT (Traditional Behavior)
+----------------------------------------------
+
+In the traditional asynchronous mode:
+
+1. mount() syscall completes and returns to caller
+2. Filesystem appears mounted to the system
+3. FUSE daemon starts worker threads
+4. Worker threads process FUSE_INIT request
+5. Filesystem becomes fully operational
+
+Timeline:
+    mount() -----> returns
+                   |
+                   v
+            FUSE_INIT sent
+                   |
+                   v
+            daemon processes FUSE_INIT
+                   |
+                   v
+            filesystem ready
+
+Limitations:
+
+1. **No early requests**: The kernel cannot send requests (like getxattr)
+   during the mount() syscall. This breaks SELinux, which needs to query
+   extended attributes on the root inode immediately upon mounting.
+
+2. **Daemonization timing**: With the old fuse_daemonize() API, the daemon
+   must call it AFTER mount, because there's no way to report mount failures
+   to the parent process if daemonization happens first.
+
+3. **No custom root inode**: The root inode ID is hardcoded to FUSE_ROOT_ID (1)
+   because FUSE_INIT hasn't been processed yet when the mount completes.
+
+4. **Thread startup after mount**: io_uring threads and other worker threads
+   can only start after mount() returns, not before.
+
+
+Synchronous FUSE_INIT (New Behavior)
+-------------------------------------
+
+Kernel support: Linux kernel commit dfb84c330794 (v6.18+)
+libfuse support: libfuse 3.19+
+
+In synchronous mode:
+
+1. FUSE daemon opens /dev/fuse
+2. Daemon calls ioctl(fd, FUSE_DEV_IOC_SYNC_INIT)
+3. Daemon starts worker thread
+4. Daemon calls mount() syscall
+5. Kernel sends FUSE_INIT during mount() - mount() blocks
+6. Worker thread processes FUSE_INIT while mount() is blocked
+7. Worker thread may process additional requests (getxattr, etc.)
+8. mount() syscall completes and returns
+9. Filesystem is fully operational
+
+Timeline:
+    open /dev/fuse
+         |
+         v
+    ioctl(FUSE_DEV_IOC_SYNC_INIT)
+         |
+         v
+    start worker thread
+         |
+         v
+    mount() -----> blocks
+         |         |
+         |         v
+         |    FUSE_INIT sent
+         |         |
+         |         v
+         |    worker processes FUSE_INIT
+         |         |
+         |         v
+         |    (possible getxattr, etc.)
+         |         |
+         +-------> returns
+                   |
+                   v
+            filesystem ready
+
+Advantages:
+
+1. **SELinux support**: The kernel can send getxattr requests during mount()
+   to query security labels on the root inode.
+
+2. **Early daemonization**: The daemon can fork BEFORE mount using the new
+   fuse_daemonize_start()/signal() API, and report mount failures to the
+   parent process.
+
+3. **Custom root inode**: The daemon can specify a custom root inode ID
+   during FUSE_INIT, before mount() completes.
+
+4. **Thread startup before mount**: io_uring threads and worker threads
+   start before mount(), ensuring they're ready to handle requests.
+
+5. **Better error reporting**: Mount failures and initialization errors
+   can be properly reported to the parent process when using the new
+   daemonization API.
+
+
+When Synchronous FUSE_INIT is Used
+-----------------------------------
+
+libfuse automatically enables synchronous FUSE_INIT when:
+
+1. The application calls fuse_session_want_sync_init(), OR
+2. The new daemonization API is used (fuse_daemonize_start() was called)
+
+Synchronous FUSE_INIT requires:
+- Kernel support (commit dfb84c330794 or later)
+- Worker thread started before mount()
+- ioctl(FUSE_DEV_IOC_SYNC_INIT) succeeds
+
+If the kernel doesn't support synchronous FUSE_INIT, libfuse automatically
+falls back to asynchronous mode.
+
+
+Implementation Details
+----------------------
+
+The synchronous FUSE_INIT implementation uses a worker thread:
+
+- **session_sync_init_worker()**: Thread function that polls /dev/fuse
+  and processes FUSE_INIT and any subsequent requests until mount completes.
+
+- **session_start_sync_init()**: Creates the worker thread before mount().
+  Calls ioctl(FUSE_DEV_IOC_SYNC_INIT) to enable kernel support.
+
+- **session_wait_sync_init_completion()**: Waits for the worker thread
+  to complete after mount() returns. Checks for errors.
+
+The worker thread processes requests in a loop until se->terminate_mount_worker
+is set, which happens after mount() completes successfully.
+
+
+Compatibility
+-------------
+
+Synchronous FUSE_INIT is fully backward compatible:
+
+- Old kernels: ioctl returns ENOTTY, libfuse falls back to async mode
+- Old applications: Continue to work with async FUSE_INIT
+- New applications on old kernels: Graceful fallback to async mode
+- New applications on new kernels: Automatic sync mode when appropriate
+
+
+Example: Enabling Synchronous FUSE_INIT
+----------------------------------------
+
+Explicit request:
+    struct fuse_session *se = fuse_session_new(...);
+    fuse_session_want_sync_init(se);
+    fuse_session_mount(se, mountpoint);
+
+Automatic (with new daemonization API):
+    fuse_daemonize_start(0);  // Triggers sync init automatically
+    fuse_session_mount(se, mountpoint);
+
+
+See Also
+--------
+
+- doc/README.daemonize - New daemonization API documentation
+- doc/README.fusermount - Synchronous FUSE_INIT protocol with fusermount3
+- doc/README.mount - Mount implementation details
+
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index a7293a3898c37c3877eadf965d310ae2aa5cc2d1..da966217ed841744a20bee60de8ae615d1015b47 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -41,6 +41,7 @@
 #include <assert.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
+#include <sys/wait.h>
 #include <stdalign.h>
 #include <poll.h>
 
@@ -4551,6 +4552,8 @@ static int session_wait_sync_init_completion(struct fuse_session *se)
 		se->init_wakeup_fd = -1;
 	}
 
+	se->init_thread = 0;
+
 	if (se->init_error != 0) {
 		fuse_log(FUSE_LOG_ERR, "fuse: init worker failed: %d\n", se->init_error);
 		return -1;
@@ -4564,56 +4567,125 @@ static int session_wait_sync_init_completion(struct fuse_session *se)
 	return 0;
 }
 
-/* Only linux supports sync FUSE_INIT so far */
+/*
+ * Mount using the new Linux mount API (fsopen/fsconfig/fsmount/move_mount)
+ * Sync-init is only supported with the new API, as the mount might hang
+ * in case of daemon crash during FUSE_INIT. That also means once the sync init
+ * ioctl succeed fallback is not allowed anymore.
+ * Returns: fd on success, -1 on failure
+ */
 static int fuse_session_mount_new_api(struct fuse_session *se,
-				      const char *mountpoint)
+				      const char *mountpoint, bool *fall_back)
 {
 	int fd = -1;
+	int sock_fd = -1;
+	pid_t fusermount_pid = -1;
 	int res, err;
 	char *mnt_opts = NULL;
 	char *mnt_opts_with_fd = NULL;
 	char fd_opt[32];
 
 	res = fuse_kern_mount_get_base_mnt_opts(se->mo, &mnt_opts);
+	err = -EIO;
 	if (res == -1) {
 		fuse_log(FUSE_LOG_ERR, "fuse: failed to get base mount options\n");
-		err = -EIO;
 		goto err;
 	}
 
 	fd = fuse_kern_mount_prepare(mountpoint, se->mo);
 	if (fd == -1) {
 		fuse_log(FUSE_LOG_ERR, "Mount preparation failed.\n");
-		err = -EIO;
 		goto err;
 	}
 
-	/*
-	 * Enable synchronous FUSE_INIT and start worker thread, sync init
-	 * failure is not an error
-	 */
+	*fall_back = true;
 	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;
+	} else {
+		*fall_back = false;
 	}
+
+
 	snprintf(fd_opt, sizeof(fd_opt), "fd=%i", fd);
+	err = -ENOMEM;
 	if (fuse_opt_add_opt(&mnt_opts_with_fd, mnt_opts) == -1 ||
 	    fuse_opt_add_opt(&mnt_opts_with_fd, fd_opt) == -1) {
-		err = -ENOMEM;
 		goto err;
 	}
 
+	/* Try to mount directly */
 	err = fuse_kern_fsmount_mo(mountpoint, se->mo, mnt_opts_with_fd);
+
+	/* If mount failed with EPERM, fall back to fusermount3 with sync-init */
+	if (err < 0 && errno == EPERM) {
+		if (se->debug)
+			fuse_log(FUSE_LOG_DEBUG,
+				 "fuse: privileged mount failed with EPERM, falling back to fusermount3\n");
+
+		/* Terminate worker thread with wrong fd */
+		if (session_wait_sync_init_completion(se) < 0)
+			fuse_log(FUSE_LOG_ERR, "fuse: sync init completion failed\n");
+
+		/* Close the privileged fd */
+		close(fd);
+		fd = -1;
+		se->fd = -1;
+
+		/* Call fusermount3 with --sync-init */
+		err = -ENOTSUP;
+		fd = mount_fusermount_obtain_fd(mountpoint, se->mo, mnt_opts,
+						&sock_fd, &fusermount_pid);
+		if (fd < 0) {
+			fuse_log(
+				FUSE_LOG_ERR,
+				"fuse: fusermount3 sync-init failed\n");
+			goto err;
+		}
+
+		/* Start worker thread with correct fd from fusermount3 */
+		se->fd = fd;
+		err = session_start_sync_init(se, fd);
+		if (err) {
+			if (err != -ENOTTY) {
+				fuse_log(
+					FUSE_LOG_ERR,
+					"fuse: failed to start sync init worker\n");
+				goto err_with_sock;
+			}
+		} else {
+			*fall_back = false;
+		}
+
+		/* Send proceed signal and wait for mount result */
+		err = fuse_fusermount_proceed_mnt(sock_fd);
+		if (err < 0) {
+			err = -EIO;
+			goto err_with_sock;
+		}
+	} else if (err < 0) {
+		/* Mount failed with non-EPERM error, bail out */
+		goto err;
+	}
+
+err_with_sock:
+	if (sock_fd >= 0) {
+		close(sock_fd);
+		/* Reap fusermount3 child process to prevent zombie */
+		if (fusermount_pid > 0)
+			waitpid(fusermount_pid, NULL, 0);
+	}
 err:
 	if (err < 0) {
+		/* Close fd first to unblock worker thread */
 		if (fd >= 0)
 			close(fd);
 		fd = -1;
 		se->fd = -1;
-		se->error = -errno;
+		se->error = err;
 	}
 	/* Wait for synchronous FUSE_INIT to complete */
 	if (session_wait_sync_init_completion(se) < 0)
@@ -4625,10 +4697,11 @@ err:
 }
 #else
 static int fuse_session_mount_new_api(struct fuse_session *se,
-				      const char *mountpoint)
+				      const char *mountpoint, bool *fall_back)
 {
 	(void) se;
 	(void) mountpoint;
+	(void) fall_back;
 
 	return -1;
 }
@@ -4638,6 +4711,7 @@ int fuse_session_mount(struct fuse_session *se, const char *_mountpoint)
 {
 	int fd;
 	char *mountpoint;
+	bool fall_back;
 
 	if (_mountpoint == NULL) {
 		fuse_log(FUSE_LOG_ERR, "Invalid null-ptr mountpoint!\n");
@@ -4681,21 +4755,18 @@ int fuse_session_mount(struct fuse_session *se, const char *_mountpoint)
 		return 0;
 	}
 
-	/* new linux mount api */
-	fd = fuse_session_mount_new_api(se, mountpoint);
-	if (fd >= 0)
-		goto out;
+	/* new linux mount api (and sync init) */
+	fd = fuse_session_mount_new_api(se, mountpoint, &fall_back);
 
 	/* fall back to old API */
-	se->error = 0; /* reset error of new api */
-	fd = fuse_kern_mount(mountpoint, se->mo);
-	if (fd < 0)
-		goto error_out;
+	if (fall_back && fd < 0) {
+		se->error = 0; /* reset error of new api */
+		fd = fuse_kern_mount(mountpoint, se->mo);
+		if (fd < 0)
+			goto error_out;
+	}
 
-out:
 	se->fd = fd;
-
-	/* Save mountpoint */
 	se->mountpoint = mountpoint;
 
 	return 0;
diff --git a/lib/mount.c b/lib/mount.c
index 263b05051c236458b830c40181bce7f494803800..985938ea0be3e1affad19adad527a31ac2ca6034 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -41,6 +41,7 @@
 #define FUSERMOUNT_PROG		"fusermount3"
 #define FUSE_COMMFD_ENV		"_FUSE_COMMFD"
 #define FUSE_COMMFD2_ENV	"_FUSE_COMMFD2"
+#define ARG_FD_ENTRY_SIZE	30
 
 enum {
 	KEY_KERN_FLAG,
@@ -313,7 +314,7 @@ static int setup_auto_unmount(const char *mountpoint, int quiet)
 		return -1;
 	}
 
-	char arg_fd_entry[30];
+	char arg_fd_entry[ARG_FD_ENTRY_SIZE];
 	snprintf(arg_fd_entry, sizeof(arg_fd_entry), "%i", fds[0]);
 	setenv(FUSE_COMMFD_ENV, arg_fd_entry, 1);
 	/*
@@ -386,7 +387,7 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo,
 		return -1;
 	}
 
-	char arg_fd_entry[30];
+	char arg_fd_entry[ARG_FD_ENTRY_SIZE];
 	snprintf(arg_fd_entry, sizeof(arg_fd_entry), "%i", fds[0]);
 	setenv(FUSE_COMMFD_ENV, arg_fd_entry, 1);
 	/*
@@ -446,6 +447,127 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo,
 	return fd;
 }
 
+/*
+ * Mount using fusermount3 with --sync-init flag for bidirectional fd exchange
+ * Used by new mount API when privileged mount fails with EPERM
+ *
+ * Returns: fd on success, -1 on failure
+ * On success, *sock_fd_out contains the socket fd for signaling fusermount3
+ */
+int mount_fusermount_obtain_fd(const char *mountpoint, struct mount_opts *mo,
+			       const char *opts, int *sock_fd_out,
+			       pid_t *pid_out)
+{
+	int fds[2];
+	pid_t pid;
+	int res;
+	char arg_fd_entry[ARG_FD_ENTRY_SIZE];
+	posix_spawn_file_actions_t action;
+	int fd, status;
+
+	(void)mo;
+
+	if (!mountpoint) {
+		fuse_log(FUSE_LOG_ERR, "fuse: missing mountpoint parameter\n");
+		return -1;
+	}
+
+	res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
+	if (res == -1) {
+		fuse_log(FUSE_LOG_ERR, "Running %s: socketpair() failed: %s\n",
+			 FUSERMOUNT_PROG, strerror(errno));
+		return -1;
+	}
+
+	snprintf(arg_fd_entry, sizeof(arg_fd_entry), "%i", fds[0]);
+	setenv(FUSE_COMMFD_ENV, arg_fd_entry, 1);
+	snprintf(arg_fd_entry, sizeof(arg_fd_entry), "%i", fds[1]);
+	setenv(FUSE_COMMFD2_ENV, arg_fd_entry, 1);
+
+	char const *const argv[] = {
+		FUSERMOUNT_PROG,
+		"--sync-init",
+		"-o", opts ? opts : "",
+		"--",
+		mountpoint,
+		NULL,
+	};
+
+	posix_spawn_file_actions_init(&action);
+	posix_spawn_file_actions_addclose(&action, fds[1]);
+	status = fusermount_posix_spawn(&action, argv, &pid);
+	posix_spawn_file_actions_destroy(&action);
+
+	if (status != 0) {
+		close(fds[0]);
+		close(fds[1]);
+		return -1;
+	}
+
+	close(fds[0]);
+
+	fd = receive_fd(fds[1]);
+	if (fd < 0) {
+		close(fds[1]);
+		waitpid(pid, NULL, 0);
+		return -1;
+	}
+
+	fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+	/* Return socket fd for later signaling */
+	*sock_fd_out = fds[1];
+	*pid_out = pid;
+
+	return fd;
+}
+
+/*
+ * Send proceed signal to fusermount3 and wait for mount result
+ * Returns: 0 on success, -1 on failure
+ */
+int fuse_fusermount_proceed_mnt(int sock_fd)
+{
+	char buf = '\0';
+	ssize_t res;
+
+	/* Send proceed signal */
+	do {
+		res = send(sock_fd, &buf, 1, 0);
+	} while (res == -1 && errno == EINTR);
+
+	if (res != 1) {
+		fuse_log(FUSE_LOG_ERR, "fuse: failed to send proceed signal: %s\n",
+			 strerror(errno));
+		return -1;
+	}
+
+	/* Wait for mount result from fusermount3 (4-byte error code) */
+	int32_t status;
+
+	do {
+		res = recv(sock_fd, &status, sizeof(status), 0);
+	} while (res == -1 && errno == EINTR);
+
+	if (res != sizeof(status)) {
+		if (res == 0)
+			fuse_log(FUSE_LOG_ERR, "fuse: fusermount3 closed connection\n");
+		else
+			fuse_log(FUSE_LOG_ERR, "fuse: failed to receive mount status: %s\n",
+				 strerror(errno));
+		return -1;
+	}
+
+	if (status != 0) {
+		if (status != -EPERM)
+			fuse_log(FUSE_LOG_ERR, "fuse: fusermount3 mount failed: %s\n",
+				 strerror(-status));
+		return -1;
+	}
+
+	return 0;
+}
+
 #ifndef O_CLOEXEC
 #define O_CLOEXEC 0
 #endif
diff --git a/lib/mount_i_linux.h b/lib/mount_i_linux.h
index 867105019fa57576682091d1a650302f31e450b3..2a3386443afa73a508454124332527c35a184398 100644
--- a/lib/mount_i_linux.h
+++ b/lib/mount_i_linux.h
@@ -76,5 +76,12 @@ int fuse_kern_fsmount_mo(const char *mnt, struct mount_opts *mo,
 			 const char *mnt_opts);
 char *fuse_mnt_build_source(const struct mount_opts *mo);
 char *fuse_mnt_build_type(const struct mount_opts *mo);
+int mount_fusermount_obtain_fd(const char *mountpoint,
+					   struct mount_opts *mo,
+					   const char *opts, int *sock_fd_out,
+					   pid_t *pid_out);
+
+int fuse_fusermount_proceed_mnt(int sock_fd);
+
 
 #endif /* FUSE_MOUNT_I_H_ */
diff --git a/util/fusermount.c b/util/fusermount.c
index 808b4afd89ceb49273c944d43bffe5033e27549b..e6d973687bb4eef0d7e6626a1028cc32dd177e89 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -1397,7 +1397,6 @@ struct mount_context {
 	char *source;
 	char *mnt_opts;
 	char *x_opts;
-	const char *type;
 };
 
 /*
@@ -1521,7 +1520,6 @@ static int mount_fuse_finish_fsmount(const char *mnt, const char *opts,
 
 	/* Store results in context */
 	ctx->source = mp.source;
-	ctx->type = mp.type;
 	ctx->mnt_opts = final_mnt_opts;
 	*type = mp.type;
 

-- 
2.43.0


  parent reply	other threads:[~2026-03-23 18:19 UTC|newest]

Thread overview: 59+ 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
2026-03-25  7:52         ` Bernd Schubert
2026-03-25 16:42           ` 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 ` Bernd Schubert [this message]
2026-03-24 20:21   ` [PATCH 19/19] Add support for sync-init of unprivileged daemons 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=20260323-fuse-init-before-mount-v1-19-a52d3040af69@bsbernd.com \
    --to=bernd@bsbernd.com \
    --cc=bschubert@ddn.com \
    --cc=djwong@kernel.org \
    --cc=joannelkoong@gmail.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