[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