Re: [PATCH v6 08/31] ext4: avoid unnecessary transaction in ext4_map_blocks() for unwritten extents
From: Ojaswin Mujoo
Date: Mon Sep 28 2026 - 06:22:14 EST
On Thu, Sep 03, 2026 at 08:35:20PM +0800, Zhang Yi wrote:
> From: Zhang Yi <yi.zhang@xxxxxxxxxx>
>
> When ext4_map_blocks() finds an unwritten extent in the extent cache and
> the caller is willing to accept unwritten extents without conversion,
> there is no need to start a journal transaction since no metadata update
> is required. This avoids unnecessary transaction overhead in the
> upcoming iomap writeback path when overwriting already-allocated
> unwritten extents.
>
> One thing to be careful about, as the comment in ext4_map_blocks()
> states, if the flags contain EXT4_GET_BLOCKS_CREATE, the function will
> mark @map as mapped.
>
> Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx>
Yeahh, I had something similar in one of my WIP branches :)
Thanks for taking care of this. Feel free to add:
Reviewed-by: Ojaswin Mujoo <ojaswin@xxxxxxxxxxxxx>
Regards,
ojaswin
> ---
> fs/ext4/inode.c | 19 ++++++++++++++-----
> 1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index c9dea4ca5caf..7a5c74af8ff3 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -809,14 +809,23 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
> * Note that if blocks have been preallocated
> * ext4_ext_map_blocks() returns with buffer head unmapped
> */
> - if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED)
> + if (retval > 0) {
> /*
> - * If we need to convert extent to unwritten
> - * we continue and do the actual work in
> - * ext4_ext_map_blocks()
> + * If we need to convert written extent to unwritten or
> + * convert unwritten extent to written, continue and do
> + * the actual work in ext4_ext_map_blocks().
> */
> - if (!(flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN))
> + if (map->m_flags & EXT4_MAP_MAPPED &&
> + !(flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN))
> goto out_handle;
> + if (map->m_flags & EXT4_MAP_UNWRITTEN &&
> + (flags & EXT4_GET_BLOCKS_UNWRIT_EXT) &&
> + !(flags & EXT4_GET_BLOCKS_CONVERT)) {
> + /* Contains EXT4_GET_BLOCKS_CREATE - mark mapped. */
> + map->m_flags |= EXT4_MAP_MAPPED;
> + goto out_handle;
> + }
> + }
>
> if (!handle) {
> handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
> --
> 2.52.0
>