[PATCH 10/11] erofs-utils: fsck, dump: support metadata compression
Gao Xiang
hsiangkao at linux.alibaba.com
Fri Jul 18 16:54:18 AEST 2025
Source kernel commit: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Source kernel commit: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
dump/main.c | 10 +++++++++-
fsck/main.c | 25 ++++++++++++++---------
include/erofs/internal.h | 19 ++++++++++++------
include/erofs_fs.h | 12 ++++++++---
lib/data.c | 43 ++++++++++++++++++++++++++++++++++------
lib/namei.c | 5 +++--
lib/super.c | 29 +++++++++++++++++++++------
lib/xattr.c | 12 +++++------
lib/zmap.c | 15 ++++++++------
9 files changed, 125 insertions(+), 45 deletions(-)
diff --git a/dump/main.c b/dump/main.c
index f0dab02e..38cc8a28 100644
--- a/dump/main.c
+++ b/dump/main.c
@@ -105,6 +105,7 @@ static struct erofsdump_feature feature_lists[] = {
{ false, EROFS_FEATURE_INCOMPAT_DEDUPE, "dedupe" },
{ false, EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES, "xattr_prefixes" },
{ false, EROFS_FEATURE_INCOMPAT_48BIT, "48bit" },
+ { false, EROFS_FEATURE_INCOMPAT_METABOX, "metabox" },
};
static int erofsdump_readdir(struct erofs_dir_context *ctx);
@@ -163,7 +164,11 @@ static int erofsdump_parse_options_cfg(int argc, char **argv)
exit(0);
case 2:
dumpcfg.show_inode = true;
- dumpcfg.nid = (erofs_nid_t)atoll(optarg);
+ dumpcfg.nid = strtoull(optarg, &endptr, 0);
+ if (*endptr != '\0') {
+ erofs_err("invalid NID %s", optarg);
+ return -EINVAL;
+ }
++dumpcfg.totalshow;
break;
case 'h':
@@ -643,6 +648,9 @@ static void erofsdump_show_superblock(void)
if (erofs_sb_has_fragments(&g_sbi) && g_sbi.packed_nid > 0)
fprintf(stdout, "Filesystem packed nid: %llu\n",
g_sbi.packed_nid | 0ULL);
+ if (erofs_sb_has_metabox(&g_sbi))
+ fprintf(stdout, "Filesystem metabox nid: %llu\n",
+ g_sbi.metabox_nid | 0ULL);
if (erofs_sb_has_compr_cfgs(&g_sbi)) {
fprintf(stdout, "Filesystem compr_algs: ");
erofsdump_print_supported_compressors(stdout,
diff --git a/fsck/main.c b/fsck/main.c
index 44719b95..d4f0fea7 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -333,12 +333,14 @@ static int erofs_verify_xattr(struct erofs_inode *inode)
struct erofs_sb_info *sbi = inode->sbi;
unsigned int xattr_hdr_size = sizeof(struct erofs_xattr_ibody_header);
unsigned int xattr_entry_size = sizeof(struct erofs_xattr_entry);
- erofs_off_t addr;
+ struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
unsigned int ofs, xattr_shared_count;
struct erofs_xattr_ibody_header *ih;
struct erofs_xattr_entry *entry;
- int i, remaining = inode->xattr_isize, ret = 0;
- char buf[EROFS_MAX_BLOCK_SIZE];
+ int remaining = inode->xattr_isize, ret = 0;
+ erofs_off_t addr;
+ char *ptr;
+ int i;
if (inode->xattr_isize == xattr_hdr_size) {
erofs_err("xattr_isize %d of nid %llu is not supported yet",
@@ -355,13 +357,15 @@ static int erofs_verify_xattr(struct erofs_inode *inode)
}
addr = erofs_iloc(inode) + inode->inode_isize;
- ret = erofs_dev_read(sbi, 0, buf, addr, xattr_hdr_size);
- if (ret < 0) {
+ ptr = erofs_read_metabuf(&buf, sbi, addr,
+ erofs_inode_in_metabox(inode));
+ if (IS_ERR(ptr)) {
+ ret = PTR_ERR(ptr);
erofs_err("failed to read xattr header @ nid %llu: %d",
inode->nid | 0ULL, ret);
goto out;
}
- ih = (struct erofs_xattr_ibody_header *)buf;
+ ih = (struct erofs_xattr_ibody_header *)ptr;
xattr_shared_count = ih->h_shared_count;
ofs = erofs_blkoff(sbi, addr) + xattr_hdr_size;
@@ -385,14 +389,16 @@ static int erofs_verify_xattr(struct erofs_inode *inode)
while (remaining > 0) {
unsigned int entry_sz;
- ret = erofs_dev_read(sbi, 0, buf, addr, xattr_entry_size);
- if (ret) {
+ ptr = erofs_read_metabuf(&buf, sbi, addr,
+ erofs_inode_in_metabox(inode));
+ if (IS_ERR(ptr)) {
+ ret = PTR_ERR(ptr);
erofs_err("failed to read xattr entry @ nid %llu: %d",
inode->nid | 0ULL, ret);
goto out;
}
- entry = (struct erofs_xattr_entry *)buf;
+ entry = (struct erofs_xattr_entry *)ptr;
entry_sz = erofs_xattr_entry_size(entry);
if (remaining < entry_sz) {
erofs_err("xattr on-disk corruption: xattr entry beyond xattr_isize @ nid %llu",
@@ -404,6 +410,7 @@ static int erofs_verify_xattr(struct erofs_inode *inode)
remaining -= entry_sz;
}
out:
+ erofs_put_metabuf(&buf);
return ret;
}
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 3439a183..de6f4eae 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -126,6 +126,7 @@ struct erofs_sb_info {
u16 device_id_mask; /* used for others */
};
erofs_nid_t packed_nid;
+ erofs_nid_t metabox_nid;
u32 xattr_prefix_start;
u8 xattr_prefix_count;
@@ -153,8 +154,6 @@ struct erofs_sb_info {
bool useqpl;
};
-#define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct erofs_super_block))
-
/* make sure that any user of the erofs headers has atleast 64bit off_t type */
extern int erofs_assert_largefile[sizeof(off_t)-8];
@@ -182,6 +181,7 @@ EROFS_FEATURE_FUNCS(fragments, incompat, INCOMPAT_FRAGMENTS)
EROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE)
EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
EROFS_FEATURE_FUNCS(48bit, incompat, INCOMPAT_48BIT)
+EROFS_FEATURE_FUNCS(metabox, incompat, INCOMPAT_METABOX)
EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
EROFS_FEATURE_FUNCS(xattr_filter, compat, COMPAT_XATTR_FILTER)
@@ -295,12 +295,18 @@ struct erofs_inode {
#endif
};
+static inline bool erofs_inode_in_metabox(struct erofs_inode *inode)
+{
+ return inode->nid >> EROFS_DIRENT_NID_METABOX_BIT;
+}
+
static inline erofs_off_t erofs_iloc(struct erofs_inode *inode)
{
struct erofs_sb_info *sbi = inode->sbi;
+ erofs_off_t base = erofs_inode_in_metabox(inode) ? 0 :
+ erofs_pos(sbi, sbi->meta_blkaddr);
- return erofs_pos(sbi, sbi->meta_blkaddr) +
- (inode->nid << EROFS_ISLOTBITS);
+ return base + ((inode->nid & EROFS_DIRENT_NID_MASK) << EROFS_ISLOTBITS);
}
static inline bool is_inode_layout_compression(struct erofs_inode *inode)
@@ -437,9 +443,10 @@ int erofs_ilookup(const char *path, struct erofs_inode *vi);
static inline void erofs_unmap_metabuf(struct erofs_buf *buf) {}
static inline void erofs_put_metabuf(struct erofs_buf *buf) {}
void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, bool need_kmap);
-void erofs_init_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi);
+void erofs_init_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi,
+ bool in_mbox);
void *erofs_read_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi,
- erofs_off_t offset);
+ erofs_off_t offset, bool in_mbox);
int erofs_iopen(struct erofs_vfile *vf, struct erofs_inode *inode);
int erofs_map_blocks(struct erofs_inode *inode,
struct erofs_map_blocks *map, int flags);
diff --git a/include/erofs_fs.h b/include/erofs_fs.h
index e180c5d4..56e268e5 100644
--- a/include/erofs_fs.h
+++ b/include/erofs_fs.h
@@ -32,8 +32,9 @@
#define EROFS_FEATURE_INCOMPAT_DEDUPE 0x00000020
#define EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES 0x00000040
#define EROFS_FEATURE_INCOMPAT_48BIT 0x00000080
+#define EROFS_FEATURE_INCOMPAT_METABOX 0x00000100
#define EROFS_ALL_FEATURE_INCOMPAT \
- ((EROFS_FEATURE_INCOMPAT_48BIT << 1) - 1)
+ ((EROFS_FEATURE_INCOMPAT_METABOX << 1) - 1)
#define EROFS_SB_EXTSLOT_SIZE 16
@@ -83,7 +84,9 @@ struct erofs_super_block {
__u8 reserved[3];
__le32 build_time; /* seconds added to epoch for mkfs time */
__le64 rootnid_8b; /* (48BIT on) nid of root directory */
- __u8 reserved2[8];
+ __le64 reserved2;
+ __le64 metabox_nid; /* (METABOX on) nid of the metabox inode */
+ __le64 reserved3;
};
/*
@@ -268,6 +271,9 @@ struct erofs_inode_chunk_index {
__le32 startblk_lo; /* starting block number of this chunk */
};
+#define EROFS_DIRENT_NID_METABOX_BIT 63
+#define EROFS_DIRENT_NID_MASK (BIT(EROFS_DIRENT_NID_METABOX_BIT) - 1)
+
/* dirent sorts in alphabet order, thus we can do binary search */
struct erofs_dirent {
__le64 nid; /* node number */
@@ -448,7 +454,7 @@ static inline void erofs_check_ondisk_layout_definitions(void)
};
#endif
- BUILD_BUG_ON(sizeof(struct erofs_super_block) != 128);
+ BUILD_BUG_ON(sizeof(struct erofs_super_block) != 144);
BUILD_BUG_ON(sizeof(struct erofs_inode_compact) != 32);
BUILD_BUG_ON(sizeof(struct erofs_inode_extended) != 64);
BUILD_BUG_ON(sizeof(struct erofs_xattr_ibody_header) != 12);
diff --git a/lib/data.c b/lib/data.c
index 87ced24f..6791fda5 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -14,6 +14,8 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, bool need_kmap)
{
struct erofs_sb_info *sbi = buf->sbi;
u32 blksiz = erofs_blksiz(sbi);
+ struct erofs_vfile vfm, *vf;
+ struct erofs_inode vi;
erofs_blk_t blknr;
int err;
@@ -22,7 +24,22 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, bool need_kmap)
blknr = erofs_blknr(sbi, offset);
if (blknr != buf->blocknr) {
buf->blocknr = ~0ULL;
- err = erofs_pread(buf->vf, buf->base, blksiz,
+ vf = buf->vf;
+ /*
+ * TODO: introduce a metabox cache like the current fragment
+ * cache to improve userspace metadata performance.
+ */
+ if (!vf) {
+ vi = (struct erofs_inode) { .sbi = sbi,
+ .nid = sbi->metabox_nid };
+ err = erofs_read_inode_from_disk(&vi);
+ if (!err)
+ err = erofs_iopen(&vfm, &vi);
+ if (err)
+ return ERR_PTR(err);
+ vf = &vfm;
+ }
+ err = erofs_pread(vf, buf->base, blksiz,
round_down(offset, blksiz));
if (err)
return ERR_PTR(err);
@@ -31,16 +48,17 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, bool need_kmap)
return buf->base + erofs_blkoff(sbi, offset);
}
-void erofs_init_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi)
+void erofs_init_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi,
+ bool in_mbox)
{
buf->sbi = sbi;
- buf->vf = &sbi->bdev;
+ buf->vf = in_mbox ? NULL : &sbi->bdev;
}
void *erofs_read_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi,
- erofs_off_t offset)
+ erofs_off_t offset, bool in_mbox)
{
- erofs_init_metabuf(buf, sbi);
+ erofs_init_metabuf(buf, sbi, in_mbox);
return erofs_bread(buf, offset, true);
}
@@ -215,7 +233,20 @@ static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
eend = min(offset + size, map.m_la + map.m_llen);
DBG_BUGON(ptr < map.m_la);
- if (!(map.m_flags & EROFS_MAP_MAPPED)) {
+ if ((map.m_flags & EROFS_MAP_META) &&
+ erofs_inode_in_metabox(inode)) {
+ struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
+ void *src;
+
+ src = erofs_read_metabuf(&buf, inode->sbi,
+ map.m_pa, true);
+ if (IS_ERR(src))
+ return PTR_ERR(src);
+ memcpy(estart, src, eend - ptr);
+ erofs_put_metabuf(&buf);
+ ptr = eend;
+ continue;
+ } else if (!(map.m_flags & EROFS_MAP_MAPPED)) {
if (!map.m_llen) {
/* reached EOF */
memset(estart, 0, offset + size - ptr);
diff --git a/lib/namei.c b/lib/namei.c
index 8de0a908..e0a60853 100644
--- a/lib/namei.c
+++ b/lib/namei.c
@@ -27,6 +27,7 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi)
struct erofs_sb_info *sbi = vi->sbi;
erofs_blk_t blkaddr = erofs_blknr(sbi, erofs_iloc(vi));
unsigned int ofs = erofs_blkoff(sbi, erofs_iloc(vi));
+ bool in_mbox = erofs_inode_in_metabox(vi);
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
erofs_blk_t addrmask = BIT_ULL(48) - 1;
struct erofs_inode_extended *die, copied;
@@ -35,7 +36,7 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi)
void *ptr;
int err = 0;
- ptr = erofs_read_metabuf(&buf, sbi, erofs_pos(sbi, blkaddr));
+ ptr = erofs_read_metabuf(&buf, sbi, erofs_pos(sbi, blkaddr), in_mbox);
if (IS_ERR(ptr)) {
err = PTR_ERR(ptr);
erofs_err("failed to get inode (nid: %llu) page, err %d",
@@ -74,7 +75,7 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi)
memcpy(&copied, dic, gotten);
ptr = erofs_read_metabuf(&buf, sbi,
- erofs_pos(sbi, blkaddr + 1));
+ erofs_pos(sbi, blkaddr + 1), in_mbox);
if (IS_ERR(ptr)) {
err = PTR_ERR(ptr);
erofs_err("failed to get inode payload block (nid: %llu), err %d",
diff --git a/lib/super.c b/lib/super.c
index 1d13e6e3..57849fbf 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -79,7 +79,7 @@ int erofs_read_superblock(struct erofs_sb_info *sbi)
int read, ret;
read = erofs_io_pread(&sbi->bdev, data, EROFS_MAX_BLOCK_SIZE, 0);
- if (read < EROFS_SUPER_END) {
+ if (read < EROFS_SUPER_OFFSET + sizeof(*dsb)) {
ret = read < 0 ? read : -EIO;
erofs_err("cannot read erofs superblock: %s",
erofs_strerror(ret));
@@ -123,6 +123,12 @@ int erofs_read_superblock(struct erofs_sb_info *sbi)
sbi->root_nid = le16_to_cpu(dsb->rb.rootnid_2b);
}
sbi->packed_nid = le64_to_cpu(dsb->packed_nid);
+ if (erofs_sb_has_metabox(sbi)) {
+ if (sbi->sb_size <= offsetof(struct erofs_super_block,
+ metabox_nid))
+ return -EFSCORRUPTED;
+ sbi->metabox_nid = le64_to_cpu(dsb->metabox_nid);
+ }
sbi->inos = le64_to_cpu(dsb->inos);
sbi->checksum = le32_to_cpu(dsb->checksum);
@@ -187,7 +193,6 @@ int erofs_writesb(struct erofs_sb_info *sbi, struct erofs_buffer_head *sb_bh)
.devt_slotoff = cpu_to_le16(sbi->devt_slotoff),
.packed_nid = cpu_to_le64(sbi->packed_nid),
};
- const u32 sb_blksize = round_up(EROFS_SUPER_END, erofs_blksiz(sbi));
char *buf;
int ret;
@@ -205,16 +210,21 @@ int erofs_writesb(struct erofs_sb_info *sbi, struct erofs_buffer_head *sb_bh)
else
sb.u1.lz4_max_distance = cpu_to_le16(sbi->lz4.max_distance);
- buf = calloc(sb_blksize, 1);
+ if (erofs_sb_has_metabox(sbi))
+ sb.metabox_nid = cpu_to_le64(sbi->metabox_nid);
+ sb.sb_extslots = (sbi->sb_size - 128) >> 4;
+
+ buf = calloc(round_up(EROFS_SUPER_OFFSET + sbi->sb_size,
+ erofs_blksiz(sbi)), 1);
if (!buf) {
erofs_err("failed to allocate memory for sb: %s",
erofs_strerror(-errno));
return -ENOMEM;
}
- memcpy(buf + EROFS_SUPER_OFFSET, &sb, sizeof(sb));
+ memcpy(buf + EROFS_SUPER_OFFSET, &sb, sbi->sb_size);
ret = erofs_dev_write(sbi, buf, sb_bh ? erofs_btell(sb_bh, false) : 0,
- EROFS_SUPER_END);
+ EROFS_SUPER_OFFSET + sbi->sb_size);
free(buf);
if (sb_bh)
erofs_bdrop(sb_bh, false);
@@ -223,9 +233,16 @@ int erofs_writesb(struct erofs_sb_info *sbi, struct erofs_buffer_head *sb_bh)
struct erofs_buffer_head *erofs_reserve_sb(struct erofs_bufmgr *bmgr)
{
+ struct erofs_sb_info *sbi = bmgr->sbi;
struct erofs_buffer_head *bh;
+ unsigned int sb_size = 128;
int err;
+ if (erofs_sb_has_metabox(sbi) &&
+ sb_size <= offsetof(struct erofs_super_block, metabox_nid))
+ sb_size = offsetof(struct erofs_super_block, metabox_nid) + 8;
+ sbi->sb_size = round_up(sb_size, 16);
+
bh = erofs_balloc(bmgr, META, 0, 0);
if (IS_ERR(bh)) {
erofs_err("failed to allocate super: %s",
@@ -233,7 +250,7 @@ struct erofs_buffer_head *erofs_reserve_sb(struct erofs_bufmgr *bmgr)
return bh;
}
bh->op = &erofs_skip_write_bhops;
- err = erofs_bh_balloon(bh, EROFS_SUPER_END);
+ err = erofs_bh_balloon(bh, EROFS_SUPER_OFFSET + sbi->sb_size);
if (err < 0) {
erofs_err("failed to balloon super: %s", erofs_strerror(err));
goto err_bdrop;
diff --git a/lib/xattr.c b/lib/xattr.c
index a2ef8d20..1f6a83f6 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -1079,7 +1079,7 @@ static int init_inode_xattrs(struct erofs_inode *vi)
it.ofs = erofs_blkoff(sbi, erofs_iloc(vi) + vi->inode_isize);
/* read in shared xattr array (non-atomic, see kmalloc below) */
- it.kaddr = erofs_read_metabuf(&it.buf, sbi, erofs_pos(sbi, it.blkaddr));
+ it.kaddr = erofs_read_metabuf(&it.buf, sbi, erofs_pos(sbi, it.blkaddr), false);
if (IS_ERR(it.kaddr))
return PTR_ERR(it.kaddr);
@@ -1101,7 +1101,7 @@ static int init_inode_xattrs(struct erofs_inode *vi)
DBG_BUGON(it.ofs != erofs_blksiz(sbi));
it.kaddr = erofs_read_metabuf(&it.buf, sbi,
- erofs_pos(sbi, ++it.blkaddr));
+ erofs_pos(sbi, ++it.blkaddr), false);
if (IS_ERR(it.kaddr)) {
free(vi->xattr_shared_xattrs);
vi->xattr_shared_xattrs = NULL;
@@ -1143,7 +1143,7 @@ static inline int xattr_iter_fixup(struct xattr_iter *it)
it->blkaddr += erofs_blknr(sbi, it->ofs);
it->kaddr = erofs_read_metabuf(&it->buf, sbi,
- erofs_pos(sbi, it->blkaddr));
+ erofs_pos(sbi, it->blkaddr), false);
if (IS_ERR(it->kaddr))
return PTR_ERR(it->kaddr);
it->ofs = erofs_blkoff(sbi, it->ofs);
@@ -1168,7 +1168,7 @@ static int inline_xattr_iter_begin(struct xattr_iter *it,
it->ofs = erofs_blkoff(sbi, erofs_iloc(vi) + inline_xattr_ofs);
it->kaddr = erofs_read_metabuf(&it->buf, sbi,
- erofs_pos(sbi, it->blkaddr));
+ erofs_pos(sbi, it->blkaddr), false);
if (IS_ERR(it->kaddr))
return PTR_ERR(it->kaddr);
return vi->xattr_isize - xattr_header_sz;
@@ -1393,7 +1393,7 @@ static int shared_getxattr(struct erofs_inode *vi, struct getxattr_iter *it)
it->it.ofs = xattrblock_offset(vi, vi->xattr_shared_xattrs[i]);
it->it.kaddr = erofs_read_metabuf(&it->it.buf, sbi,
- erofs_pos(sbi, blkaddr));
+ erofs_pos(sbi, blkaddr), false);
if (IS_ERR(it->it.kaddr))
return PTR_ERR(it->it.kaddr);
it->it.blkaddr = blkaddr;
@@ -1548,7 +1548,7 @@ static int shared_listxattr(struct erofs_inode *vi, struct listxattr_iter *it)
it->it.ofs = xattrblock_offset(vi, vi->xattr_shared_xattrs[i]);
it->it.kaddr = erofs_read_metabuf(&it->it.buf, sbi,
- erofs_pos(sbi, blkaddr));
+ erofs_pos(sbi, blkaddr), false);
if (IS_ERR(it->it.kaddr))
return PTR_ERR(it->it.kaddr);
it->it.blkaddr = blkaddr;
diff --git a/lib/zmap.c b/lib/zmap.c
index db8561be..916b0d25 100644
--- a/lib/zmap.c
+++ b/lib/zmap.c
@@ -35,7 +35,8 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m,
struct z_erofs_lcluster_index *di;
unsigned int advise;
- di = erofs_read_metabuf(&m->map->buf, sbi, pos);
+ di = erofs_read_metabuf(&m->map->buf, sbi, pos,
+ erofs_inode_in_metabox(vi));
if (IS_ERR(di))
return PTR_ERR(di);
m->lcn = lcn;
@@ -150,7 +151,8 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m,
else
return -EOPNOTSUPP;
- in = erofs_read_metabuf(&m->map->buf, sbi, pos);
+ in = erofs_read_metabuf(&m->map->buf, sbi, pos,
+ erofs_inode_in_metabox(vi));
if (IS_ERR(in))
return PTR_ERR(in);
@@ -541,6 +543,7 @@ static int z_erofs_map_blocks_ext(struct erofs_inode *vi,
unsigned int recsz = z_erofs_extent_recsize(vi->z_advise);
erofs_off_t pos = round_up(Z_EROFS_MAP_HEADER_END(erofs_iloc(vi) +
vi->inode_isize + vi->xattr_isize), recsz);
+ bool in_mbox = erofs_inode_in_metabox(vi);
erofs_off_t lend = vi->i_size;
erofs_off_t l, r, mid, pa, la, lstart;
struct z_erofs_extent *ext;
@@ -550,7 +553,7 @@ static int z_erofs_map_blocks_ext(struct erofs_inode *vi,
map->m_flags = 0;
if (recsz <= offsetof(struct z_erofs_extent, pstart_hi)) {
if (recsz <= offsetof(struct z_erofs_extent, pstart_lo)) {
- ext = erofs_read_metabuf(&map->buf, sbi, pos);
+ ext = erofs_read_metabuf(&map->buf, sbi, pos, in_mbox);
if (IS_ERR(ext))
return PTR_ERR(ext);
pa = le64_to_cpu(*(__le64 *)ext);
@@ -562,7 +565,7 @@ static int z_erofs_map_blocks_ext(struct erofs_inode *vi,
}
for (; lstart <= map->m_la; lstart += 1 << vi->z_lclusterbits) {
- ext = erofs_read_metabuf(&map->buf, sbi, pos);
+ ext = erofs_read_metabuf(&map->buf, sbi, pos, in_mbox);
if (IS_ERR(ext))
return PTR_ERR(ext);
map->m_plen = le32_to_cpu(ext->plen);
@@ -582,7 +585,7 @@ static int z_erofs_map_blocks_ext(struct erofs_inode *vi,
for (l = 0, r = vi->z_extents; l < r; ) {
mid = l + (r - l) / 2;
ext = erofs_read_metabuf(&map->buf, sbi,
- pos + mid * recsz);
+ pos + mid * recsz, in_mbox);
if (IS_ERR(ext))
return PTR_ERR(ext);
@@ -651,7 +654,7 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
return 0;
pos = round_up(erofs_iloc(vi) + vi->inode_isize + vi->xattr_isize, 8);
- h = erofs_read_metabuf(&buf, sbi, pos);
+ h = erofs_read_metabuf(&buf, sbi, pos, erofs_inode_in_metabox(vi));
if (IS_ERR(h))
return PTR_ERR(h);
--
2.43.5
More information about the Linux-erofs
mailing list