public inbox for linux-ext4@vger.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: tytso@mit.edu
Cc: bernd@bsbernd.com, miklos@szeredi.hu, linux-ext4@vger.kernel.org,
	neal@gompa.dev, linux-fsdevel@vger.kernel.org,
	fuse-devel@lists.linux.dev, joannelkoong@gmail.com
Subject: [PATCH 11/19] fuse2fs: try to create loop device when ext4 device is a regular file
Date: Wed, 29 Apr 2026 07:55:30 -0700	[thread overview]
Message-ID: <177747214733.4107473.11688396903521099167.stgit@frogsfrogsfrogs> (raw)
In-Reply-To: <177747214459.4107473.9520724883867588970.stgit@frogsfrogsfrogs>

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

If the filesystem device is a regular file, try to create a loop device
for it so that we can take advantage of iomap.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 configure         |   41 +++++++++++++++++++
 configure.ac      |   23 +++++++++++
 fuse4fs/fuse4fs.c |  116 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 lib/config.h.in   |    3 +
 misc/fuse2fs.c    |  113 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 292 insertions(+), 4 deletions(-)


diff --git a/configure b/configure
index 344c7af2ee48f8..ba1556b34257a6 100755
--- a/configure
+++ b/configure
@@ -14691,6 +14691,47 @@ printf "%s\n" "#define HAVE_FUSE_IOMAP 1" >>confdefs.h
 
 fi
 
+if test -n "$have_fuse_iomap"; then
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fuse_loopdev.h in libfuse" >&5
+printf %s "checking for fuse_loopdev.h in libfuse... " >&6; }
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+	#define _GNU_SOURCE
+	#define _FILE_OFFSET_BITS	64
+	#define FUSE_USE_VERSION	399
+	#include <fuse_loopdev.h>
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  have_fuse_loopdev=yes
+	   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+else case e in #(
+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; } ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+if test -n "$have_fuse_loopdev"
+then
+
+printf "%s\n" "#define HAVE_FUSE_LOOPDEV 1" >>confdefs.h
+
+fi
+
 have_fuse_lowlevel=
 if test -n "$FUSE_USE_VERSION"
 then
diff --git a/configure.ac b/configure.ac
index 8d85e9966877ea..8cfde4d85489e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1432,6 +1432,29 @@ then
 	AC_DEFINE(HAVE_FUSE_IOMAP, 1, [Define to 1 if fuse supports iomap])
 fi
 
+dnl
+dnl Check if fuse library has fuse_loopdev.h, which it only gained after adding
+dnl iomap support.
+dnl
+if test -n "$have_fuse_iomap"; then
+	AC_MSG_CHECKING(for fuse_loopdev.h in libfuse)
+	AC_LINK_IFELSE(
+	[	AC_LANG_PROGRAM([[
+	#define _GNU_SOURCE
+	#define _FILE_OFFSET_BITS	64
+	#define FUSE_USE_VERSION	399
+	#include <fuse_loopdev.h>
+		]], [[
+		]])
+	], have_fuse_loopdev=yes
+	   AC_MSG_RESULT(yes),
+	   AC_MSG_RESULT(no))
+fi
+if test -n "$have_fuse_loopdev"
+then
+	AC_DEFINE(HAVE_FUSE_LOOPDEV, 1, [Define to 1 if fuse supports loopdev operations])
+fi
+
 dnl
 dnl Check if the FUSE lowlevel library is supported
 dnl
diff --git a/fuse4fs/fuse4fs.c b/fuse4fs/fuse4fs.c
index 68f1f7c02df223..3c3debb6f60ac7 100644
--- a/fuse4fs/fuse4fs.c
+++ b/fuse4fs/fuse4fs.c
@@ -27,6 +27,9 @@
 #include <unistd.h>
 #include <ctype.h>
 #include <assert.h>
+#ifdef HAVE_FUSE_LOOPDEV
+# include <fuse_loopdev.h>
+#endif
 #define FUSE_DARWIN_ENABLE_EXTENSIONS 0
 #ifdef __SET_FOB_FOR_FUSE
 # error Do not set magic value __SET_FOB_FOR_FUSE!!!!
@@ -262,6 +265,10 @@ struct fuse4fs {
 	pthread_mutex_t bfl;
 	char *device;
 	char *shortdev;
+#ifdef HAVE_FUSE_LOOPDEV
+	char *loop_device;
+	int loop_fd;
+#endif
 
 	/* options set by fuse_opt_parse must be of type int */
 	int ro;
@@ -285,6 +292,7 @@ struct fuse4fs {
 	enum fuse4fs_feature_toggle iomap_want;
 	enum fuse4fs_iomap_state iomap_state;
 	uint32_t iomap_dev;
+	uint64_t iomap_cap;
 #endif
 	unsigned int blockmask;
 	unsigned long offset;
@@ -913,8 +921,23 @@ static inline int fuse4fs_iomap_enabled(const struct fuse4fs *ff)
 {
 	return ff->iomap_state >= IOMAP_ENABLED;
 }
+
+static inline void fuse4fs_discover_iomap(struct fuse4fs *ff)
+{
+	if (ff->iomap_want == FT_DISABLE)
+		return;
+
+	ff->iomap_cap = fuse_lowlevel_discover_iomap(-1);
+}
+
+static inline bool fuse4fs_can_iomap(const struct fuse4fs *ff)
+{
+	return ff->iomap_cap & FUSE_IOMAP_SUPPORT_FILEIO;
+}
 #else
 # define fuse4fs_iomap_enabled(...)	(0)
+# define fuse4fs_discover_iomap(...)	((void)0)
+# define fuse4fs_can_iomap(...)		(false)
 #endif
 
 static inline void fuse4fs_dump_extents(struct fuse4fs *ff, ext2_ino_t ino,
@@ -1584,6 +1607,76 @@ static void fuse4fs_release_lockfile(struct fuse4fs *ff)
 	free(ff->lockfile);
 }
 
+#ifdef HAVE_FUSE_LOOPDEV
+static int fuse4fs_try_losetup(struct fuse4fs *ff, int flags)
+{
+	bool rw = flags & EXT2_FLAG_RW;
+	int dev_fd;
+	int ret;
+
+	/*
+	 * Only transform a regular file into a loopdev for iomap, and only if
+	 * the service helper isn't required to that for us.
+	 */
+	if (!fuse4fs_can_iomap(ff) || 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) {
+		err_printf(ff, "%s: %s\n", _("while opening fs"),
+			   error_message(errno));
+		return -1;
+	}
+
+	ret = fuse_loopdev_setup(dev_fd, rw ? O_RDWR : O_RDONLY, ff->device, 5,
+				 &ff->loop_fd, &ff->loop_device);
+	if (ret == -EBUSY) {
+		/*
+		 * If the setup function returned EBUSY, there is already a
+		 * loop device backed by this file.  Report that the file is
+		 * already in use.  Ignore the other errors because we can
+		 * otherwise handle filesystem in a file.
+		 */
+		err_printf(ff, "%s: %s\n", _("while opening fs loopdev"),
+				   error_message(errno));
+		close(dev_fd);
+		return -1;
+	}
+
+	close(dev_fd);
+	return 0;
+}
+
+static void fuse4fs_detach_losetup(struct fuse4fs *ff)
+{
+	if (ff->loop_fd >= 0)
+		close(ff->loop_fd);
+	ff->loop_fd = -1;
+}
+
+static void fuse4fs_undo_losetup(struct fuse4fs *ff)
+{
+	fuse4fs_detach_losetup(ff);
+	free(ff->loop_device);
+	ff->loop_device = NULL;
+}
+
+static inline const char *fuse4fs_device(const struct fuse4fs *ff)
+{
+	/*
+	 * If we created a loop device for the file passed in, open that.
+	 * Otherwise open the path the user gave us.
+	 */
+	return ff->loop_device ? ff->loop_device : ff->device;
+}
+#else
+# define fuse4fs_try_losetup(...)	(0)
+# define fuse4fs_detach_losetup(...)	((void)0)
+# define fuse4fs_undo_losetup(...)	((void)0)
+# define fuse4fs_device(ff)		((ff)->device)
+#endif
+
 static void fuse4fs_unmount(struct fuse4fs *ff)
 {
 	char uuid[UUID_STR_SIZE];
@@ -1607,6 +1700,7 @@ static void fuse4fs_unmount(struct fuse4fs *ff)
 	}
 
 	fuse4fs_service_close_bdev(ff);
+	fuse4fs_undo_losetup(ff);
 
 	if (ff->lockfile)
 		fuse4fs_release_lockfile(ff);
@@ -1620,6 +1714,8 @@ static errcode_t fuse4fs_open(struct fuse4fs *ff)
 		    EXT2_FLAG_EXCLUSIVE | EXT2_FLAG_WRITE_FULL_SUPER;
 	errcode_t err;
 
+	fuse4fs_discover_iomap(ff);
+
 	if (ff->lockfile) {
 		err = fuse4fs_acquire_lockfile(ff);
 		if (err)
@@ -1632,6 +1728,12 @@ static errcode_t fuse4fs_open(struct fuse4fs *ff)
 	if (ff->directio)
 		flags |= EXT2_FLAG_DIRECT_IO;
 
+	dbg_printf(ff, "opening with flags=0x%x\n", flags);
+
+	err = fuse4fs_try_losetup(ff, flags);
+	if (err)
+		return err;
+
 	/*
 	 * If the filesystem is stored on a block device, the _EXCLUSIVE flag
 	 * causes libext2fs to try to open the block device with O_EXCL.  If
@@ -1666,8 +1768,8 @@ static errcode_t fuse4fs_open(struct fuse4fs *ff)
 		if (fuse4fs_is_service(ff))
 			err = fuse4fs_service_openfs(ff, options, &flags);
 		else
-			err = ext2fs_open2(ff->device, options, flags, 0, 0,
-					   unix_io_manager, &ff->fs);
+			err = ext2fs_open2(fuse4fs_device(ff), options, flags,
+					   0, 0, unix_io_manager, &ff->fs);
 		if ((err == EPERM || err == EACCES) &&
 		    (!ff->ro || (flags & EXT2_FLAG_RW))) {
 			/*
@@ -1681,6 +1783,11 @@ static errcode_t fuse4fs_open(struct fuse4fs *ff)
 			flags &= ~EXT2_FLAG_RW;
 			ff->ro = 1;
 
+			fuse4fs_undo_losetup(ff);
+			err = fuse4fs_try_losetup(ff, flags);
+			if (err)
+				return err;
+
 			/* Force the loop to run once more */
 			err = -1;
 		}
@@ -2129,6 +2236,8 @@ static void op_init(void *userdata, struct fuse_conn_info *conn)
 	fuse4fs_iomap_enable(conn, ff);
 	conn->time_gran = 1;
 
+	fuse4fs_detach_losetup(ff);
+
 	if (ff->opstate == F4OP_WRITABLE)
 		fuse4fs_read_bitmaps(ff);
 
@@ -7737,6 +7846,9 @@ int main(int argc, char *argv[])
 		.iomap_want = FT_DEFAULT,
 		.iomap_state = IOMAP_UNKNOWN,
 		.iomap_dev = FUSE_IOMAP_DEV_NULL,
+#endif
+#ifdef HAVE_FUSE_LOOPDEV
+		.loop_fd = -1,
 #endif
 	};
 	errcode_t err;
diff --git a/lib/config.h.in b/lib/config.h.in
index 58338cc926590e..96ed5479181a5b 100644
--- a/lib/config.h.in
+++ b/lib/config.h.in
@@ -151,6 +151,9 @@
 /* Define to 1 if fuse supports iomap */
 #undef HAVE_FUSE_IOMAP
 
+/* Define to 1 if fuse supports loopdev operations */
+#undef HAVE_FUSE_LOOPDEV
+
 /* Define to 1 if fuse supports lowlevel API */
 #undef HAVE_FUSE_LOWLEVEL
 
diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index f7653dc6c20c3f..3c76eba683a10d 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -25,6 +25,9 @@
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <ctype.h>
+#ifdef HAVE_FUSE_LOOPDEV
+# include <fuse_loopdev.h>
+#endif
 #define FUSE_DARWIN_ENABLE_EXTENSIONS 0
 #ifdef __SET_FOB_FOR_FUSE
 # error Do not set magic value __SET_FOB_FOR_FUSE!!!!
@@ -245,6 +248,10 @@ struct fuse2fs {
 	pthread_mutex_t bfl;
 	char *device;
 	char *shortdev;
+#ifdef HAVE_FUSE_LOOPDEV
+	char *loop_device;
+	int loop_fd;
+#endif
 
 	/* options set by fuse_opt_parse must be of type int */
 	int ro;
@@ -268,6 +275,7 @@ struct fuse2fs {
 	enum fuse2fs_feature_toggle iomap_want;
 	enum fuse2fs_iomap_state iomap_state;
 	uint32_t iomap_dev;
+	uint64_t iomap_cap;
 #endif
 	unsigned int blockmask;
 	unsigned long offset;
@@ -725,9 +733,23 @@ static inline int fuse2fs_iomap_enabled(const struct fuse2fs *ff)
 {
 	return ff->iomap_state >= IOMAP_ENABLED;
 }
+
+static inline void fuse2fs_discover_iomap(struct fuse2fs *ff)
+{
+	if (ff->iomap_want == FT_DISABLE)
+		return;
+
+	ff->iomap_cap = fuse_lowlevel_discover_iomap(-1);
+}
+
+static inline bool fuse2fs_can_iomap(const struct fuse2fs *ff)
+{
+	return ff->iomap_cap & FUSE_IOMAP_SUPPORT_FILEIO;
+}
 #else
 # define fuse2fs_iomap_enabled(...)	(0)
-# define fuse2fs_iomap_enabled(...)	(0)
+# define fuse2fs_discover_iomap(...)	((void)0)
+# define fuse2fs_can_iomap(...)		(false)
 #endif
 
 static inline void fuse2fs_dump_extents(struct fuse2fs *ff, ext2_ino_t ino,
@@ -1201,6 +1223,73 @@ static void fuse2fs_release_lockfile(struct fuse2fs *ff)
 	free(ff->lockfile);
 }
 
+#ifdef HAVE_FUSE_LOOPDEV
+static int fuse2fs_try_losetup(struct fuse2fs *ff, int flags)
+{
+	bool rw = flags & EXT2_FLAG_RW;
+	int dev_fd;
+	int ret;
+
+	/* Only transform a regular file into a loopdev for iomap */
+	if (!fuse2fs_can_iomap(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) {
+		err_printf(ff, "%s: %s\n", _("while opening fs"),
+			   error_message(errno));
+		return -1;
+	}
+
+	ret = fuse_loopdev_setup(dev_fd, rw ? O_RDWR : O_RDONLY, ff->device, 5,
+				 &ff->loop_fd, &ff->loop_device);
+	if (ret == -EBUSY) {
+		/*
+		 * If the setup function returned EBUSY, there is already a
+		 * loop device backed by this file.  Report that the file is
+		 * already in use.  Ignore the other errors because we can
+		 * otherwise handle filesystem in a file.
+		 */
+		err_printf(ff, "%s: %s\n", _("while opening fs loopdev"),
+				   error_message(-ret));
+		close(dev_fd);
+		return -1;
+	}
+
+	close(dev_fd);
+	return 0;
+}
+
+static void fuse2fs_detach_losetup(struct fuse2fs *ff)
+{
+	if (ff->loop_fd >= 0)
+		close(ff->loop_fd);
+	ff->loop_fd = -1;
+}
+
+static void fuse2fs_undo_losetup(struct fuse2fs *ff)
+{
+	fuse2fs_detach_losetup(ff);
+	free(ff->loop_device);
+	ff->loop_device = NULL;
+}
+
+static inline const char *fuse2fs_device(const struct fuse2fs *ff)
+{
+	/*
+	 * If we created a loop device for the file passed in, open that.
+	 * Otherwise open the path the user gave us.
+	 */
+	return ff->loop_device ? ff->loop_device : ff->device;
+}
+#else
+# define fuse2fs_try_losetup(...)	(0)
+# define fuse2fs_detach_losetup(...)	((void)0)
+# define fuse2fs_undo_losetup(...)	((void)0)
+# define fuse2fs_device(ff)		((ff)->device)
+#endif
+
 static void fuse2fs_unmount(struct fuse2fs *ff)
 {
 	char uuid[UUID_STR_SIZE];
@@ -1218,6 +1307,8 @@ static void fuse2fs_unmount(struct fuse2fs *ff)
 				   uuid);
 	}
 
+	fuse2fs_undo_losetup(ff);
+
 	if (ff->lockfile)
 		fuse2fs_release_lockfile(ff);
 }
@@ -1230,6 +1321,8 @@ static errcode_t fuse2fs_open(struct fuse2fs *ff)
 		    EXT2_FLAG_EXCLUSIVE | EXT2_FLAG_WRITE_FULL_SUPER;
 	errcode_t err;
 
+	fuse2fs_discover_iomap(ff);
+
 	if (ff->lockfile) {
 		err = fuse2fs_acquire_lockfile(ff);
 		if (err)
@@ -1242,6 +1335,12 @@ static errcode_t fuse2fs_open(struct fuse2fs *ff)
 	if (ff->directio)
 		flags |= EXT2_FLAG_DIRECT_IO;
 
+	dbg_printf(ff, "opening with flags=0x%x\n", flags);
+
+	err = fuse2fs_try_losetup(ff, flags);
+	if (err)
+		return err;
+
 	/*
 	 * If the filesystem is stored on a block device, the _EXCLUSIVE flag
 	 * causes libext2fs to try to open the block device with O_EXCL.  If
@@ -1273,7 +1372,7 @@ static errcode_t fuse2fs_open(struct fuse2fs *ff)
 	 */
 	deadline = init_deadline(FUSE2FS_OPEN_TIMEOUT);
 	do {
-		err = ext2fs_open2(ff->device, options, flags, 0, 0,
+		err = ext2fs_open2(fuse2fs_device(ff), options, flags, 0, 0,
 				   unix_io_manager, &ff->fs);
 		if ((err == EPERM || err == EACCES) &&
 		    (!ff->ro || (flags & EXT2_FLAG_RW))) {
@@ -1288,6 +1387,11 @@ static errcode_t fuse2fs_open(struct fuse2fs *ff)
 			flags &= ~EXT2_FLAG_RW;
 			ff->ro = 1;
 
+			fuse2fs_undo_losetup(ff);
+			err = fuse2fs_try_losetup(ff, flags);
+			if (err)
+				return err;
+
 			/* Force the loop to run once more */
 			err = -1;
 		}
@@ -1744,6 +1848,8 @@ static void *op_init(struct fuse_conn_info *conn,
 		cfg->debug = 1;
 	cfg->nullpath_ok = 1;
 
+	fuse2fs_detach_losetup(ff);
+
 	if (ff->opstate == F2OP_WRITABLE)
 		fuse2fs_read_bitmaps(ff);
 
@@ -6852,6 +6958,9 @@ int main(int argc, char *argv[])
 		.iomap_want = FT_DEFAULT,
 		.iomap_state = IOMAP_UNKNOWN,
 		.iomap_dev = FUSE_IOMAP_DEV_NULL,
+#endif
+#ifdef HAVE_FUSE_LOOPDEV
+		.loop_fd = -1,
 #endif
 	};
 	errcode_t err;


  parent reply	other threads:[~2026-04-29 14:55 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-29 14:12 [PATCHBLIZZARD v8] fuse/libfuse/e2fsprogs: faster file IO for containerized ext4 servers Darrick J. Wong
2026-04-29 14:20 ` [PATCHSET v8 1/6] libext2fs: refactoring for fuse2fs iomap support Darrick J. Wong
2026-04-29 14:51   ` [PATCH 1/5] libext2fs: invalidate cached blocks when freeing them Darrick J. Wong
2026-04-29 14:51   ` [PATCH 2/5] libext2fs: only flush affected blocks in unix_write_byte Darrick J. Wong
2026-04-29 14:52   ` [PATCH 3/5] libext2fs: allow unix_write_byte when the write would be aligned Darrick J. Wong
2026-04-29 14:52   ` [PATCH 4/5] libext2fs: allow clients to ask to write full superblocks Darrick J. Wong
2026-04-29 14:52   ` [PATCH 5/5] libext2fs: allow callers to disallow I/O to file data blocks Darrick J. Wong
2026-04-29 14:20 ` [PATCHSET v8 2/6] fuse2fs: use fuse iomap data paths for better file I/O performance Darrick J. Wong
2026-04-29 14:52   ` [PATCH 01/19] fuse2fs: implement bare minimum iomap for file mapping reporting Darrick J. Wong
2026-04-29 14:53   ` [PATCH 02/19] fuse2fs: add iomap= mount option Darrick J. Wong
2026-04-29 14:53   ` [PATCH 03/19] fuse2fs: implement iomap configuration Darrick J. Wong
2026-04-29 14:53   ` [PATCH 04/19] fuse2fs: register block devices for use with iomap Darrick J. Wong
2026-04-29 14:53   ` [PATCH 05/19] fuse2fs: implement directio file reads Darrick J. Wong
2026-04-29 14:54   ` [PATCH 06/19] fuse2fs: add extent dump function for debugging Darrick J. Wong
2026-04-29 14:54   ` [PATCH 07/19] fuse2fs: implement direct write support Darrick J. Wong
2026-04-29 14:54   ` [PATCH 08/19] fuse2fs: turn on iomap for pagecache IO Darrick J. Wong
2026-04-29 14:54   ` [PATCH 09/19] fuse2fs: don't zero bytes in punch hole Darrick J. Wong
2026-04-29 14:55   ` [PATCH 10/19] fuse2fs: don't do file data block IO when iomap is enabled Darrick J. Wong
2026-04-29 14:55   ` Darrick J. Wong [this message]
2026-04-29 14:55   ` [PATCH 12/19] fuse2fs: enable file IO to inline data files Darrick J. Wong
2026-04-29 14:56   ` [PATCH 13/19] fuse2fs: set iomap-related inode flags Darrick J. Wong
2026-04-29 14:56   ` [PATCH 14/19] fuse2fs: configure block device block size Darrick J. Wong
2026-04-29 14:56   ` [PATCH 15/19] fuse4fs: separate invalidation Darrick J. Wong
2026-04-29 14:56   ` [PATCH 16/19] fuse2fs: implement statx Darrick J. Wong
2026-04-29 14:57   ` [PATCH 17/19] fuse2fs: enable atomic writes Darrick J. Wong
2026-04-29 14:57   ` [PATCH 18/19] fuse4fs: disable fs reclaim and write throttling Darrick J. Wong
2026-04-29 14:57   ` [PATCH 19/19] fuse2fs: implement freeze and shutdown requests Darrick J. Wong
2026-04-29 14:20 ` [PATCHSET v8 3/6] fuse4fs: adapt iomap for fuse services Darrick J. Wong
2026-04-29 14:57   ` [PATCH 1/3] fuse4fs: configure iomap when running as a service Darrick J. Wong
2026-04-29 14:58   ` [PATCH 2/3] fuse4fs: set iomap backing device blocksize Darrick J. Wong
2026-04-29 14:58   ` [PATCH 3/3] fuse4fs: ask for loop devices when opening via fuservicemount Darrick J. Wong
2026-04-29 14:21 ` [PATCHSET v8 4/6] fuse4fs: specify the root node id Darrick J. Wong
2026-04-29 14:58   ` [PATCH 1/1] fuse4fs: don't use inode number translation when possible Darrick J. Wong
2026-04-29 14:21 ` [PATCHSET v8 5/6] fuse2fs: handle timestamps and ACLs correctly when iomap is enabled Darrick J. Wong
2026-04-29 14:58   ` [PATCH 01/10] fuse2fs: add strictatime/lazytime mount options Darrick J. Wong
2026-04-29 14:59   ` [PATCH 02/10] fuse2fs: skip permission checking on utimens when iomap is enabled Darrick J. Wong
2026-04-29 14:59   ` [PATCH 03/10] fuse2fs: let the kernel tell us about acl/mode updates Darrick J. Wong
2026-04-29 14:59   ` [PATCH 04/10] fuse2fs: better debugging for file mode updates Darrick J. Wong
2026-04-29 14:59   ` [PATCH 05/10] fuse2fs: debug timestamp updates Darrick J. Wong
2026-04-29 15:00   ` [PATCH 06/10] fuse2fs: use coarse timestamps for iomap mode Darrick J. Wong
2026-04-29 15:00   ` [PATCH 07/10] fuse2fs: add tracing for retrieving timestamps Darrick J. Wong
2026-04-29 15:00   ` [PATCH 08/10] fuse2fs: enable syncfs Darrick J. Wong
2026-04-29 15:00   ` [PATCH 09/10] fuse2fs: set sync, immutable, and append at file load time Darrick J. Wong
2026-04-29 15:01   ` [PATCH 10/10] fuse4fs: increase attribute timeout in iomap mode Darrick J. Wong
2026-04-29 14:21 ` [PATCHSET v8 6/6] fuse2fs: cache iomap mappings for even better file IO performance Darrick J. Wong
2026-04-29 15:01   ` [PATCH 1/4] fuse2fs: enable caching of iomaps Darrick J. Wong
2026-04-29 15:01   ` [PATCH 2/4] fuse2fs: constrain iomap mapping cache size Darrick J. Wong
2026-04-29 15:02   ` [PATCH 3/4] fuse4fs: upsert first file mapping to kernel on open Darrick J. Wong
2026-04-29 15:02   ` [PATCH 4/4] fuse2fs: enable iomap Darrick J. Wong
  -- strict thread matches above, loose matches on Subject: below --
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:38 ` [PATCH 11/19] fuse2fs: try to create loop device when ext4 device is a regular file 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=177747214733.4107473.11688396903521099167.stgit@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=bernd@bsbernd.com \
    --cc=fuse-devel@lists.linux.dev \
    --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