Previously, iomap_readpage_iter() returning 0 would break out of the loops of iomap_readahead_iter(), which is what iomap_read_inline_data() relies on. However, commit d9dc477ff6a2 ("iomap: advance the iter directly on buffered read") changes this behavior without calling iomap_iter_advance(), which causes EROFS to get stuck in iomap_readpage_iter(). It seems iomap_iter_advance() cannot be called in iomap_read_inline_data() because of the iomap_write_begin() path, so handle this in iomap_readpage_iter() instead. Reported-and-tested-by: Bo Liu <liubo03@xxxxxxxxxx> Fixes: d9dc477ff6a2 ("iomap: advance the iter directly on buffered read") Cc: Brian Foster <bfoster@xxxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: "Darrick J. Wong" <djwong@xxxxxxxxxx> Cc: Christian Brauner <brauner@xxxxxxxxxx> Signed-off-by: Gao Xiang <hsiangkao@xxxxxxxxxxxxxxxxx> --- v1: https://lore.kernel.org/r/20250319025953.3559299-1-hsiangkao@xxxxxxxxxxxxxxxxx change since v1: - iomap_iter_advance() directly instead of `goto done` as suggested by Christoph. fs/iomap/buffered-io.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index d52cfdc299c4..814b7f679486 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -372,9 +372,14 @@ static int iomap_readpage_iter(struct iomap_iter *iter, struct iomap_folio_state *ifs; size_t poff, plen; sector_t sector; + int ret; - if (iomap->type == IOMAP_INLINE) - return iomap_read_inline_data(iter, folio); + if (iomap->type == IOMAP_INLINE) { + ret = iomap_read_inline_data(iter, folio); + if (ret) + return ret; + return iomap_iter_advance(iter, &length); + } /* zero post-eof blocks as the page may be mapped */ ifs = ifs_alloc(iter->inode, folio, iter->flags); -- 2.43.5