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 <[email protected]>
Assisted-by: Codex:GPT-5.5
Signed-off-by: Yifan Zhao <[email protected]>

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

iomap_bio_read_folio_range(), we should fix iomap instead.

Thanks,
Gao Xiang


Reply via email to