[PATCH 12/16] fuse2fs: don't zero bytes in punch hole

Darrick J. Wong
2025-05-22T00:13:59Z

When iomap is in use for the pagecache, it will take care of zeroing the
unaligned parts of punched out regions so we don't have to do it
ourselves.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
misc/fuse2fs.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index fe6d97324c1f57..aeb2b6fbc28401 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -152,6 +152,7 @@ enum fuse2fs_iomap_state {
IOMAP_DISABLED,
IOMAP_UNKNOWN,
IOMAP_ENABLED,
+ IOMAP_FILEIO, /* enabled and does all file data block IO */
};
#endif

@@ -1040,6 +1041,7 @@ static errcode_t confirm_iomap(struct fuse_conn_info *conn, struct fuse2fs *ff)
/* fallthrough */;
case IOMAP_DISABLED:
return 0;
+ case IOMAP_FILEIO:
case IOMAP_ENABLED:
break;
}
@@ -1059,11 +1061,17 @@ static errcode_t confirm_iomap(struct fuse_conn_info *conn, struct fuse2fs *ff)

static int iomap_enabled(const struct fuse2fs *ff)
{
- return ff->iomap_state == IOMAP_ENABLED;
+ return ff->iomap_state >= IOMAP_ENABLED;
+}
+
+static int iomap_does_fileio(const struct fuse2fs *ff)
+{
+ return ff->iomap_state == IOMAP_FILEIO;
}
#else
# define confirm_iomap(...) (0)
# define iomap_enabled(...) (0)
+# define iomap_does_fileio(...) (0)
#endif

static void *op_init(struct fuse_conn_info *conn
@@ -1100,6 +1108,20 @@ static void *op_init(struct fuse_conn_info *conn
if (ff->iomap_state != IOMAP_DISABLED &&
fuse_set_feature_flag(conn, FUSE_CAP_IOMAP))
ff->iomap_state = IOMAP_ENABLED;
+
+ /*
+ * If iomap is turned on and the kernel advertises support for both
+ * direct and pagecache IO, then that means the kernel handles all
+ * regular file data block IO for us. That means we can turn off all
+ * of libext2fs' file data block handling except for inline data.
+ *
+ * XXX: kernel doesn't support inline data iomap
+ */
+ if (iomap_enabled(ff) &&
+ fuse_get_feature_flag(conn, FUSE_CAP_IOMAP_DIRECTIO) &&
+ fuse_get_feature_flag(conn, FUSE_CAP_IOMAP_PAGECACHE))
+ ff->iomap_state = IOMAP_FILEIO;
+
/*
* In iomap mode, the kernel writes file data directly to the block
* device and does not flush the bdev page cache. We must open the
@@ -4580,6 +4602,10 @@ static errcode_t clean_block_middle(struct fuse2fs *ff, ext2_ino_t ino,
int retflags;
errcode_t err;

+ /* the kernel does this for us in iomap mode */
+ if (iomap_does_fileio(ff))
+ return 0;
+
residue = FUSE2FS_OFF_IN_FSB(ff, offset);
if (residue == 0)
return 0;
@@ -4617,6 +4643,10 @@ static errcode_t clean_block_edge(struct fuse2fs *ff, ext2_ino_t ino,
off_t residue;
errcode_t err;

+ /* the kernel does this for us in iomap mode */
+ if (iomap_does_fileio(ff))
+ return 0;
+
residue = FUSE2FS_OFF_IN_FSB(ff, offset);
if (residue == 0)
return 0;