commit 31da107fdb0a ("erofs: fold in z_erofs_reload_indexes()") commit 53a7f9961cdd ("erofs: clean up unnecessary code and comments") commit 9ff471800b74 ("erofs: get rid of a useless DBG_BUGON") commit cc4efd3dd2ac ("erofs: stop parsing non-compact HEAD index if clusterofs is invalid") commit 118a8cf504d7 ("erofs: fix inconsistent per-file compression format") commit 9b32b063be10 ("erofs: ensure m_llen is reset to 0 if metadata is invalid")
Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com> --- lib/zmap.c | 91 ++++++++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/lib/zmap.c b/lib/zmap.c index ee0af1f..c79424b 100644 --- a/lib/zmap.c +++ b/lib/zmap.c @@ -25,25 +25,6 @@ struct z_erofs_maprecorder { bool partialref; }; -static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m, - erofs_blk_t eblk) -{ - int ret; - struct erofs_map_blocks *const map = m->map; - char *mpage = map->mpage; - - if (map->index == eblk) - return 0; - - ret = erofs_blk_read(m->inode->sbi, 0, mpage, eblk, 1); - if (ret < 0) - return -EIO; - - map->index = eblk; - - return 0; -} - static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m, unsigned long lcn) { @@ -53,17 +34,20 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m, const erofs_off_t pos = Z_EROFS_FULL_INDEX_ALIGN(ibase + vi->inode_isize + vi->xattr_isize) + lcn * sizeof(struct z_erofs_lcluster_index); + erofs_blk_t eblk = erofs_blknr(sbi, pos); struct z_erofs_lcluster_index *di; unsigned int advise; int err; - err = z_erofs_reload_indexes(m, erofs_blknr(sbi, pos)); - if (err) - return err; - - m->nextpackoff = pos + sizeof(struct z_erofs_lcluster_index); - m->lcn = lcn; + if (m->map->index != eblk) { + err = erofs_blk_read(sbi, 0, m->kaddr, eblk, 1); + if (err < 0) + return err; + m->map->index = eblk; + } di = m->kaddr + erofs_blkoff(sbi, pos); + m->lcn = lcn; + m->nextpackoff = pos + sizeof(struct z_erofs_lcluster_index); advise = le16_to_cpu(di->di_advise); m->type = advise & Z_EROFS_LI_LCLUSTER_TYPE_MASK; @@ -72,18 +56,21 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m, m->delta[0] = le16_to_cpu(di->di_u.delta[0]); if (m->delta[0] & Z_EROFS_LI_D0_CBLKCNT) { if (!(vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | - Z_EROFS_ADVISE_BIG_PCLUSTER_2))) { + Z_EROFS_ADVISE_BIG_PCLUSTER_2))) { DBG_BUGON(1); return -EFSCORRUPTED; } - m->compressedblks = m->delta[0] & - ~Z_EROFS_LI_D0_CBLKCNT; + m->compressedblks = m->delta[0] & ~Z_EROFS_LI_D0_CBLKCNT; m->delta[0] = 1; } m->delta[1] = le16_to_cpu(di->di_u.delta[1]); } else { m->partialref = !!(advise & Z_EROFS_LI_PARTIAL_REF); m->clusterofs = le16_to_cpu(di->di_clusterofs); + if (m->clusterofs >= 1 << vi->z_logical_clusterbits) { + DBG_BUGON(1); + return -EFSCORRUPTED; + } m->pblk = le32_to_cpu(di->di_u.blkaddr); } return 0; @@ -129,9 +116,9 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, struct erofs_inode *const vi = m->inode; const unsigned int lclusterbits = vi->z_logical_clusterbits; unsigned int vcnt, base, lo, lobits, encodebits, nblk, eofs; - int i; - u8 *in, type; bool big_pcluster; + u8 *in, type; + int i; if (1 << amortizedshift == 4 && lclusterbits <= 14) vcnt = 2; @@ -242,6 +229,7 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m, unsigned int compacted_4b_initial, compacted_2b; unsigned int amortizedshift; erofs_off_t pos; + erofs_blk_t eblk; int err; if (lcn >= totalidx) @@ -276,9 +264,13 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m, amortizedshift = 2; out: pos += lcn * (1 << amortizedshift); - err = z_erofs_reload_indexes(m, erofs_blknr(sbi, pos)); - if (err) - return err; + eblk = erofs_blknr(sbi, pos); + if (m->map->index != eblk) { + err = erofs_blk_read(sbi, 0, m->kaddr, eblk, 1); + if (err < 0) + return err; + m->map->index = eblk; + } return unpack_compacted_index(m, amortizedshift, pos, lookahead); } @@ -472,7 +464,7 @@ static int z_erofs_do_map_blocks(struct erofs_inode *vi, .kaddr = map->mpage, }; int err = 0; - unsigned int lclusterbits, endoff; + unsigned int lclusterbits, endoff, afmt; unsigned long initial_lcn; unsigned long long ofs, end; @@ -490,6 +482,7 @@ static int z_erofs_do_map_blocks(struct erofs_inode *vi, map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_ENCODED; end = (m.lcn + 1ULL) << lclusterbits; + switch (m.type) { case Z_EROFS_LCLUSTER_TYPE_PLAIN: case Z_EROFS_LCLUSTER_TYPE_HEAD1: @@ -518,7 +511,7 @@ static int z_erofs_do_map_blocks(struct erofs_inode *vi, m.delta[0] = 1; /* fallthrough */ case Z_EROFS_LCLUSTER_TYPE_NONHEAD: - /* get the correspoinding first chunk */ + /* get the corresponding first chunk */ err = z_erofs_extent_lookback(&m, m.delta[0]); if (err) goto out; @@ -532,6 +525,7 @@ static int z_erofs_do_map_blocks(struct erofs_inode *vi, if (m.partialref) map->m_flags |= EROFS_MAP_PARTIAL_REF; map->m_llen = end - map->m_la; + if (flags & EROFS_GET_BLOCKS_FINDTAIL) { vi->z_tailextent_headlcn = m.lcn; /* for non-compact indexes, fragmentoff is 64 bits */ @@ -557,17 +551,20 @@ static int z_erofs_do_map_blocks(struct erofs_inode *vi, err = -EFSCORRUPTED; goto out; } - if (vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER) - map->m_algorithmformat = - Z_EROFS_COMPRESSION_INTERLACED; - else - map->m_algorithmformat = - Z_EROFS_COMPRESSION_SHIFTED; - } else if (m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) { - map->m_algorithmformat = vi->z_algorithmtype[1]; + afmt = vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER ? + Z_EROFS_COMPRESSION_INTERLACED : + Z_EROFS_COMPRESSION_SHIFTED; } else { - map->m_algorithmformat = vi->z_algorithmtype[0]; + afmt = m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2 ? + vi->z_algorithmtype[1] : vi->z_algorithmtype[0]; + if (!(sbi->available_compr_algs & (1 << afmt))) { + erofs_err("inconsistent algorithmtype %u for nid %llu", + afmt, vi->nid); + err = -EFSCORRUPTED; + goto out; + } } + map->m_algorithmformat = afmt; if (flags & EROFS_GET_BLOCKS_FIEMAP) { err = z_erofs_get_extent_decompressedlen(&m); @@ -662,8 +659,7 @@ out: } int z_erofs_map_blocks_iter(struct erofs_inode *vi, - struct erofs_map_blocks *map, - int flags) + struct erofs_map_blocks *map, int flags) { int err = 0; @@ -690,6 +686,7 @@ int z_erofs_map_blocks_iter(struct erofs_inode *vi, err = z_erofs_do_map_blocks(vi, map, flags); out: - DBG_BUGON(err < 0 && err != -ENOMEM); + if (err) + map->m_llen = 0; return err; } -- 2.43.5