public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: tytso@mit.edu
Cc: bpf@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-ext4@vger.kernel.org, miklos@szeredi.hu, bernd@bsbernd.com,
	joannelkoong@gmail.com, neal@gompa.dev
Subject: [PATCH 2/8] fuse4fs: enable safe service mode
Date: Mon, 23 Feb 2026 15:46:45 -0800	[thread overview]
Message-ID: <177188745992.3944907.2684603430792948652.stgit@frogsfrogsfrogs> (raw)
In-Reply-To: <177188745924.3944907.12406087337118974135.stgit@frogsfrogsfrogs>

From: Darrick J. Wong <djwong@kernel.org>

Make it possible to run fuse4fs as a safe systemd service, wherein the
fuse server only has access to the fds that we pass in.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 MCONFIG.in                  |    1 
 configure                   |  135 +++++++++++++++++++++
 configure.ac                |   45 +++++++
 fuse4fs/Makefile.in         |   40 ++++++
 fuse4fs/fuse4fs.c           |  276 ++++++++++++++++++++++++++++++++++++++++++-
 fuse4fs/fuse4fs.socket.in   |   17 +++
 fuse4fs/fuse4fs@.service.in |   99 +++++++++++++++
 lib/config.h.in             |    3 
 util/subst.conf.in          |    2 
 9 files changed, 606 insertions(+), 12 deletions(-)
 create mode 100644 fuse4fs/fuse4fs.socket.in
 create mode 100644 fuse4fs/fuse4fs@.service.in


diff --git a/MCONFIG.in b/MCONFIG.in
index d66e2f3bc1d552..2fcb71d898fef7 100644
--- a/MCONFIG.in
+++ b/MCONFIG.in
@@ -42,6 +42,7 @@ HAVE_CROND = @have_crond@
 CROND_DIR = @crond_dir@
 HAVE_SYSTEMD = @have_systemd@
 SYSTEMD_SYSTEM_UNIT_DIR = @systemd_system_unit_dir@
+HAVE_FUSE_SERVICE = @have_fuse_service@
 
 @SET_MAKE@
 
diff --git a/configure b/configure
index 5db59894242aab..15e9fd92eaf6e7 100755
--- a/configure
+++ b/configure
@@ -697,6 +697,8 @@ UNI_DIFF_OPTS
 SEM_INIT_LIB
 FUSE4FS_CMT
 FUSE2FS_CMT
+fuse_service_socket_dir
+have_fuse_service
 FUSE_LIB
 fuse3_LIBS
 fuse3_CFLAGS
@@ -929,6 +931,7 @@ with_libiconv_prefix
 with_libintl_prefix
 enable_largefile
 with_libarchive
+with_fuse_service_socket_dir
 enable_fuse2fs
 enable_fuse4fs
 enable_lto
@@ -1652,6 +1655,8 @@ Optional Packages:
   --with-libintl-prefix[=DIR]  search for libintl in DIR/include and DIR/lib
   --without-libintl-prefix     don't search for libintl in includedir and libdir
   --without-libarchive    disable use of libarchive
+  --with-fuse-service-socket-dir[=DIR]
+                          Create fuse3 filesystem service sockets in DIR.
   --with-multiarch=ARCH   specify the multiarch triplet
   --with-udev-rules-dir[=DIR]
                           Install udev rules into DIR.
@@ -14746,6 +14751,136 @@ printf "%s\n" "#define HAVE_FUSE_LOWLEVEL 1" >>confdefs.h
 
 fi
 
+have_fuse_service=
+fuse_service_socket_dir=
+if test -n "$have_fuse_lowlevel"
+then
+
+# Check whether --with-fuse_service_socket_dir was given.
+if test ${with_fuse_service_socket_dir+y}
+then :
+  withval=$with_fuse_service_socket_dir;
+else case e in #(
+  e) with_fuse_service_socket_dir=yes ;;
+esac
+fi
+
+	if test "x${with_fuse_service_socket_dir}" != "xno"
+then :
+
+		if test "x${with_fuse_service_socket_dir}" = "xyes"
+then :
+
+
+pkg_failed=no
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fuse3" >&5
+printf %s "checking for fuse3... " >&6; }
+
+if test -n "$fuse3_CFLAGS"; then
+    pkg_cv_fuse3_CFLAGS="$fuse3_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fuse3\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "fuse3") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_fuse3_CFLAGS=`$PKG_CONFIG --cflags "fuse3" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$fuse3_LIBS"; then
+    pkg_cv_fuse3_LIBS="$fuse3_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fuse3\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "fuse3") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_fuse3_LIBS=`$PKG_CONFIG --libs "fuse3" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+                fuse3_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "fuse3" 2>&1`
+        else
+                fuse3_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "fuse3" 2>&1`
+        fi
+        # Put the nasty error message in config.log where it belongs
+        echo "$fuse3_PKG_ERRORS" >&5
+
+
+				with_fuse_service_socket_dir=""
+
+elif test $pkg_failed = untried; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+
+				with_fuse_service_socket_dir=""
+
+else
+        fuse3_CFLAGS=$pkg_cv_fuse3_CFLAGS
+        fuse3_LIBS=$pkg_cv_fuse3_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+
+				with_fuse_service_socket_dir="$($PKG_CONFIG --variable=service_socket_dir fuse3)"
+
+fi
+
+
+fi
+		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fuse3 service socket dir" >&5
+printf %s "checking for fuse3 service socket dir... " >&6; }
+		fuse_service_socket_dir="${with_fuse_service_socket_dir}"
+		if test -n "${fuse_service_socket_dir}"
+then :
+
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${fuse_service_socket_dir}" >&5
+printf "%s\n" "${fuse_service_socket_dir}" >&6; }
+			have_fuse_service="yes"
+
+else case e in #(
+  e)
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+			have_fuse_service="no"
+		   ;;
+esac
+fi
+
+fi
+fi
+
+
+if test "$have_fuse_service" = yes
+then
+
+printf "%s\n" "#define HAVE_FUSE_SERVICE 1" >>confdefs.h
+
+fi
+
 FUSE2FS_CMT=
 # Check whether --enable-fuse2fs was given.
 if test ${enable_fuse2fs+y}
diff --git a/configure.ac b/configure.ac
index f1bffa88b80fa4..8aa25ca7585f32 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1478,6 +1478,51 @@ then
 		  [Define to 1 if fuse supports lowlevel API])
 fi
 
+dnl
+dnl Check if the FUSE library tells us where to put fs service sockets
+dnl
+have_fuse_service=
+fuse_service_socket_dir=
+if test -n "$have_fuse_lowlevel"
+then
+	AC_ARG_WITH([fuse_service_socket_dir],
+	  [AS_HELP_STRING([--with-fuse-service-socket-dir@<:@=DIR@:>@],
+		  [Create fuse3 filesystem service sockets in DIR.])],
+	  [],
+	  [with_fuse_service_socket_dir=yes])
+	AS_IF([test "x${with_fuse_service_socket_dir}" != "xno"],
+	  [
+		AS_IF([test "x${with_fuse_service_socket_dir}" = "xyes"],
+		  [
+			PKG_CHECK_MODULES([fuse3], [fuse3],
+			  [
+				with_fuse_service_socket_dir="$($PKG_CONFIG --variable=service_socket_dir fuse3)"
+			  ], [
+				with_fuse_service_socket_dir=""
+			  ])
+			m4_pattern_allow([^PKG_(MAJOR|MINOR|BUILD|REVISION)$])
+		  ])
+		AC_MSG_CHECKING([for fuse3 service socket dir])
+		fuse_service_socket_dir="${with_fuse_service_socket_dir}"
+		AS_IF([test -n "${fuse_service_socket_dir}"],
+		  [
+			AC_MSG_RESULT(${fuse_service_socket_dir})
+			have_fuse_service="yes"
+		  ],
+		  [
+			AC_MSG_RESULT(no)
+			have_fuse_service="no"
+		  ])
+	  ],
+	  [])
+fi
+AC_SUBST(have_fuse_service)
+AC_SUBST(fuse_service_socket_dir)
+if test "$have_fuse_service" = yes
+then
+	AC_DEFINE(HAVE_FUSE_SERVICE, 1, [Define to 1 if fuse supports service])
+fi
+
 dnl
 dnl Check if fuse2fs is actually built.
 dnl
diff --git a/fuse4fs/Makefile.in b/fuse4fs/Makefile.in
index 31afbd8def1de6..119fb1f37ad1ae 100644
--- a/fuse4fs/Makefile.in
+++ b/fuse4fs/Makefile.in
@@ -17,6 +17,13 @@ UMANPAGES=
 @FUSE4FS_CMT@UPROGS+=fuse4fs
 @FUSE4FS_CMT@UMANPAGES+=fuse4fs.1
 
+ifeq ($(HAVE_SYSTEMD),yes)
+SERVICE_FILES	+= fuse4fs.socket fuse4fs@.service
+INSTALLDIRS_TGT	+= installdirs-systemd
+INSTALL_TGT	+= install-systemd
+UNINSTALL_TGT	+= uninstall-systemd
+endif
+
 FUSE4FS_OBJS=	fuse4fs.o journal.o recovery.o revoke.o
 
 PROFILED_FUSE4FS_OJBS=	profiled/fuse4fs.o profiled/journal.o \
@@ -54,7 +61,7 @@ DEPEND_CFLAGS = -I$(top_srcdir)/e2fsck
 @PROFILE_CMT@	$(Q) $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
 
 all:: profiled $(SPROGS) $(UPROGS) $(USPROGS) $(SMANPAGES) $(UMANPAGES) \
-	$(FMANPAGES) $(LPROGS)
+	$(FMANPAGES) $(LPROGS) $(SERVICE_FILES)
 
 all-static::
 
@@ -71,6 +78,14 @@ fuse4fs: $(FUSE4FS_OBJS) $(DEPLIBS) $(DEPLIBBLKID) $(DEPLIBUUID) \
 		$(LIBFUSE) $(LIBBLKID) $(LIBUUID) $(LIBEXT2FS) $(LIBINTL) \
 		$(CLOCK_GETTIME_LIB) $(SYSLIBS) $(LIBS_E2P)
 
+%.socket: %.socket.in $(DEP_SUBSTITUTE)
+	$(E) "	SUBST $@"
+	$(Q) $(SUBSTITUTE_UPTIME) $< $@
+
+%.service: %.service.in $(DEP_SUBSTITUTE)
+	$(E) "	SUBST $@"
+	$(Q) $(SUBSTITUTE_UPTIME) $< $@
+
 journal.o: $(srcdir)/../debugfs/journal.c
 	$(E) "	CC $<"
 	$(Q) $(CC) -c $(JOURNAL_CFLAGS) -I$(srcdir) \
@@ -93,11 +108,15 @@ fuse4fs.1: $(DEP_SUBSTITUTE) $(srcdir)/fuse4fs.1.in
 	$(E) "	SUBST $@"
 	$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/fuse4fs.1.in fuse4fs.1
 
-installdirs:
+installdirs: $(INSTALLDIRS_TGT)
 	$(E) "	MKDIR_P $(bindir) $(man1dir)"
 	$(Q) $(MKDIR_P) $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir)
 
-install: all $(UMANPAGES) installdirs
+installdirs-systemd:
+	$(E) "	MKDIR_P $(SYSTEMD_SYSTEM_UNIT_DIR)"
+	$(Q) $(MKDIR_P) $(DESTDIR)$(SYSTEMD_SYSTEM_UNIT_DIR)
+
+install: all $(UMANPAGES) installdirs $(INSTALL_TGT)
 	$(Q) for i in $(UPROGS); do \
 		$(ES) "	INSTALL $(bindir)/$$i"; \
 		$(INSTALL_PROGRAM) $$i $(DESTDIR)$(bindir)/$$i; \
@@ -110,13 +129,19 @@ install: all $(UMANPAGES) installdirs
 		$(INSTALL_DATA) $$i $(DESTDIR)$(man1dir)/$$i; \
 	done
 
+install-systemd: $(SERVICE_FILES) installdirs-systemd
+	$(Q) for i in $(SERVICE_FILES); do \
+		$(ES) "	INSTALL_DATA $(SYSTEMD_SYSTEM_UNIT_DIR)/$$i"; \
+		$(INSTALL_DATA) $$i $(DESTDIR)$(SYSTEMD_SYSTEM_UNIT_DIR)/$$i; \
+	done
+
 install-strip: install
 	$(Q) for i in $(UPROGS); do \
 		$(E) "	STRIP $(bindir)/$$i"; \
 		$(STRIP) $(DESTDIR)$(bindir)/$$i; \
 	done
 
-uninstall:
+uninstall: $(UNINSTALL_TGT)
 	for i in $(UPROGS); do \
 		$(RM) -f $(DESTDIR)$(bindir)/$$i; \
 	done
@@ -124,9 +149,16 @@ uninstall:
 		$(RM) -f $(DESTDIR)$(man1dir)/$$i; \
 	done
 
+uninstall-systemd:
+	for i in $(SERVICE_FILES); do \
+		$(RM) -f $(DESTDIR)$(SYSTEMD_SYSTEM_UNIT_DIR)/$$i; \
+	done
+
 clean::
 	$(RM) -f $(UPROGS) $(UMANPAGES) profile.h \
 		fuse4fs.profiled \
+		$(SERVICE_FILES) \
+		fuse4fs.socket \
 		profiled/*.o \#* *.s *.o *.a *~ core gmon.out
 
 mostlyclean: clean
diff --git a/fuse4fs/fuse4fs.c b/fuse4fs/fuse4fs.c
index 1a4ac0cd9a038f..acb6402a174ad3 100644
--- a/fuse4fs/fuse4fs.c
+++ b/fuse4fs/fuse4fs.c
@@ -46,6 +46,10 @@
 # define _FILE_OFFSET_BITS 64
 #endif /* _FILE_OFFSET_BITS */
 #include <fuse_lowlevel.h>
+#ifdef HAVE_FUSE_SERVICE
+# include <sys/mount.h>
+# include <fuse_service.h>
+#endif
 #ifdef __SET_FOB_FOR_FUSE
 # undef _FILE_OFFSET_BITS
 #endif /* __SET_FOB_FOR_FUSE */
@@ -314,8 +318,22 @@ struct fuse4fs {
 #endif
 	struct fuse_session *fuse;
 	struct cache inodes;
+#ifdef HAVE_FUSE_SERVICE
+	struct fuse_service *service;
+	int bdev_fd;
+	int fusedev_fd;
+#endif
 };
 
+#ifdef HAVE_FUSE_SERVICE
+static inline bool fuse4fs_is_service(const struct fuse4fs *ff)
+{
+	return fuse_service_accepted(ff->service);
+}
+#else
+# define fuse4fs_is_service(...)		(false)
+#endif
+
 #define FUSE4FS_CHECK_HANDLE(req, fh) \
 	do { \
 		if ((fh) == NULL || (fh)->magic != FUSE4FS_FILE_MAGIC) { \
@@ -915,7 +933,11 @@ static inline void fuse4fs_discover_iomap(struct fuse4fs *ff)
 	if (ff->iomap_want == FT_DISABLE)
 		return;
 
+#ifdef HAVE_FUSE_SERVICE
+	ff->iomap_cap = fuse_lowlevel_discover_iomap(ff->fusedev_fd);
+#else
 	ff->iomap_cap = fuse_lowlevel_discover_iomap(-1);
+#endif
 }
 
 static inline bool fuse4fs_can_iomap(const struct fuse4fs *ff)
@@ -1410,6 +1432,176 @@ static errcode_t fuse4fs_check_support(struct fuse4fs *ff)
 	return 0;
 }
 
+#ifdef HAVE_FUSE_SERVICE
+static int fuse4fs_service_connect(struct fuse4fs *ff, struct fuse_args *args)
+{
+	int ret;
+
+	ret = fuse_service_accept(&ff->service);
+	if (ret)
+		return ret;
+
+	if (fuse4fs_is_service(ff))
+		fuse_service_append_args(ff->service, args);
+
+	return 0;
+}
+
+static inline int
+fuse4fs_service_parse_cmdline(struct fuse_args *args,
+			      struct fuse_cmdline_opts *opts)
+{
+	return fuse_service_parse_cmdline_opts(args, opts);
+}
+
+static void fuse4fs_service_release(struct fuse4fs *ff, int mount_ret)
+{
+	if (fuse4fs_is_service(ff)) {
+		fuse_service_send_goodbye(ff->service, mount_ret);
+		fuse_service_release(ff->service);
+	}
+}
+
+static void fuse4fs_service_close_bdev(struct fuse4fs *ff)
+{
+	if (ff->bdev_fd >= 0)
+		close(ff->bdev_fd);
+	ff->bdev_fd = -1;
+}
+
+static int fuse4fs_service_finish(struct fuse4fs *ff, int ret)
+{
+	if (!fuse4fs_is_service(ff))
+		return ret;
+
+	fuse_service_destroy(&ff->service);
+	close(ff->bdev_fd);
+	ff->bdev_fd = -1;
+
+	/*
+	 * If we're being run as a service, the return code must fit the LSB
+	 * init script action error guidelines, which is to say that we
+	 * compress all errors to 1 ("generic or unspecified error", LSB 5.0
+	 * section 22.2) and hope the admin will scan the log for what actually
+	 * happened.
+	 *
+	 * We have to sleep 2 seconds here because journald uses the pid to
+	 * connect our log messages to the systemd service.  This is critical
+	 * for capturing all the log messages if fuse4fs fails, because any
+	 * program scraping the journalctl output needs to see all of our
+	 * output.
+	 */
+	sleep(2);
+	if (ret != EXIT_SUCCESS)
+		return EXIT_FAILURE;
+	return EXIT_SUCCESS;
+}
+
+static int fuse4fs_service_get_config(struct fuse4fs *ff)
+{
+	double deadline = init_deadline(FUSE4FS_OPEN_TIMEOUT);
+	int open_flags = O_RDWR | O_EXCL;
+	int ret;
+
+	do {
+		ret = fuse_service_request_file(ff->service, ff->device,
+						open_flags, 0, 0);
+		if (ret)
+			return ret;
+
+		ret = fuse_service_receive_file(ff->service, ff->device,
+						&ff->bdev_fd);
+		if (ret)
+			return ret;
+
+		if (ff->bdev_fd < 0 &&
+		    (errno == EPERM || errno == EACCES) &&
+		    (open_flags & O_ACCMODE) != O_RDONLY) {
+			open_flags = O_RDONLY | O_EXCL;
+
+			/* Force the loop to run once more */
+			ret = 1;
+		}
+	} while (ret == 1 ||
+		 (ff->bdev_fd < 0 && errno == EBUSY &&
+		  retry_before_deadline(deadline)));
+	if (ff->bdev_fd < 0) {
+		err_printf(ff, "%s %s: %s.\n", _("opening device"), ff->device,
+			   strerror(errno));
+		return -1;
+	}
+
+	ret = fuse_service_finish_file_requests(ff->service);
+	if (ret)
+		return ret;
+
+	ff->fusedev_fd = fuse_service_take_fusedev(ff->service);
+	return 0;
+}
+
+static errcode_t fuse4fs_service_openfs(struct fuse4fs *ff, char *options,
+					int flags)
+{
+	char path[32];
+
+	snprintf(path, sizeof(path), "%d", ff->bdev_fd);
+	iocache_set_backing_manager(unixfd_io_manager);
+	return ext2fs_open2(path, options, flags, 0, 0, iocache_io_manager,
+			&ff->fs);
+}
+
+static int fuse4fs_service_configure_iomap(struct fuse4fs *ff)
+{
+	int error = 0;
+	int ret;
+
+	ret = fuse_service_configure_iomap(ff->service,
+					   ff->iomap_want == FT_ENABLE,
+					   &error);
+	if (ret)
+		return -1;
+
+	if (error) {
+		err_printf(ff, "%s: %s.\n", _("enabling iomap"),
+			   strerror(error));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int fuse4fs_service(struct fuse4fs *ff, struct fuse_session *se,
+			   const char *mountpoint)
+{
+	char path[32];
+	int ret = 0;
+
+	snprintf(path, sizeof(path), "/dev/fd/%d", ff->fusedev_fd);
+	ret = fuse_session_mount(se, path);
+	if (ret)
+		return ret;
+
+	ret = fuse_service_mount(ff->service, se, mountpoint);
+	if (ret) {
+		err_printf(ff, "%s: %s\n", _("mounting filesystem"),
+			   strerror(errno));
+		return ret;
+	}
+
+	return 0;
+}
+#else
+# define fuse4fs_service_connect(...)		(0)
+# define fuse4fs_service_parse_cmdline(...)	(EOPNOTSUPP)
+# define fuse4fs_service_release(...)		((void)0)
+# define fuse4fs_service_close_bdev(...)	((void)0)
+# define fuse4fs_service_finish(fctx, ret)	(ret)
+# define fuse4fs_service_get_config(...)	(EOPNOTSUPP)
+# define fuse4fs_service_openfs(...)		(EOPNOTSUPP)
+# define fuse4fs_service_configure_iomap(...)	(EOPNOTSUPP)
+# define fuse4fs_service(...)			(EOPNOTSUPP)
+#endif
+
 static errcode_t fuse4fs_acquire_lockfile(struct fuse4fs *ff)
 {
 	char *resolved;
@@ -1469,6 +1661,10 @@ static int fuse4fs_try_losetup(struct fuse4fs *ff, int flags)
 	if (!fuse4fs_can_iomap(ff))
 		return 0;
 
+	/* Service helper does the losetup */
+	if (fuse4fs_is_service(ff))
+		return 0;
+
 	/* open the actual target device, see if it's a regular file */
 	dev_fd = open(ff->device, rw ? O_RDWR : O_RDONLY);
 	if (dev_fd < 0) {
@@ -1546,6 +1742,7 @@ static void fuse4fs_unmount(struct fuse4fs *ff)
 				   uuid);
 	}
 
+	fuse4fs_service_close_bdev(ff);
 	fuse4fs_undo_losetup(ff);
 
 	if (ff->lockfile)
@@ -1612,8 +1809,11 @@ static errcode_t fuse4fs_open(struct fuse4fs *ff)
 	 */
 	deadline = init_deadline(FUSE4FS_OPEN_TIMEOUT);
 	do {
-		err = ext2fs_open2(fuse4fs_device(ff), options, flags, 0, 0,
-				   iocache_io_manager, &ff->fs);
+		if (fuse4fs_is_service(ff))
+			err = fuse4fs_service_openfs(ff, options, flags);
+		else
+			err = ext2fs_open2(fuse4fs_device(ff), options, flags,
+					   0, 0, iocache_io_manager, &ff->fs);
 		if ((err == EPERM || err == EACCES) &&
 		    (!ff->ro || (flags & EXT2_FLAG_RW))) {
 			/*
@@ -1976,6 +2176,10 @@ static int fuse4fs_setup_logging(struct fuse4fs *ff)
 	if (logfile)
 		return fuse4fs_capture_output(ff, logfile);
 
+	/* systemd already hooked us up to /dev/ttyprintk */
+	if (fuse4fs_is_service(ff))
+		return 0;
+
 	/* in kernel mode, try to log errors to the kernel log */
 	if (ff->kernel)
 		fuse4fs_capture_output(ff, "/dev/ttyprintk");
@@ -7906,14 +8110,13 @@ static const char *get_subtype(const char *argv0)
 }
 
 static void fuse4fs_compute_libfuse_args(struct fuse4fs *ff,
-					 struct fuse_args *args,
-					 const char *argv0)
+					 struct fuse_args *args)
 {
 	char extra_args[BUFSIZ];
 
 	/* Set up default fuse parameters */
 	snprintf(extra_args, BUFSIZ, "-osubtype=%s,fsname=%s",
-		 get_subtype(argv0),
+		 get_subtype(args->argv[0]),
 		 ff->device);
 	if (ff->no_default_opts == 0)
 		fuse_opt_add_arg(args, extra_args);
@@ -8032,7 +8235,11 @@ static int fuse4fs_main(struct fuse_args *args, struct fuse4fs *ff)
 	struct fuse_loop_config *loop_config = NULL;
 	int ret;
 
-	if (fuse_parse_cmdline(args, &opts) != 0) {
+	if (fuse4fs_is_service(ff))
+		ret = fuse4fs_service_parse_cmdline(args, &opts);
+	else
+		ret = fuse_parse_cmdline(args, &opts);
+	if (ret != 0) {
 		ret = 1;
 		goto out;
 	}
@@ -8065,7 +8272,18 @@ static int fuse4fs_main(struct fuse_args *args, struct fuse4fs *ff)
 	}
 	ff->fuse = se;
 
-	if (fuse_session_mount(se, opts.mountpoint) != 0) {
+	if (fuse4fs_is_service(ff)) {
+		/*
+		 * foreground mode is needed so that systemd actually tracks
+		 * the service correctly and doesnt try to kill it; and so that
+		 * stdout/stderr don't get zapped
+		 */
+		opts.foreground = 1;
+		ret = fuse4fs_service(ff, se, opts.mountpoint);
+	} else {
+		ret = fuse_session_mount(se, opts.mountpoint);
+	}
+	if (ret != 0) {
 		ret = 4;
 		goto out_destroy_session;
 	}
@@ -8106,6 +8324,8 @@ static int fuse4fs_main(struct fuse_args *args, struct fuse4fs *ff)
 	fuse_loop_cfg_set_idle_threads(loop_config, opts.max_idle_threads);
 	fuse_loop_cfg_set_max_threads(loop_config, 4);
 
+	fuse4fs_service_release(ff, 0);
+
 	/*
 	 * Try to set ourselves up with fs reclaim disabled to prevent
 	 * recursive reclaim and throttling.  This must be done before starting
@@ -8138,6 +8358,7 @@ static int fuse4fs_main(struct fuse_args *args, struct fuse4fs *ff)
 out_free_opts:
 	free(opts.mountpoint);
 out:
+	fuse4fs_service_release(ff, ret);
 	return ret;
 }
 
@@ -8160,11 +8381,31 @@ int main(int argc, char *argv[])
 		.loop_fd = -1,
 #endif
 		.translate_inums = 1,
+#ifdef HAVE_FUSE_SERVICE
+		.bdev_fd = -1,
+		.fusedev_fd = -1,
+#endif
 	};
 	errcode_t err;
 	FILE *orig_stderr = stderr;
 	int ret;
 
+	/* XXX */
+	if (getenv("FUSE4FS_DEBUGGER")) {
+		char *moo = getenv("FUSE4FS_DEBUGGER");
+		int del = atoi(moo);
+
+		fprintf(stderr, "WAITING %ds FOR DEBUGGER\n", del);
+		fflush(stderr);
+		sleep(del);
+	}
+
+	ret = fuse4fs_service_connect(&fctx, &args);
+	if (ret) {
+		fprintf(stderr, "Could not connect to service socket!\n");
+		exit(1);
+	}
+
 	ret = fuse_opt_parse(&args, &fctx, fuse4fs_opts, fuse4fs_opt_proc);
 	if (ret)
 		exit(1);
@@ -8206,6 +8447,24 @@ int main(int argc, char *argv[])
 		goto out;
 	}
 
+	if (fuse4fs_is_service(&fctx)) {
+		ret = fuse4fs_service_get_config(&fctx);
+		if (ret) {
+			ret = 2;
+			goto out;
+		}
+
+#ifdef HAVE_FUSE_IOMAP
+		if (fctx.iomap_want != FT_DISABLE) {
+			ret = fuse4fs_service_configure_iomap(&fctx);
+			if (ret) {
+				ret = 2;
+				goto out;
+			}
+		}
+#endif
+	}
+
 	try_adjust_oom_score(&fctx);
 
 	/* Will we allow users to allocate every last block? */
@@ -8260,7 +8519,7 @@ int main(int argc, char *argv[])
 	/* Initialize generation counter */
 	get_random_bytes(&fctx.next_generation, sizeof(unsigned int));
 
-	fuse4fs_compute_libfuse_args(&fctx, &args, argv[0]);
+	fuse4fs_compute_libfuse_args(&fctx, &args);
 
 	ret = fuse4fs_main(&args, &fctx);
 	switch(ret) {
@@ -8304,6 +8563,7 @@ int main(int argc, char *argv[])
 	if (fctx.device)
 		free(fctx.device);
 	pthread_mutex_destroy(&fctx.bfl);
+	ret = fuse4fs_service_finish(&fctx, ret);
 	fuse_opt_free_args(&args);
 	return ret;
 }
diff --git a/fuse4fs/fuse4fs.socket.in b/fuse4fs/fuse4fs.socket.in
new file mode 100644
index 00000000000000..0e90a4f0c97f6e
--- /dev/null
+++ b/fuse4fs/fuse4fs.socket.in
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2025-2026 Oracle.  All Rights Reserved.
+# Author: Darrick J. Wong <djwong@kernel.org>
+[Unit]
+Description=Socket for ext4 Service
+
+[Socket]
+ListenSequentialPacket=@fuse_service_socket_dir@/ext2
+ListenSequentialPacket=@fuse_service_socket_dir@/ext3
+ListenSequentialPacket=@fuse_service_socket_dir@/ext4
+Accept=yes
+SocketMode=0660
+RemoveOnStop=yes
+
+[Install]
+WantedBy=sockets.target
diff --git a/fuse4fs/fuse4fs@.service.in b/fuse4fs/fuse4fs@.service.in
new file mode 100644
index 00000000000000..2b9b3e0a69d2ee
--- /dev/null
+++ b/fuse4fs/fuse4fs@.service.in
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2025-2026 Oracle.  All Rights Reserved.
+# Author: Darrick J. Wong <djwong@kernel.org>
+[Unit]
+Description=ext4 Service
+
+[Service]
+Type=exec
+ExecStart=@bindir@/fuse4fs -o kernel
+
+# Try to capture core dumps
+LimitCORE=infinity
+
+SyslogIdentifier=%N
+
+# No realtime CPU scheduling
+RestrictRealtime=true
+
+# Don't let us see anything in the regular system, and don't run as root
+DynamicUser=true
+ProtectSystem=strict
+ProtectHome=true
+PrivateTmp=true
+PrivateDevices=true
+PrivateUsers=true
+
+# No network access
+PrivateNetwork=true
+ProtectHostname=true
+RestrictAddressFamilies=none
+IPAddressDeny=any
+
+# Don't let the program mess with the kernel configuration at all
+ProtectKernelLogs=true
+ProtectKernelModules=true
+ProtectKernelTunables=true
+ProtectControlGroups=true
+ProtectProc=invisible
+RestrictNamespaces=true
+RestrictFileSystems=
+
+# Hide everything in /proc, even /proc/mounts
+ProcSubset=pid
+
+# Only allow the default personality Linux
+LockPersonality=true
+
+# No writable memory pages
+MemoryDenyWriteExecute=true
+
+# Don't let our mounts leak out to the host
+PrivateMounts=true
+
+# Restrict system calls to the native arch and only enough to get things going
+SystemCallArchitectures=native
+SystemCallFilter=@system-service
+SystemCallFilter=~@privileged
+SystemCallFilter=~@resources
+
+SystemCallFilter=~@clock
+SystemCallFilter=~@cpu-emulation
+SystemCallFilter=~@debug
+SystemCallFilter=~@module
+SystemCallFilter=~@reboot
+SystemCallFilter=~@swap
+
+SystemCallFilter=~@mount
+
+# libfuse io_uring wants to pin cores and memory
+SystemCallFilter=mbind
+SystemCallFilter=sched_setaffinity
+
+# Leave a breadcrumb if we get whacked by the system call filter
+SystemCallErrorNumber=EL3RST
+
+# Log to the kernel dmesg, just like an in-kernel ext4 driver
+StandardOutput=append:/dev/ttyprintk
+StandardError=append:/dev/ttyprintk
+
+# Run with no capabilities at all
+CapabilityBoundingSet=
+AmbientCapabilities=
+NoNewPrivileges=true
+
+# fuse4fs doesn't create files
+UMask=7777
+
+# No access to hardware /dev files at all
+ProtectClock=true
+DevicePolicy=closed
+
+# Don't mess with set[ug]id anything.
+RestrictSUIDSGID=true
+
+# Don't let OOM kills of processes in this containment group kill the whole
+# service, because we don't want filesystem drivers to go down.
+OOMPolicy=continue
+OOMScoreAdjust=-1000
diff --git a/lib/config.h.in b/lib/config.h.in
index 7e045b65131522..8c5ba567a748a8 100644
--- a/lib/config.h.in
+++ b/lib/config.h.in
@@ -85,6 +85,9 @@
 /* Define to 1 if fuse supports loopdev operations */
 #undef HAVE_FUSE_LOOPDEV
 
+/* Define to 1 if fuse supports service */
+#undef HAVE_FUSE_SERVICE
+
 /* Define to 1 if you have the Mac OS X function
    CFLocaleCopyPreferredLanguages in the CoreFoundation framework. */
 #undef HAVE_CFLOCALECOPYPREFERREDLANGUAGES
diff --git a/util/subst.conf.in b/util/subst.conf.in
index 5af5e356d46ac7..5fc7cf8f33fa76 100644
--- a/util/subst.conf.in
+++ b/util/subst.conf.in
@@ -24,3 +24,5 @@ root_bindir		@root_bindir@
 libdir			@libdir@
 $exec_prefix		@exec_prefix@
 pkglibexecdir		@libexecdir@/e2fsprogs
+bindir			@bindir@
+fuse_service_socket_dir	@fuse_service_socket_dir@


  parent reply	other threads:[~2026-02-23 23:46 UTC|newest]

Thread overview: 230+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-23 22:46 [PATCHBLIZZARD v7] fuse/libfuse/e2fsprogs: containerize ext4 for safer operation Darrick J. Wong
2026-02-23 23:00 ` [PATCHSET v7 1/9] fuse: general bug fixes Darrick J. Wong
2026-02-23 23:06   ` [PATCH 1/5] fuse: flush pending FUSE_RELEASE requests before sending FUSE_DESTROY Darrick J. Wong
2026-02-24 19:33     ` Joanne Koong
2026-02-24 19:57       ` Darrick J. Wong
2026-02-24 20:03         ` Joanne Koong
2026-02-23 23:06   ` [PATCH 2/5] fuse: quiet down complaints in fuse_conn_limit_write Darrick J. Wong
2026-02-24  8:36     ` Horst Birthelmer
2026-02-24 19:17       ` Darrick J. Wong
2026-02-24 20:09     ` Joanne Koong
2026-02-27 16:05     ` Miklos Szeredi
2026-02-23 23:07   ` [PATCH 3/5] fuse: implement file attributes mask for statx Darrick J. Wong
2026-03-25 18:35     ` Joanne Koong
2026-03-25 22:12       ` Darrick J. Wong
2026-02-23 23:07   ` [PATCH 4/5] fuse: update file mode when updating acls Darrick J. Wong
2026-03-25 19:39     ` Joanne Koong
2026-03-25 22:23       ` Darrick J. Wong
2026-02-23 23:07   ` [PATCH 5/5] fuse: propagate default and file acls on creation Darrick J. Wong
2026-02-23 23:00 ` [PATCHSET v7 2/9] iomap: cleanups ahead of adding fuse support Darrick J. Wong
2026-02-23 23:07   ` [PATCH 1/2] iomap: allow directio callers to supply _COMP_WORK Darrick J. Wong
2026-02-24 14:00     ` Christoph Hellwig
2026-02-24 19:17       ` Darrick J. Wong
2026-02-23 23:08   ` [PATCH 2/2] iomap: allow NULL swap info bdev when activating swapfile Darrick J. Wong
2026-02-24 14:01     ` Christoph Hellwig
2026-02-24 19:26       ` Darrick J. Wong
2026-02-25 14:16         ` Christoph Hellwig
2026-02-25 17:03           ` Darrick J. Wong
2026-02-25 17:49             ` Christoph Hellwig
2026-02-23 23:01 ` [PATCHSET v7 3/9] fuse: cleanups ahead of adding fuse support Darrick J. Wong
2026-02-23 23:08   ` [PATCH 1/2] fuse: move the passthrough-specific code back to passthrough.c Darrick J. Wong
2026-02-23 23:08   ` [PATCH 2/2] fuse_trace: " Darrick J. Wong
2026-02-23 23:01 ` [PATCHSET v7 4/9] fuse: allow servers to use iomap for better file IO performance Darrick J. Wong
2026-02-23 23:08   ` [PATCH 01/33] fuse: implement the basic iomap mechanisms Darrick J. Wong
2026-02-23 23:09   ` [PATCH 02/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:09   ` [PATCH 03/33] fuse: make debugging configurable at runtime Darrick J. Wong
2026-02-23 23:09   ` [PATCH 04/33] fuse: adapt FUSE_DEV_IOC_BACKING_{OPEN,CLOSE} to add new iomap devices Darrick J. Wong
2026-02-23 23:09   ` [PATCH 05/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:10   ` [PATCH 06/33] fuse: enable SYNCFS and ensure we flush everything before sending DESTROY Darrick J. Wong
2026-02-23 23:10   ` [PATCH 07/33] fuse: clean up per-file type inode initialization Darrick J. Wong
2026-02-23 23:10   ` [PATCH 08/33] fuse: create a per-inode flag for setting exclusive mode Darrick J. Wong
2026-02-23 23:11   ` [PATCH 09/33] fuse: create a per-inode flag for toggling iomap Darrick J. Wong
2026-02-23 23:11   ` [PATCH 10/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:11   ` [PATCH 11/33] fuse: isolate the other regular file IO paths from iomap Darrick J. Wong
2026-02-23 23:11   ` [PATCH 12/33] fuse: implement basic iomap reporting such as FIEMAP and SEEK_{DATA,HOLE} Darrick J. Wong
2026-02-23 23:12   ` [PATCH 13/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:12   ` [PATCH 14/33] fuse: implement direct IO with iomap Darrick J. Wong
2026-02-23 23:12   ` [PATCH 15/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:12   ` [PATCH 16/33] fuse: implement buffered " Darrick J. Wong
2026-02-27 18:04     ` Darrick J. Wong
2026-02-23 23:13   ` [PATCH 17/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:13   ` [PATCH 18/33] fuse: use an unrestricted backing device with iomap pagecache io Darrick J. Wong
2026-02-23 23:13   ` [PATCH 19/33] fuse: implement large folios for iomap pagecache files Darrick J. Wong
2026-02-23 23:13   ` [PATCH 20/33] fuse: advertise support for iomap Darrick J. Wong
2026-02-23 23:14   ` [PATCH 21/33] fuse: query filesystem geometry when using iomap Darrick J. Wong
2026-02-23 23:14   ` [PATCH 22/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:14   ` [PATCH 23/33] fuse: implement fadvise for iomap files Darrick J. Wong
2026-02-23 23:14   ` [PATCH 24/33] fuse: invalidate ranges of block devices being used for iomap Darrick J. Wong
2026-02-23 23:15   ` [PATCH 25/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:15   ` [PATCH 26/33] fuse: implement inline data file IO via iomap Darrick J. Wong
2026-02-27 18:02     ` Darrick J. Wong
2026-02-23 23:15   ` [PATCH 27/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:15   ` [PATCH 28/33] fuse: allow more statx fields Darrick J. Wong
2026-02-23 23:16   ` [PATCH 29/33] fuse: support atomic writes with iomap Darrick J. Wong
2026-02-24 12:58     ` Pankaj Raghav (Samsung)
2026-02-24 19:30       ` Darrick J. Wong
2026-02-24 21:18         ` Pankaj Raghav (Samsung)
2026-02-23 23:16   ` [PATCH 30/33] fuse_trace: " Darrick J. Wong
2026-02-23 23:16   ` [PATCH 31/33] fuse: disable direct fs reclaim for any fuse server that uses iomap Darrick J. Wong
2026-02-23 23:17   ` [PATCH 32/33] fuse: enable swapfile activation on iomap Darrick J. Wong
2026-02-23 23:17   ` [PATCH 33/33] fuse: implement freeze and shutdowns for iomap filesystems Darrick J. Wong
2026-02-23 23:01 ` [PATCHSET v7 5/9] fuse: allow servers to specify root node id Darrick J. Wong
2026-02-23 23:17   ` [PATCH 1/3] fuse: make the root nodeid dynamic Darrick J. Wong
2026-02-23 23:17   ` [PATCH 2/3] fuse_trace: " Darrick J. Wong
2026-02-23 23:18   ` [PATCH 3/3] fuse: allow setting of root nodeid Darrick J. Wong
2026-02-23 23:01 ` [PATCHSET v7 6/9] fuse: handle timestamps and ACLs correctly when iomap is enabled Darrick J. Wong
2026-02-23 23:18   ` [PATCH 1/9] fuse: enable caching of timestamps Darrick J. Wong
2026-02-23 23:18   ` [PATCH 2/9] fuse: force a ctime update after a fileattr_set call when in iomap mode Darrick J. Wong
2026-02-23 23:18   ` [PATCH 3/9] fuse: allow local filesystems to set some VFS iflags Darrick J. Wong
2026-02-23 23:19   ` [PATCH 4/9] fuse_trace: " Darrick J. Wong
2026-02-23 23:19   ` [PATCH 5/9] fuse: cache atime when in iomap mode Darrick J. Wong
2026-02-23 23:19   ` [PATCH 6/9] fuse: let the kernel handle KILL_SUID/KILL_SGID for iomap filesystems Darrick J. Wong
2026-02-23 23:19   ` [PATCH 7/9] fuse_trace: " Darrick J. Wong
2026-02-23 23:20   ` [PATCH 8/9] fuse: update ctime when updating acls on an iomap inode Darrick J. Wong
2026-02-23 23:20   ` [PATCH 9/9] fuse: always cache ACLs when using iomap Darrick J. Wong
2026-02-23 23:02 ` [PATCHSET v7 7/9] fuse: cache iomap mappings for even better file IO performance Darrick J. Wong
2026-02-23 23:20   ` [PATCH 01/12] fuse: cache iomaps Darrick J. Wong
2026-02-27 18:07     ` Darrick J. Wong
2026-02-23 23:20   ` [PATCH 02/12] fuse_trace: " Darrick J. Wong
2026-02-23 23:21   ` [PATCH 03/12] fuse: use the iomap cache for iomap_begin Darrick J. Wong
2026-02-23 23:21   ` [PATCH 04/12] fuse_trace: " Darrick J. Wong
2026-02-23 23:21   ` [PATCH 05/12] fuse: invalidate iomap cache after file updates Darrick J. Wong
2026-02-23 23:21   ` [PATCH 06/12] fuse_trace: " Darrick J. Wong
2026-02-23 23:22   ` [PATCH 07/12] fuse: enable iomap cache management Darrick J. Wong
2026-02-23 23:22   ` [PATCH 08/12] fuse_trace: " Darrick J. Wong
2026-02-23 23:22   ` [PATCH 09/12] fuse: overlay iomap inode info in struct fuse_inode Darrick J. Wong
2026-02-23 23:23   ` [PATCH 10/12] fuse: constrain iomap mapping cache size Darrick J. Wong
2026-02-23 23:23   ` [PATCH 11/12] fuse_trace: " Darrick J. Wong
2026-02-23 23:23   ` [PATCH 12/12] fuse: enable iomap Darrick J. Wong
2026-02-23 23:02 ` [PATCHSET v7 8/9] fuse: run fuse servers as a contained service Darrick J. Wong
2026-02-23 23:23   ` [PATCH 1/2] fuse: allow privileged mount helpers to pre-approve iomap usage Darrick J. Wong
2026-02-23 23:24   ` [PATCH 2/2] fuse: set iomap backing device block size Darrick J. Wong
2026-02-23 23:02 ` [PATCHSET RFC 9/9] fuse: allow fuse servers to upload iomap BPF programs Darrick J. Wong
2026-02-23 23:24   ` [PATCH 1/5] fuse: enable fuse servers to upload BPF programs to handle iomap requests Darrick J. Wong
2026-02-23 23:24   ` [PATCH 2/5] fuse_trace: " Darrick J. Wong
2026-02-23 23:24   ` [PATCH 3/5] fuse: prevent iomap bpf programs from writing to most of the system Darrick J. Wong
2026-02-23 23:25   ` [PATCH 4/5] fuse: add kfuncs for iomap bpf programs to manage the cache Darrick J. Wong
2026-02-23 23:25   ` [PATCH 5/5] fuse: make fuse_inode opaque to iomap bpf programs Darrick J. Wong
2026-02-23 23:02 ` [PATCHSET v7 1/6] libfuse: allow servers to use iomap for better file IO performance Darrick J. Wong
2026-02-23 23:25   ` [PATCH 01/25] libfuse: bump kernel and library ABI versions Darrick J. Wong
2026-02-23 23:25   ` [PATCH 02/25] libfuse: wait in do_destroy until all open files are closed Darrick J. Wong
2026-02-23 23:26   ` [PATCH 03/25] libfuse: add kernel gates for FUSE_IOMAP Darrick J. Wong
2026-02-23 23:26   ` [PATCH 04/25] libfuse: add fuse commands for iomap_begin and end Darrick J. Wong
2026-02-23 23:26   ` [PATCH 05/25] libfuse: add upper level iomap commands Darrick J. Wong
2026-02-23 23:26   ` [PATCH 06/25] libfuse: add a lowlevel notification to add a new device to iomap Darrick J. Wong
2026-02-23 23:27   ` [PATCH 07/25] libfuse: add upper-level iomap add device function Darrick J. Wong
2026-02-23 23:27   ` [PATCH 08/25] libfuse: add iomap ioend low level handler Darrick J. Wong
2026-02-23 23:27   ` [PATCH 09/25] libfuse: add upper level iomap ioend commands Darrick J. Wong
2026-02-23 23:27   ` [PATCH 10/25] libfuse: add a reply function to send FUSE_ATTR_* to the kernel Darrick J. Wong
2026-02-23 23:28   ` [PATCH 11/25] libfuse: connect high level fuse library to fuse_reply_attr_iflags Darrick J. Wong
2026-02-23 23:28   ` [PATCH 12/25] libfuse: support enabling exclusive mode for files Darrick J. Wong
2026-02-23 23:28   ` [PATCH 13/25] libfuse: support direct I/O through iomap Darrick J. Wong
2026-02-23 23:29   ` [PATCH 14/25] libfuse: don't allow hardlinking of iomap files in the upper level fuse library Darrick J. Wong
2026-02-23 23:29   ` [PATCH 15/25] libfuse: allow discovery of the kernel's iomap capabilities Darrick J. Wong
2026-02-23 23:29   ` [PATCH 16/25] libfuse: add lower level iomap_config implementation Darrick J. Wong
2026-02-23 23:29   ` [PATCH 17/25] libfuse: add upper " Darrick J. Wong
2026-02-23 23:30   ` [PATCH 18/25] libfuse: add low level code to invalidate iomap block device ranges Darrick J. Wong
2026-02-23 23:30   ` [PATCH 19/25] libfuse: add upper-level API to invalidate parts of an iomap block device Darrick J. Wong
2026-02-23 23:30   ` [PATCH 20/25] libfuse: add atomic write support Darrick J. Wong
2026-02-23 23:30   ` [PATCH 21/25] libfuse: allow disabling of fs memory reclaim and write throttling Darrick J. Wong
2026-02-23 23:31   ` [PATCH 22/25] libfuse: create a helper to transform an open regular file into an open loopdev Darrick J. Wong
2026-02-23 23:31   ` [PATCH 23/25] libfuse: add swapfile support for iomap files Darrick J. Wong
2026-02-23 23:31   ` [PATCH 24/25] libfuse: add lower-level filesystem freeze, thaw, and shutdown requests Darrick J. Wong
2026-02-23 23:31   ` [PATCH 25/25] libfuse: add upper-level filesystem freeze, thaw, and shutdown events Darrick J. Wong
2026-02-23 23:03 ` [PATCHSET v7 2/6] libfuse: allow servers to specify root node id Darrick J. Wong
2026-02-23 23:32   ` [PATCH 1/1] libfuse: allow root_nodeid mount option Darrick J. Wong
2026-02-23 23:03 ` [PATCHSET v7 3/6] libfuse: implement syncfs Darrick J. Wong
2026-02-23 23:32   ` [PATCH 1/2] libfuse: add strictatime/lazytime mount options Darrick J. Wong
2026-02-23 23:32   ` [PATCH 2/2] libfuse: set sync, immutable, and append when loading files Darrick J. Wong
2026-02-23 23:03 ` [PATCHSET v7 4/6] libfuse: cache iomap mappings for even better file IO performance Darrick J. Wong
2026-02-23 23:32   ` [PATCH 1/5] libfuse: enable iomap cache management for lowlevel fuse Darrick J. Wong
2026-02-23 23:33   ` [PATCH 2/5] libfuse: add upper-level iomap cache management Darrick J. Wong
2026-02-23 23:33   ` [PATCH 3/5] libfuse: allow constraining of iomap mapping cache size Darrick J. Wong
2026-02-23 23:33   ` [PATCH 4/5] libfuse: add upper-level iomap mapping cache constraint code Darrick J. Wong
2026-02-23 23:33   ` [PATCH 5/5] libfuse: enable iomap Darrick J. Wong
2026-02-23 23:03 ` [PATCHSET v7 5/6] libfuse: run fuse servers as a contained service Darrick J. Wong
2026-02-23 23:34   ` [PATCH 1/5] libfuse: add systemd/inetd socket service mounting helper Darrick J. Wong
2026-02-23 23:34   ` [PATCH 2/5] libfuse: integrate fuse services into mount.fuse3 Darrick J. Wong
2026-02-23 23:34   ` [PATCH 3/5] libfuse: delegate iomap privilege from mount.service to fuse services Darrick J. Wong
2026-02-23 23:34   ` [PATCH 4/5] libfuse: enable setting iomap block device block size Darrick J. Wong
2026-02-23 23:35   ` [PATCH 5/5] fuservicemount: create loop devices for regular files Darrick J. Wong
2026-02-23 23:04 ` [PATCHSET RFC 6/6] fuse: allow fuse servers to upload iomap BPF programs Darrick J. Wong
2026-02-23 23:35   ` [PATCH 1/3] libfuse: allow fuse servers to upload bpf code for iomap functions Darrick J. Wong
2026-02-23 23:35   ` [PATCH 2/3] libfuse: add kfuncs for iomap bpf programs to manage the cache Darrick J. Wong
2026-02-23 23:36   ` [PATCH 3/3] libfuse: make fuse_inode opaque to iomap bpf programs Darrick J. Wong
2026-02-23 23:04 ` [PATCHSET v7 1/8] fuse2fs: use fuse iomap data paths for better file I/O performance Darrick J. Wong
2026-02-23 23:36   ` [PATCH 01/19] fuse2fs: implement bare minimum iomap for file mapping reporting Darrick J. Wong
2026-02-23 23:36   ` [PATCH 02/19] fuse2fs: add iomap= mount option Darrick J. Wong
2026-02-23 23:36   ` [PATCH 03/19] fuse2fs: implement iomap configuration Darrick J. Wong
2026-02-23 23:37   ` [PATCH 04/19] fuse2fs: register block devices for use with iomap Darrick J. Wong
2026-02-23 23:37   ` [PATCH 05/19] fuse2fs: implement directio file reads Darrick J. Wong
2026-02-23 23:37   ` [PATCH 06/19] fuse2fs: add extent dump function for debugging Darrick J. Wong
2026-02-23 23:37   ` [PATCH 07/19] fuse2fs: implement direct write support Darrick J. Wong
2026-02-23 23:38   ` [PATCH 08/19] fuse2fs: turn on iomap for pagecache IO Darrick J. Wong
2026-02-23 23:38   ` [PATCH 09/19] fuse2fs: don't zero bytes in punch hole Darrick J. Wong
2026-02-23 23:38   ` [PATCH 10/19] fuse2fs: don't do file data block IO when iomap is enabled Darrick J. Wong
2026-02-23 23:38   ` [PATCH 11/19] fuse2fs: try to create loop device when ext4 device is a regular file Darrick J. Wong
2026-02-23 23:39   ` [PATCH 12/19] fuse2fs: enable file IO to inline data files Darrick J. Wong
2026-02-23 23:39   ` [PATCH 13/19] fuse2fs: set iomap-related inode flags Darrick J. Wong
2026-02-23 23:39   ` [PATCH 14/19] fuse2fs: configure block device block size Darrick J. Wong
2026-02-23 23:39   ` [PATCH 15/19] fuse4fs: separate invalidation Darrick J. Wong
2026-02-23 23:40   ` [PATCH 16/19] fuse2fs: implement statx Darrick J. Wong
2026-02-23 23:40   ` [PATCH 17/19] fuse2fs: enable atomic writes Darrick J. Wong
2026-02-23 23:40   ` [PATCH 18/19] fuse4fs: disable fs reclaim and write throttling Darrick J. Wong
2026-02-23 23:41   ` [PATCH 19/19] fuse2fs: implement freeze and shutdown requests Darrick J. Wong
2026-02-23 23:04 ` [PATCHSET v7 2/8] fuse4fs: specify the root node id Darrick J. Wong
2026-02-23 23:41   ` [PATCH 1/1] fuse4fs: don't use inode number translation when possible Darrick J. Wong
2026-02-23 23:05 ` [PATCHSET v7 3/8] fuse2fs: handle timestamps and ACLs correctly when iomap is enabled Darrick J. Wong
2026-02-23 23:41   ` [PATCH 01/10] fuse2fs: add strictatime/lazytime mount options Darrick J. Wong
2026-02-23 23:41   ` [PATCH 02/10] fuse2fs: skip permission checking on utimens when iomap is enabled Darrick J. Wong
2026-02-23 23:42   ` [PATCH 03/10] fuse2fs: let the kernel tell us about acl/mode updates Darrick J. Wong
2026-02-23 23:42   ` [PATCH 04/10] fuse2fs: better debugging for file mode updates Darrick J. Wong
2026-02-23 23:42   ` [PATCH 05/10] fuse2fs: debug timestamp updates Darrick J. Wong
2026-02-23 23:42   ` [PATCH 06/10] fuse2fs: use coarse timestamps for iomap mode Darrick J. Wong
2026-02-23 23:43   ` [PATCH 07/10] fuse2fs: add tracing for retrieving timestamps Darrick J. Wong
2026-02-23 23:43   ` [PATCH 08/10] fuse2fs: enable syncfs Darrick J. Wong
2026-02-23 23:43   ` [PATCH 09/10] fuse2fs: set sync, immutable, and append at file load time Darrick J. Wong
2026-02-23 23:43   ` [PATCH 10/10] fuse4fs: increase attribute timeout in iomap mode Darrick J. Wong
2026-02-23 23:05 ` [PATCHSET v7 4/8] fuse2fs: cache iomap mappings for even better file IO performance Darrick J. Wong
2026-02-23 23:44   ` [PATCH 1/3] fuse2fs: enable caching of iomaps Darrick J. Wong
2026-02-23 23:44   ` [PATCH 2/3] fuse2fs: constrain iomap mapping cache size Darrick J. Wong
2026-02-23 23:44   ` [PATCH 3/3] fuse2fs: enable iomap Darrick J. Wong
2026-02-23 23:05 ` [PATCHSET v7 5/8] fuse2fs: improve block and inode caching Darrick J. Wong
2026-02-23 23:44   ` [PATCH 1/6] libsupport: add caching IO manager Darrick J. Wong
2026-02-23 23:45   ` [PATCH 2/6] iocache: add the actual buffer cache Darrick J. Wong
2026-02-23 23:45   ` [PATCH 3/6] iocache: bump buffer mru priority every 50 accesses Darrick J. Wong
2026-02-23 23:45   ` [PATCH 4/6] fuse2fs: enable caching IO manager Darrick J. Wong
2026-02-23 23:45   ` [PATCH 5/6] fuse2fs: increase inode cache size Darrick J. Wong
2026-02-23 23:46   ` [PATCH 6/6] libext2fs: improve caching for inodes Darrick J. Wong
2026-02-23 23:05 ` [PATCHSET v7 6/8] fuse4fs: run servers as a contained service Darrick J. Wong
2026-02-23 23:46   ` [PATCH 1/8] libext2fs: fix MMP code to work with unixfd IO manager Darrick J. Wong
2026-02-23 23:46   ` Darrick J. Wong [this message]
2026-02-23 23:47   ` [PATCH 3/8] fuse4fs: set proc title when in fuse service mode Darrick J. Wong
2026-02-23 23:47   ` [PATCH 4/8] fuse4fs: upsert first file mapping to kernel on open Darrick J. Wong
2026-02-23 23:47   ` [PATCH 5/8] fuse4fs: set iomap backing device blocksize Darrick J. Wong
2026-02-23 23:47   ` [PATCH 6/8] fuse4fs: ask for loop devices when opening via fuservicemount Darrick J. Wong
2026-02-23 23:48   ` [PATCH 7/8] fuse4fs: make MMP work correctly in safe service mode Darrick J. Wong
2026-02-23 23:48   ` [PATCH 8/8] debian: update packaging for fuse4fs service Darrick J. Wong
2026-02-23 23:06 ` [PATCHSET v7 7/8] fuse4fs: reclaim buffer cache under memory pressure Darrick J. Wong
2026-02-23 23:48   ` [PATCH 1/4] libsupport: add pressure stall monitor Darrick J. Wong
2026-02-23 23:48   ` [PATCH 2/4] fuse2fs: only reclaim buffer cache when there is memory pressure Darrick J. Wong
2026-02-23 23:49   ` [PATCH 3/4] fuse4fs: enable memory pressure monitoring with service containers Darrick J. Wong
2026-02-23 23:49   ` [PATCH 4/4] fuse2fs: flush dirty metadata periodically Darrick J. Wong
2026-02-23 23:06 ` [PATCHSET RFC 8/8] fuse: allow fuse servers to upload iomap BPF programs Darrick J. Wong
2026-02-23 23:49   ` [PATCH 1/3] fuse4fs: add dynamic iomap bpf prototype which will break FIEMAP Darrick J. Wong
2026-02-23 23:49   ` [PATCH 2/3] fuse4fs: wire up caching examples to fuse iomap bpf program Darrick J. Wong
2026-02-23 23:50   ` [PATCH 3/3] fuse4fs: adjust test bpf program to deal with opaque inodes Darrick J. Wong
2026-03-16 17:56 ` [PATCHBLIZZARD v7] fuse/libfuse/e2fsprogs: containerize ext4 for safer operation Joanne Koong
2026-03-16 18:04   ` Darrick J. Wong
2026-03-16 23:08     ` Joanne Koong
2026-03-16 23:41       ` Darrick J. Wong
2026-03-17  0:20         ` Demi Marie Obenour
2026-03-17 13:59           ` Theodore Tso
2026-03-17 14:05             ` Demi Marie Obenour
2026-03-17 15:20               ` Theodore Tso
2026-03-18 21:31           ` Darrick J. Wong
2026-03-19  7:28             ` Demi Marie Obenour
2026-03-19 16:08               ` Darrick J. Wong
2026-03-20 17:04                 ` Joanne Koong
2026-03-20 20:31                   ` Darrick J. Wong
2026-03-17  0:10       ` Demi Marie Obenour

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=177188745992.3944907.2684603430792948652.stgit@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=bernd@bsbernd.com \
    --cc=bpf@vger.kernel.org \
    --cc=joannelkoong@gmail.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=neal@gompa.dev \
    --cc=tytso@mit.edu \
    /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