mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
erofs: do sanity check on m->type in z_erofs_load_compact_lcluster()
All below functions will do sanity check on m->type, let's move sanity check to z_erofs_load_compact_lcluster() for cleanup. - z_erofs_map_blocks_fo - z_erofs_get_extent_compressedlen - z_erofs_get_extent_decompressedlen - z_erofs_extent_lookback Reviewed-by: Hongbo Li <lihongbo22@huawei.com> Signed-off-by: Chao Yu <chao@kernel.org> Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20250708110928.3110375-1-chao@kernel.org Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
This commit is contained in:
parent
96debe8c27
commit
1a5223c182
103
fs/erofs/zmap.c
103
fs/erofs/zmap.c
|
|
@ -240,6 +240,13 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m,
|
||||||
static int z_erofs_load_lcluster_from_disk(struct z_erofs_maprecorder *m,
|
static int z_erofs_load_lcluster_from_disk(struct z_erofs_maprecorder *m,
|
||||||
unsigned int lcn, bool lookahead)
|
unsigned int lcn, bool lookahead)
|
||||||
{
|
{
|
||||||
|
if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) {
|
||||||
|
erofs_err(m->inode->i_sb, "unknown type %u @ lcn %u of nid %llu",
|
||||||
|
m->type, lcn, EROFS_I(m->inode)->nid);
|
||||||
|
DBG_BUGON(1);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
switch (EROFS_I(m->inode)->datalayout) {
|
switch (EROFS_I(m->inode)->datalayout) {
|
||||||
case EROFS_INODE_COMPRESSED_FULL:
|
case EROFS_INODE_COMPRESSED_FULL:
|
||||||
return z_erofs_load_full_lcluster(m, lcn);
|
return z_erofs_load_full_lcluster(m, lcn);
|
||||||
|
|
@ -265,12 +272,7 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) {
|
if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
||||||
erofs_err(sb, "unknown type %u @ lcn %lu of nid %llu",
|
|
||||||
m->type, lcn, vi->nid);
|
|
||||||
DBG_BUGON(1);
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
} else if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
|
||||||
lookback_distance = m->delta[0];
|
lookback_distance = m->delta[0];
|
||||||
if (!lookback_distance)
|
if (!lookback_distance)
|
||||||
break;
|
break;
|
||||||
|
|
@ -325,25 +327,18 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
|
||||||
DBG_BUGON(lcn == initial_lcn &&
|
DBG_BUGON(lcn == initial_lcn &&
|
||||||
m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD);
|
m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD);
|
||||||
|
|
||||||
if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD && m->delta[0] != 1) {
|
||||||
if (m->delta[0] != 1) {
|
erofs_err(sb, "bogus CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);
|
||||||
erofs_err(sb, "bogus CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);
|
DBG_BUGON(1);
|
||||||
DBG_BUGON(1);
|
return -EFSCORRUPTED;
|
||||||
return -EFSCORRUPTED;
|
|
||||||
}
|
|
||||||
if (m->compressedblks)
|
|
||||||
goto out;
|
|
||||||
} else if (m->type < Z_EROFS_LCLUSTER_TYPE_MAX) {
|
|
||||||
/*
|
|
||||||
* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
|
|
||||||
* rather than CBLKCNT, it's a 1 block-sized pcluster.
|
|
||||||
*/
|
|
||||||
m->compressedblks = 1;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
erofs_err(sb, "cannot found CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);
|
|
||||||
DBG_BUGON(1);
|
/*
|
||||||
return -EFSCORRUPTED;
|
* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type rather
|
||||||
|
* than CBLKCNT, it's a 1 block-sized pcluster.
|
||||||
|
*/
|
||||||
|
if (m->type != Z_EROFS_LCLUSTER_TYPE_NONHEAD || !m->compressedblks)
|
||||||
|
m->compressedblks = 1;
|
||||||
out:
|
out:
|
||||||
m->map->m_plen = erofs_pos(sb, m->compressedblks);
|
m->map->m_plen = erofs_pos(sb, m->compressedblks);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -379,11 +374,6 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
|
||||||
if (lcn != headlcn)
|
if (lcn != headlcn)
|
||||||
break; /* ends at the next HEAD lcluster */
|
break; /* ends at the next HEAD lcluster */
|
||||||
m->delta[1] = 1;
|
m->delta[1] = 1;
|
||||||
} else {
|
|
||||||
erofs_err(inode->i_sb, "unknown type %u @ lcn %llu of nid %llu",
|
|
||||||
m->type, lcn, vi->nid);
|
|
||||||
DBG_BUGON(1);
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
}
|
||||||
lcn += m->delta[1];
|
lcn += m->delta[1];
|
||||||
}
|
}
|
||||||
|
|
@ -428,44 +418,33 @@ static int z_erofs_map_blocks_fo(struct inode *inode,
|
||||||
map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_ENCODED;
|
map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_ENCODED;
|
||||||
end = (m.lcn + 1ULL) << lclusterbits;
|
end = (m.lcn + 1ULL) << lclusterbits;
|
||||||
|
|
||||||
switch (m.type) {
|
if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD && endoff >= m.clusterofs) {
|
||||||
case Z_EROFS_LCLUSTER_TYPE_PLAIN:
|
m.headtype = m.type;
|
||||||
case Z_EROFS_LCLUSTER_TYPE_HEAD1:
|
map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
|
||||||
case Z_EROFS_LCLUSTER_TYPE_HEAD2:
|
/*
|
||||||
if (endoff >= m.clusterofs) {
|
* For ztailpacking files, in order to inline data more
|
||||||
m.headtype = m.type;
|
* effectively, special EOF lclusters are now supported
|
||||||
map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
|
* which can have three parts at most.
|
||||||
/*
|
*/
|
||||||
* For ztailpacking files, in order to inline data more
|
if (ztailpacking && end > inode->i_size)
|
||||||
* effectively, special EOF lclusters are now supported
|
end = inode->i_size;
|
||||||
* which can have three parts at most.
|
} else {
|
||||||
*/
|
if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
||||||
if (ztailpacking && end > inode->i_size)
|
/* m.lcn should be >= 1 if endoff < m.clusterofs */
|
||||||
end = inode->i_size;
|
if (!m.lcn) {
|
||||||
break;
|
erofs_err(sb, "invalid logical cluster 0 at nid %llu",
|
||||||
|
vi->nid);
|
||||||
|
err = -EFSCORRUPTED;
|
||||||
|
goto unmap_out;
|
||||||
|
}
|
||||||
|
end = (m.lcn << lclusterbits) | m.clusterofs;
|
||||||
|
map->m_flags |= EROFS_MAP_FULL_MAPPED;
|
||||||
|
m.delta[0] = 1;
|
||||||
}
|
}
|
||||||
/* m.lcn should be >= 1 if endoff < m.clusterofs */
|
|
||||||
if (!m.lcn) {
|
|
||||||
erofs_err(sb, "invalid logical cluster 0 at nid %llu",
|
|
||||||
vi->nid);
|
|
||||||
err = -EFSCORRUPTED;
|
|
||||||
goto unmap_out;
|
|
||||||
}
|
|
||||||
end = (m.lcn << lclusterbits) | m.clusterofs;
|
|
||||||
map->m_flags |= EROFS_MAP_FULL_MAPPED;
|
|
||||||
m.delta[0] = 1;
|
|
||||||
fallthrough;
|
|
||||||
case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
|
|
||||||
/* get the corresponding first chunk */
|
/* get the corresponding first chunk */
|
||||||
err = z_erofs_extent_lookback(&m, m.delta[0]);
|
err = z_erofs_extent_lookback(&m, m.delta[0]);
|
||||||
if (err)
|
if (err)
|
||||||
goto unmap_out;
|
goto unmap_out;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
erofs_err(sb, "unknown type %u @ offset %llu of nid %llu",
|
|
||||||
m.type, ofs, vi->nid);
|
|
||||||
err = -EOPNOTSUPP;
|
|
||||||
goto unmap_out;
|
|
||||||
}
|
}
|
||||||
if (m.partialref)
|
if (m.partialref)
|
||||||
map->m_flags |= EROFS_MAP_PARTIAL_REF;
|
map->m_flags |= EROFS_MAP_PARTIAL_REF;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user