[PATCH 07/11] erofs-utils: lib: use meta buffers for zmap operations

Gao Xiang hsiangkao at linux.alibaba.com
Fri Jul 18 16:54:15 AEST 2025


Source kernel commit: 09c543798c3cde19aae575a0f76d5fc7c130ff18

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 dump/main.c              |  2 +-
 fsck/main.c              |  2 +-
 include/erofs/internal.h |  3 +-
 lib/data.c               |  4 +-
 lib/fragments.c          |  4 +-
 lib/rebuild.c            |  2 +-
 lib/zmap.c               | 98 ++++++++++++++--------------------------
 7 files changed, 42 insertions(+), 73 deletions(-)

diff --git a/dump/main.c b/dump/main.c
index 4e68b0ad..632075a2 100644
--- a/dump/main.c
+++ b/dump/main.c
@@ -375,7 +375,7 @@ static void erofsdump_show_fileinfo(bool show_extent)
 	char timebuf[128] = {0};
 	unsigned int extent_count = 0;
 	struct erofs_map_blocks map = {
-		.index = UINT_MAX,
+		.buf = __EROFS_BUF_INITIALIZER,
 		.m_la = 0,
 	};
 
diff --git a/fsck/main.c b/fsck/main.c
index 04370f46..96096a91 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -499,7 +499,7 @@ out:
 static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
 {
 	struct erofs_map_blocks map = {
-		.index = UINT_MAX,
+		.buf = __EROFS_BUF_INITIALIZER,
 	};
 	bool needdecode = fsckcfg.check_decomp && !erofs_is_packed_inode(inode);
 	int ret = 0;
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index b61fe716..0a49394d 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -390,7 +390,7 @@ enum {
 #define EROFS_MAP_FRAGMENT	(EROFS_MAP_MAPPED | __EROFS_MAP_FRAGMENT)
 
 struct erofs_map_blocks {
-	char mpage[EROFS_MAX_BLOCK_SIZE];
+	struct erofs_buf buf;
 
 	erofs_off_t m_pa, m_la;
 	u64 m_plen, m_llen;
@@ -398,7 +398,6 @@ struct erofs_map_blocks {
 	unsigned short m_deviceid;
 	char m_algorithmformat;
 	unsigned int m_flags;
-	erofs_blk_t index;
 };
 
 /*
diff --git a/lib/data.c b/lib/data.c
index d2558254..83cc5d5d 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -197,7 +197,7 @@ static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
 			       erofs_off_t size, erofs_off_t offset)
 {
 	struct erofs_map_blocks map = {
-		.index = UINT_MAX,
+		.buf = __EROFS_BUF_INITIALIZER,
 	};
 	int ret;
 	erofs_off_t ptr = offset;
@@ -300,7 +300,7 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
 {
 	erofs_off_t end, length, skip;
 	struct erofs_map_blocks map = {
-		.index = UINT_MAX,
+		.buf = __EROFS_BUF_INITIALIZER,
 	};
 	bool trimmed;
 	unsigned int bufsize = 0;
diff --git a/lib/fragments.c b/lib/fragments.c
index 3278f473..887c2530 100644
--- a/lib/fragments.c
+++ b/lib/fragments.c
@@ -569,9 +569,7 @@ int erofs_packedfile_read(struct erofs_sb_info *sbi,
 	struct erofs_inode pi = {
 		.sbi = sbi,
 	};
-	struct erofs_map_blocks map = {
-		.index = UINT_MAX,
-	};
+	struct erofs_map_blocks map = { .buf = __EROFS_BUF_INITIALIZER };
 	unsigned int bsz = erofs_blksiz(sbi);
 	erofs_off_t end = pos + len;
 	char *buffer = NULL;
diff --git a/lib/rebuild.c b/lib/rebuild.c
index c580f81f..33857fd6 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -194,7 +194,7 @@ static int erofs_rebuild_write_blob_index(struct erofs_sb_info *dst_sb,
 	for (i = 0; i < count; i++) {
 		struct erofs_blobchunk *chunk;
 		struct erofs_map_blocks map = {
-			.index = UINT_MAX,
+			.buf = __EROFS_BUF_INITIALIZER,
 		};
 
 		map.m_la = i << chunkbits;
diff --git a/lib/zmap.c b/lib/zmap.c
index 917ee010..db8561be 100644
--- a/lib/zmap.c
+++ b/lib/zmap.c
@@ -13,7 +13,6 @@
 struct z_erofs_maprecorder {
 	struct erofs_inode *inode;
 	struct erofs_map_blocks *map;
-	void *kaddr;
 
 	unsigned long lcn;
 	/* compression extent information gathered */
@@ -33,18 +32,12 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m,
 	const erofs_off_t pos = Z_EROFS_FULL_INDEX_START(erofs_iloc(vi) +
 			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;
 
-	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);
+	di = erofs_read_metabuf(&m->map->buf, sbi, pos);
+	if (IS_ERR(di))
+		return PTR_ERR(di);
 	m->lcn = lcn;
 	m->nextpackoff = pos + sizeof(struct z_erofs_lcluster_index);
 
@@ -118,12 +111,11 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m,
 	const unsigned int lclusterbits = vi->z_lclusterbits;
 	const unsigned int totalidx = BLK_ROUND_UP(sbi, vi->i_size);
 	unsigned int compacted_4b_initial, compacted_2b, amortizedshift;
-	unsigned int vcnt, base, lo, lobits, encodebits, nblk, eofs;
+	unsigned int vcnt, lo, lobits, encodebits, nblk, bytes;
 	bool big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
-	erofs_blk_t eblk;
 	erofs_off_t pos;
 	u8 *in, type;
-	int i, err;
+	int i;
 
 	if (lcn >= totalidx || lclusterbits > 14)
 		return -EINVAL;
@@ -158,24 +150,18 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m,
 	else
 		return -EOPNOTSUPP;
 
-	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;
-	}
+	in = erofs_read_metabuf(&m->map->buf, sbi, pos);
+	if (IS_ERR(in))
+		return PTR_ERR(in);
 
 	/* it doesn't equal to round_up(..) */
 	m->nextpackoff = round_down(pos, vcnt << amortizedshift) +
 			 (vcnt << amortizedshift);
 	lobits = max(lclusterbits, ilog2(Z_EROFS_LI_D0_CBLKCNT) + 1U);
 	encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
-	eofs = erofs_blkoff(sbi, pos);
-	base = round_down(eofs, vcnt << amortizedshift);
-	in = m->kaddr + base;
-
-	i = (eofs - base) >> amortizedshift;
+	bytes = pos & ((vcnt << amortizedshift) - 1);
+	in -= bytes;
+	i = bytes >> amortizedshift;
 
 	lo = decode_compactedbits(lobits, in, encodebits * i, &type);
 	m->type = type;
@@ -420,7 +406,6 @@ static int z_erofs_map_blocks_fo(struct erofs_inode *vi,
 	struct z_erofs_maprecorder m = {
 		.inode = vi,
 		.map = map,
-		.kaddr = map->mpage,
 	};
 	int err = 0;
 	unsigned int endoff, afmt;
@@ -558,23 +543,16 @@ static int z_erofs_map_blocks_ext(struct erofs_inode *vi,
 				   vi->inode_isize + vi->xattr_isize), recsz);
 	erofs_off_t lend = vi->i_size;
 	erofs_off_t l, r, mid, pa, la, lstart;
-	erofs_blk_t eblk;
 	struct z_erofs_extent *ext;
 	unsigned int fmt;
 	bool last;
-	int err;
 
 	map->m_flags = 0;
 	if (recsz <= offsetof(struct z_erofs_extent, pstart_hi)) {
 		if (recsz <= offsetof(struct z_erofs_extent, pstart_lo)) {
-			eblk = erofs_blknr(sbi, pos);
-			if (map->index != eblk) {
-				err = erofs_blk_read(sbi, 0, map->mpage, eblk, 1);
-				if (err < 0)
-					return err;
-				map->index = eblk;
-			}
-			ext = (void *)(map->mpage + erofs_blkoff(sbi, pos));
+			ext = erofs_read_metabuf(&map->buf, sbi, pos);
+			if (IS_ERR(ext))
+				return PTR_ERR(ext);
 			pa = le64_to_cpu(*(__le64 *)ext);
 			pos += sizeof(__le64);
 			lstart = 0;
@@ -584,14 +562,9 @@ static int z_erofs_map_blocks_ext(struct erofs_inode *vi,
 		}
 
 		for (; lstart <= map->m_la; lstart += 1 << vi->z_lclusterbits) {
-			eblk = erofs_blknr(sbi, pos);
-			if (map->index != eblk) {
-				err = erofs_blk_read(sbi, 0, map->mpage, eblk, 1);
-				if (err < 0)
-					return err;
-				map->index = eblk;
-			}
-			ext = (void *)(map->mpage + erofs_blkoff(sbi, pos));
+			ext = erofs_read_metabuf(&map->buf, sbi, pos);
+			if (IS_ERR(ext))
+				return PTR_ERR(ext);
 			map->m_plen = le32_to_cpu(ext->plen);
 			if (pa != EROFS_NULL_ADDR) {
 				map->m_pa = pa;
@@ -608,14 +581,11 @@ static int z_erofs_map_blocks_ext(struct erofs_inode *vi,
 		lstart = lend;
 		for (l = 0, r = vi->z_extents; l < r; ) {
 			mid = l + (r - l) / 2;
-			eblk = erofs_blknr(sbi, pos + mid * recsz);
-			if (map->index != eblk) {
-				err = erofs_blk_read(sbi, 0, map->mpage, eblk, 1);
-				if (err < 0)
-					return err;
-				map->index = eblk;
-			}
-			ext = (void *)(map->mpage + erofs_blkoff(sbi, pos + mid * recsz));
+			ext = erofs_read_metabuf(&map->buf, sbi,
+						 pos + mid * recsz);
+			if (IS_ERR(ext))
+				return PTR_ERR(ext);
+
 			la = le32_to_cpu(ext->lstart_lo);
 			pa = le32_to_cpu(ext->pstart_lo) |
 				(u64)le32_to_cpu(ext->pstart_hi) << 32;
@@ -669,24 +639,22 @@ static int z_erofs_map_blocks_ext(struct erofs_inode *vi,
 	return 0;
 }
 
-
 static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
 {
-	erofs_off_t pos;
-	struct z_erofs_map_header *h;
-	char buf[sizeof(struct z_erofs_map_header)];
 	struct erofs_sb_info *sbi = vi->sbi;
 	int err, headnr;
+	erofs_off_t pos;
+	struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
+	struct z_erofs_map_header *h;
 
 	if (erofs_atomic_read(&vi->flags) & EROFS_I_Z_INITED)
 		return 0;
 
 	pos = round_up(erofs_iloc(vi) + vi->inode_isize + vi->xattr_isize, 8);
-	err = erofs_dev_read(sbi, 0, buf, pos, sizeof(buf));
-	if (err < 0)
-		return -EIO;
+	h = erofs_read_metabuf(&buf, sbi, pos);
+	if (IS_ERR(h))
+		return PTR_ERR(h);
 
-	h = (struct z_erofs_map_header *)buf;
 	/*
 	 * if the highest bit of the 8-byte map header is set, the whole file
 	 * is stored in the packed inode. The rest bits keeps z_fragmentoff.
@@ -718,7 +686,8 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
 	    vi->z_algorithmtype[++headnr] >= Z_EROFS_COMPRESSION_MAX) {
 		erofs_err("unknown HEAD%u format %u for nid %llu",
 			  headnr + 1, vi->z_algorithmtype[0], vi->nid | 0ULL);
-		return -EOPNOTSUPP;
+		err = -EOPNOTSUPP;
+		goto out_put_metabuf;
 	}
 
 	if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT &&
@@ -726,12 +695,13 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
 	    !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
 		erofs_err("big pcluster head1/2 of compact indexes should be consistent for nid %llu",
 			  vi->nid * 1ULL);
-		return -EFSCORRUPTED;
+		err = -EFSCORRUPTED;
+		goto out_put_metabuf;
 	}
 
 	if (vi->z_idata_size ||
 	    (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER)) {
-		struct erofs_map_blocks map = { .index = UINT_MAX };
+		struct erofs_map_blocks map = { .buf = __EROFS_BUF_INITIALIZER };
 
 		err = z_erofs_map_blocks_fo(vi, &map,
 					    EROFS_GET_BLOCKS_FINDTAIL);
@@ -740,6 +710,8 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
 	}
 done:
 	erofs_atomic_set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
+out_put_metabuf:
+	erofs_put_metabuf(&buf);
 	return 0;
 }
 
-- 
2.43.5



More information about the Linux-erofs mailing list