milos-linux/fs/erofs
Zhan Xusheng 27f2d085bd erofs: fix EFSCORRUPTED on multi-algorithm images in z_erofs_map_sanity_check()
Commit a5242d37c8 ("erofs: error out obviously illegal extents in
advance") changed the per-extent algorithm presence check from "is the
bit set" to "is the only bit set":
  -		     !(sbi->available_compr_algs & (1 << map->m_algorithmformat))
  +		(sbi->available_compr_algs ^ BIT(map->m_algorithmformat))

`available_compr_algs` is a bitmap of every compression algorithm
available in the image (z_erofs_parse_cfgs() iterates it with
for_each_set_bit()), so an image that enables more than one algorithm
has multiple bits set.  XOR is zero only when the bitmap is exactly
BIT(map->m_algorithmformat); for any image with two or more algorithms
the test is non-zero for every extent and the read fails with
-EFSCORRUPTED ("inconsistent algorithmtype %u").

Reproducer (mkfs.erofs from erofs-utils 1.7.1):
  $ mkdir src
  $ yes A | head -c 100K > src/a
  $ head -c 64K /dev/zero > src/b
  $ mkfs.erofs -zlz4:deflate multi.erofs src
  $ mount -t erofs -o loop multi.erofs /mnt
  $ cat /mnt/a >/dev/null
  cat: /mnt/a: Structure needs cleaning
  $ dmesg | tail
    erofs (device loop0): inconsistent algorithmtype 0 for nid 46
    erofs (device loop0): read error -117 @ 0 of nid 46

The erofs on-disk format (Z_EROFS_COMPRESSION_MAX = 4 with LZ4, LZMA,
DEFLATE, ZSTD) and the kernel parser explicitly support
multi-algorithm images, and erofs-utils 1.7.1 generates them via the
"-z X:Y" syntax.

Restore the original per-bit presence check.

Fixes: a5242d37c8 ("erofs: error out obviously illegal extents in advance")
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2026-06-02 01:52:58 +08:00
..
compress.h erofs: enable error reporting for z_erofs_fixup_insize() 2025-11-30 23:49:32 +08:00
data.c Changes since the last update: 2026-04-21 11:16:04 -07:00
decompressor.c erofs: error out obviously illegal extents in advance 2026-04-10 16:53:39 +08:00
decompressor_crypto.c erofs: make z_erofs_crypto[] static 2026-01-23 00:00:18 +08:00
decompressor_deflate.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
decompressor_lzma.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
decompressor_zstd.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
dir.c erofs: fix the out-of-bounds nameoff handling for trailing dirents 2026-04-21 16:56:04 +08:00
erofs_fs.h erofs: handle 48-bit blocks/uniaddr for extra devices 2026-04-07 11:46:31 +08:00
fileio.c erofs: set fileio bio failed in short read case 2026-03-17 10:27:31 +08:00
fscache.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
inode.c erofs: include the trailing NUL in FS_IOC_GETFSLABEL 2026-04-02 16:08:49 +08:00
internal.h erofs: clean up encoded map flags 2026-04-10 16:53:39 +08:00
ishare.c lsm/stable-7.1 PR 20260410 2026-04-13 15:17:28 -07:00
Kconfig erofs: update the Kconfig description 2026-03-25 00:04:41 +08:00
Makefile erofs: introduce the page cache share feature 2026-01-23 20:02:09 +08:00
namei.c erofs: get rid of erofs_kmap_type 2025-03-17 01:21:24 +08:00
super.c erofs: handle 48-bit blocks/uniaddr for extra devices 2026-04-07 11:46:31 +08:00
sysfs.c erofs: avoid some unnecessary #ifdefs 2026-02-03 11:25:55 +08:00
xattr.c erofs: fix metabuf leak in inode xattr initialization 2026-05-20 14:53:14 +08:00
xattr.h erofs: mark inodes without acls in erofs_read_inode() 2026-01-28 15:38:37 +08:00
zdata.c erofs: fix use-after-free on sbi->sync_decompress 2026-05-29 12:32:56 +08:00
zmap.c erofs: fix EFSCORRUPTED on multi-algorithm images in z_erofs_map_sanity_check() 2026-06-02 01:52:58 +08:00
zutil.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00