In this case, advise contains Z_EROFS_ADVISE_EXTENTS, Z_EROFS_ADVISE_BIG_PCLUSTER_1, Z_EROFS_ADVISE_BIG_PCLUSTER_2 at the same time, and following 1 and 2 are met, WARN_ON_ONCE(iter->iomap.offset > iter->pos) in iomap_iter_done() is triggered.
1. When Z_EROFS_ADVISE_EXTENTS exists, z_erofs_fill_inode_lazy() is exited after z_extents is set, which skips the check of big pcluster; 2. When the condition "lstart < lend" is met in z_erofs_map_blocks_ext(), m_la is updated, and m_la is used to update iomap->offset in z_erofs_iomap_begin_report(); Fixes: 1d191b4ca51d ("erofs: implement encoded extent metadata") Reported-by: syzbot+d8f000c609f05f52d...@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=d8f000c609f05f52d9b5 Tested-by: syzbot+d8f000c609f05f52d...@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis <eada...@qq.com> --- fs/erofs/zmap.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index 14ea47f954f5..664611cca689 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -686,7 +686,17 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) vi->z_tailextent_headlcn = 0; goto done; } + vi->z_advise = le16_to_cpu(h->h_advise); + if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && + vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | + Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { + erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu", + vi->nid); + err = -EFSCORRUPTED; + goto out_put_metabuf; + } + vi->z_lclusterbits = sb->s_blocksize_bits + (h->h_clusterbits & 15); if (vi->datalayout == EROFS_INODE_COMPRESSED_FULL && (vi->z_advise & Z_EROFS_ADVISE_EXTENTS)) { @@ -711,14 +721,6 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) goto out_put_metabuf; } - if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && - vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | - Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { - erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu", - vi->nid); - err = -EFSCORRUPTED; - goto out_put_metabuf; - } if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT && !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { -- 2.43.0