Re: [PATCH v4 05/23] ext4: implement buffered read path using iomap

From: Ojaswin Mujoo

Date: Tue May 19 2026 - 06:10:46 EST


On Mon, May 11, 2026 at 03:23:25PM +0800, Zhang Yi wrote:
> From: Zhang Yi <yi.zhang@xxxxxxxxxx>
>
> Implement the iomap read path for ext4 by introducing a new
> ext4_iomap_buffered_read_ops instance. This provides the read_folio()
> and readahead() callbacks for ext4_iomap_aops. The implementation
> introduces:
>
> - ext4_iomap_map_blocks(): Helper function to query extent mappings for
> a given read range using ext4_map_blocks() and convert the mapping
> information to iomap type
> - ext4_iomap_buffered_read_begin(): The iomap_begin callback that maps
> blocks, validates filesystem state, and populates the iomap. It
> returns -ERANGE for inline data which is not yet supported.
>
> Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx>
> Reviewed-by: Jan Kara <jack@xxxxxxx>

Looks good, feel free to add:

Reviewed-by: Ojaswin Mujoo <ojaswin@xxxxxxxxxxxxx>

Regards,
Ojaswin

> ---
> fs/ext4/inode.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 178ac2be37b7..6c4d9137b279 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -3908,14 +3908,57 @@ const struct iomap_ops ext4_iomap_report_ops = {
> .iomap_begin = ext4_iomap_begin_report,
> };
>
> +static int ext4_iomap_map_blocks(struct inode *inode, loff_t offset,
> + loff_t length, struct ext4_map_blocks *map)
> +{
> + u8 blkbits = inode->i_blkbits;
> +
> + if ((offset >> blkbits) > EXT4_MAX_LOGICAL_BLOCK)
> + return -EINVAL;
> +
> + /* Calculate the first and last logical blocks respectively. */
> + map->m_lblk = offset >> blkbits;
> + map->m_len = min_t(loff_t, (offset + length - 1) >> blkbits,
> + EXT4_MAX_LOGICAL_BLOCK) - map->m_lblk + 1;
> +
> + return ext4_map_blocks(NULL, inode, map, 0);
> +}
> +
> +static int ext4_iomap_buffered_read_begin(struct inode *inode, loff_t offset,
> + loff_t length, unsigned int flags, struct iomap *iomap,
> + struct iomap *srcmap)
> +{
> + struct ext4_map_blocks map;
> + int ret;
> +
> + if (unlikely(ext4_forced_shutdown(inode->i_sb)))
> + return -EIO;
> +
> + /* Inline data support is not yet available. */
> + if (WARN_ON_ONCE(ext4_has_inline_data(inode)))
> + return -ERANGE;
> +
> + ret = ext4_iomap_map_blocks(inode, offset, length, &map);
> + if (ret < 0)
> + return ret;
> +
> + ext4_set_iomap(inode, iomap, &map, offset, length, flags);
> + return 0;
> +}
> +
> +const struct iomap_ops ext4_iomap_buffered_read_ops = {
> + .iomap_begin = ext4_iomap_buffered_read_begin,
> +};
> +
> static int ext4_iomap_read_folio(struct file *file, struct folio *folio)
> {
> + iomap_bio_read_folio(folio, &ext4_iomap_buffered_read_ops);
> return 0;
> }
>
> static void ext4_iomap_readahead(struct readahead_control *rac)
> {
> -
> + iomap_bio_readahead(rac, &ext4_iomap_buffered_read_ops);
> }
>
> static int ext4_iomap_writepages(struct address_space *mapping,
> --
> 2.52.0
>