[PATCH 5/9] erofs-utils: lib: sync up zmap.c

Gao Xiang hsiangkao at linux.alibaba.com
Thu Feb 6 23:50:30 AEDT 2025


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 <hsiangkao at 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



More information about the Linux-erofs mailing list