[PATCH -next v5 32/32] ext4: introduce a mount option for iomap buffered I/O path
From: Zhang Yi
Date: Fri Aug 14 2026 - 05:58:20 EST
From: Zhang Yi <yi.zhang@xxxxxxxxxx>
Since the iomap buffered I/O path does not yet support all existing ext4
features, it cannot be enabled by default. Introduce the
'buffered_iomap' and 'nobuffered_iomap' mount options to explicitly
enable or disable the iomap buffered I/O path for regular files.
Toggling this option via remount is allowed. The change of I/O path will
not take effect immediately. It will be deferred. The new setting will
only take effect after the inode is re-initialized (i.e., after the last
reference is dropped and the inode is re-read from disk).
Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx>
---
fs/ext4/ext4.h | 1 +
fs/ext4/inode.c | 6 ++++++
fs/ext4/super.c | 7 +++++++
3 files changed, 14 insertions(+)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 405e256a1802..8cfe77b45e21 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1321,6 +1321,7 @@ struct ext4_inode_info {
* scanning in mballoc
*/
#define EXT4_MOUNT2_ABORT 0x00000100 /* Abort filesystem */
+#define EXT4_MOUNT2_BUFFERED_IOMAP 0x00000200 /* Use iomap for buffered I/O */
#define clear_opt(sb, opt) EXT4_SB(sb)->s_mount_opt &= \
~EXT4_MOUNT_##opt
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c9ee78fba4d0..c7466ecc44c2 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -6080,11 +6080,17 @@ static int check_igot_inode(struct inode *inode, ext4_iget_flags flags,
* For extent-to-indirect block migration (via EXT4_IOC_SETFLAGS
* clearing EXT4_EXTENTS_FL), this operation is directly rejected for
* inodes using the iomap path.
+ *
+ * When remounting to toggle the buffered_iomap mount option, the change
+ * of I/O path is deferred as well, it will be available after the inode
+ * is re-initialized.
*/
void ext4_enable_buffered_iomap(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
+ if (!test_opt2(sb, BUFFERED_IOMAP))
+ return;
if (!S_ISREG(inode->i_mode))
return;
if (ext4_test_inode_flag(inode, EXT4_INODE_EA_INODE))
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 86ed5228dbe9..0855f9801df4 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1746,6 +1746,7 @@ enum {
Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
Opt_max_dir_size_kb, Opt_nojournal_checksum, Opt_nombcache,
Opt_no_prefetch_block_bitmaps, Opt_mb_optimize_scan,
+ Opt_buffered_iomap, Opt_nobuffered_iomap,
Opt_errors, Opt_data, Opt_data_err, Opt_jqfmt, Opt_dax_type,
#ifdef CONFIG_EXT4_DEBUG
Opt_fc_debug_max_replay, Opt_fc_debug_force
@@ -1884,6 +1885,8 @@ static const struct fs_parameter_spec ext4_param_specs[] = {
fsparam_flag ("no_prefetch_block_bitmaps",
Opt_no_prefetch_block_bitmaps),
fsparam_s32 ("mb_optimize_scan", Opt_mb_optimize_scan),
+ fsparam_flag ("buffered_iomap", Opt_buffered_iomap),
+ fsparam_flag ("nobuffered_iomap", Opt_nobuffered_iomap),
fsparam_string ("check", Opt_removed), /* mount option from ext2/3 */
fsparam_flag ("nocheck", Opt_removed), /* mount option from ext2/3 */
fsparam_flag ("reservation", Opt_removed), /* mount option from ext2/3 */
@@ -1977,6 +1980,10 @@ static const struct mount_opts {
{Opt_nombcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET},
{Opt_no_prefetch_block_bitmaps, EXT4_MOUNT_NO_PREFETCH_BLOCK_BITMAPS,
MOPT_SET},
+ {Opt_buffered_iomap, EXT4_MOUNT2_BUFFERED_IOMAP,
+ MOPT_SET | MOPT_2 | MOPT_EXT4_ONLY},
+ {Opt_nobuffered_iomap, EXT4_MOUNT2_BUFFERED_IOMAP,
+ MOPT_CLEAR | MOPT_2 | MOPT_EXT4_ONLY},
#ifdef CONFIG_EXT4_DEBUG
{Opt_fc_debug_force, EXT4_MOUNT2_JOURNAL_FAST_COMMIT,
MOPT_SET | MOPT_2 | MOPT_EXT4_ONLY},
--
2.52.0