Re: [PATCH] erofs: prevent buffered read bio merges across device chunks

From: Gao Xiang

Date: Thu Jun 11 2026 - 23:43:42 EST




On 2026/6/12 11:32, Yifan Zhao wrote:
EROFS chunked files may place adjacent logical chunks on different
devices. The physical block numbers are per-device, so two neighboring
chunks can still look sector-contiguous to the generic iomap buffered
read code.

For example:

logical file offset
0 8K 16K 24K
+----------+----------+----------+
| chunk 0 | chunk 1 | chunk 2 |
+----------+----------+----------+
| | |
v v v
dev 1 dev 3 dev 3
sector 8 sector 24 sector 40

The transition from chunk 0 to chunk 1 crosses a device boundary, but
iomap can still treat sector-contiguous bios as mergeable without
checking whether they belong to the same device.

The pending bio, however, is still bound to the previous block device:

bio->bi_bdev = dev 1

file 0..8K -> dev 1, sector 8
file 8..16K -> dev 3, sector 24
(must not be added here)

If the second range is added to the same bio, it will be submitted to
dev 1 and read from the wrong backing device, which is easy to trigger
with readahead.

This only affects paths using erofs_aops, where buffered reads go
through iomap bio helpers.

Fix by install EROFS-specific iomap read ops and split the pending
buffered read bio whenever the next mapped range belongs to a different
bdev. After the split, fall back to the generic iomap bio read helper
for the normal sector-based merge checks.

Reported-by: Kelu Ye <yekelu1@xxxxxxxxxx>
Assisted-by: Codex:GPT-5.5
Signed-off-by: Yifan Zhao <zhaoyifan28@xxxxxxxxxx>

I think it's an iomap bug instead, see:

iomap_bio_read_folio_range(), we should fix iomap instead.

Thanks,
Gao Xiang