[PATCH 4/9] erofs-utils: lib: introduce the secondary compression head
Gao Xiang
hsiangkao at linux.alibaba.com
Thu Feb 6 23:50:29 AEDT 2025
Source kernel commit: 72bb52620fdffca95a14ee52188a33cd84e574e2
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
lib/zmap.c | 46 ++++++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/lib/zmap.c b/lib/zmap.c
index 0a9bc6a..ee0af1f 100644
--- a/lib/zmap.c
+++ b/lib/zmap.c
@@ -71,7 +71,8 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m,
m->clusterofs = 1 << vi->z_logical_clusterbits;
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)) {
+ if (!(vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 |
+ Z_EROFS_ADVISE_BIG_PCLUSTER_2))) {
DBG_BUGON(1);
return -EFSCORRUPTED;
}
@@ -327,6 +328,7 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
return z_erofs_extent_lookback(m, m->delta[0]);
case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_LCLUSTER_TYPE_HEAD1:
+ case Z_EROFS_LCLUSTER_TYPE_HEAD2:
m->headtype = m->type;
map->m_la = (lcn << lclusterbits) | m->clusterofs;
break;
@@ -350,10 +352,15 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
int err;
DBG_BUGON(m->type != Z_EROFS_LCLUSTER_TYPE_PLAIN &&
- m->type != Z_EROFS_LCLUSTER_TYPE_HEAD1);
+ m->type != Z_EROFS_LCLUSTER_TYPE_HEAD1 &&
+ m->type != Z_EROFS_LCLUSTER_TYPE_HEAD2);
+ DBG_BUGON(m->type != m->headtype);
if (m->headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
- !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) {
+ ((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD1) &&
+ !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) ||
+ ((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) &&
+ !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2))) {
map->m_plen = 1 << lclusterbits;
return 0;
}
@@ -380,6 +387,7 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
switch (m->type) {
case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_LCLUSTER_TYPE_HEAD1:
+ case Z_EROFS_LCLUSTER_TYPE_HEAD2:
/*
* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
* rather than CBLKCNT, it's a 1 lcluster-sized pcluster.
@@ -431,7 +439,8 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
DBG_BUGON(!m->delta[1] &&
m->clusterofs != 1 << lclusterbits);
} else if (m->type == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
- m->type == Z_EROFS_LCLUSTER_TYPE_HEAD1) {
+ m->type == Z_EROFS_LCLUSTER_TYPE_HEAD1 ||
+ m->type == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
/* go on until the next HEAD lcluster */
if (lcn != headlcn)
break;
@@ -484,6 +493,7 @@ static int z_erofs_do_map_blocks(struct erofs_inode *vi,
switch (m.type) {
case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_LCLUSTER_TYPE_HEAD1:
+ case Z_EROFS_LCLUSTER_TYPE_HEAD2:
if (endoff >= m.clusterofs) {
m.headtype = m.type;
map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
@@ -553,6 +563,8 @@ static int z_erofs_do_map_blocks(struct erofs_inode *vi,
else
map->m_algorithmformat =
Z_EROFS_COMPRESSION_SHIFTED;
+ } else if (m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
+ map->m_algorithmformat = vi->z_algorithmtype[1];
} else {
map->m_algorithmformat = vi->z_algorithmtype[0];
}
@@ -572,18 +584,18 @@ out:
static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
{
- int ret;
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;
if (vi->flags & EROFS_I_Z_INITED)
return 0;
pos = round_up(erofs_iloc(vi) + vi->inode_isize + vi->xattr_isize, 8);
- ret = erofs_dev_read(sbi, 0, buf, pos, sizeof(buf));
- if (ret < 0)
+ err = erofs_dev_read(sbi, 0, buf, pos, sizeof(buf));
+ if (err < 0)
return -EIO;
h = (struct z_erofs_map_header *)buf;
@@ -602,9 +614,11 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
vi->z_algorithmtype[0] = h->h_algorithmtype & 15;
vi->z_algorithmtype[1] = h->h_algorithmtype >> 4;
- if (vi->z_algorithmtype[0] >= Z_EROFS_COMPRESSION_MAX) {
- erofs_err("unknown compression format %u for nid %llu",
- vi->z_algorithmtype[0], (unsigned long long)vi->nid);
+ headnr = 0;
+ if (vi->z_algorithmtype[0] >= Z_EROFS_COMPRESSION_MAX ||
+ 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;
}
@@ -621,7 +635,7 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
struct erofs_map_blocks map = { .index = UINT_MAX };
vi->idata_size = le16_to_cpu(h->h_idata_size);
- ret = z_erofs_do_map_blocks(vi, &map,
+ err = z_erofs_do_map_blocks(vi, &map,
EROFS_GET_BLOCKS_FINDTAIL);
if (!map.m_plen ||
erofs_blkoff(sbi, map.m_pa) + map.m_plen > erofs_blksiz(sbi)) {
@@ -629,18 +643,18 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
map.m_plen | 0ULL);
return -EFSCORRUPTED;
}
- if (ret < 0)
- return ret;
+ if (err < 0)
+ return err;
}
if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER &&
!(h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT)) {
struct erofs_map_blocks map = { .index = UINT_MAX };
vi->fragmentoff = le32_to_cpu(h->h_fragmentoff);
- ret = z_erofs_do_map_blocks(vi, &map,
+ err = z_erofs_do_map_blocks(vi, &map,
EROFS_GET_BLOCKS_FINDTAIL);
- if (ret < 0)
- return ret;
+ if (err < 0)
+ return err;
}
out:
vi->flags |= EROFS_I_Z_INITED;
--
2.43.5
More information about the Linux-erofs
mailing list