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;
}
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;
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;
}
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.
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;
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;
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];
}
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;
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;
}
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)) {
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;