Re: [PATCH v4 04/21] iomap: add ->iomap_next()

"Darrick J. Wong" <[email protected]> Mon, 27 Jul 2026 15:27:43 -0700
Newsgroups org.kernel.vger.linux-ext4,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-xfs
Message-ID <20260727222743.GF2901224@frogsfrogsfrogs>
On Mon, Jul 27, 2026 at 02:17:41PM -0700, Joanne Koong wrote:
> Have one ->iomap_next() callback instead of ->iomap_begin() and
> ->iomap_end(). ->iomap_next() finishes the previous mapping if needed,
> and produces the next mapping.
> 
> Collapsing to a single callback lets a performance-critical caller
> inline its iteration loop and pass its ->iomap_next() function as a
> compile-time constant, so the compiler can devirtualize that callback
> into a direct call instead of an indirect call through a function
> pointer.
> 
> iomap_iter() uses ->iomap_next() when the filesystem provides that
> callback and otherwise falls back to the ->iomap_begin()/->iomap_end()
> path, so filesystems can be converted one at a time.
> 
> Suggested-by: Christoph Hellwig <[email protected]>
> Suggested-by: Matthew Wilcox (Oracle) <[email protected]>
> Reviewed-by: Christoph Hellwig <[email protected]>
> Signed-off-by: Joanne Koong <[email protected]>

Looks great!
Reviewed-by: "Darrick J. Wong" <[email protected]>

--D

> ---
>  fs/iomap/iter.c       | 8 ++++++--
>  include/linux/iomap.h | 9 +++++++++
>  2 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/iomap/iter.c b/fs/iomap/iter.c
> index 66ccb87441ab..e05574602946 100644
> --- a/fs/iomap/iter.c
> +++ b/fs/iomap/iter.c
> @@ -107,8 +107,12 @@ int iomap_iter(struct iomap_iter *iter, const struct iomap_ops *ops)
>  
>  	trace_iomap_iter(iter, ops, _RET_IP_);
>  
> -	ret = iomap_iter_next(iter, &iter->iomap, &iter->srcmap,
> -			ops->iomap_begin, ops->iomap_end);
> +	if (ops->iomap_next)
> +		ret = ops->iomap_next(iter, &iter->iomap, &iter->srcmap);
> +	else
> +		ret = iomap_iter_next(iter, &iter->iomap, &iter->srcmap,
> +				ops->iomap_begin, ops->iomap_end);
> +
>  	iter->status = 0;
>  	if (ret > 0)
>  		iomap_iter_done(iter);
> diff --git a/include/linux/iomap.h b/include/linux/iomap.h
> index 80832edc7ec2..d203d9fe0f89 100644
> --- a/include/linux/iomap.h
> +++ b/include/linux/iomap.h
> @@ -231,9 +231,18 @@ typedef int (*iomap_iter_begin_fn)(struct inode *inode, loff_t pos,
>  typedef int (*iomap_iter_end_fn)(struct inode *inode, loff_t pos, loff_t length,
>  		ssize_t written, unsigned flags, struct iomap *iomap);
>  
> +/*
> + * Produce the next mapping (finishing the previous one if needed).
> + * Return 1 to continue iterating, 0 if the range is fully consumed, or a
> + * negative error on failure.
> + */
> +typedef int (*iomap_iter_next_fn)(const struct iomap_iter *iter,
> +		struct iomap *iomap, struct iomap *srcmap);
> +
>  struct iomap_ops {
>  	iomap_iter_begin_fn iomap_begin;
>  	iomap_iter_end_fn iomap_end;
> +	iomap_iter_next_fn iomap_next;
>  };
>  
>  /**
> -- 
> 2.52.0
> 
>