Skip to content

Commit 4459ce1

Browse files
chaseyugregkh
authored andcommitted
erofs: do sanity check on m->type in z_erofs_load_compact_lcluster()
[ Upstream commit 1a5223c ] 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> Stable-dep-of: 2d8c7ed ("erofs: unify lcn as u64 for 32-bit platforms") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent fba3407 commit 4459ce1

1 file changed

Lines changed: 41 additions & 62 deletions

File tree

fs/erofs/zmap.c

Lines changed: 41 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,13 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m,
240240
static int z_erofs_load_lcluster_from_disk(struct z_erofs_maprecorder *m,
241241
unsigned int lcn, bool lookahead)
242242
{
243+
if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) {
244+
erofs_err(m->inode->i_sb, "unknown type %u @ lcn %u of nid %llu",
245+
m->type, lcn, EROFS_I(m->inode)->nid);
246+
DBG_BUGON(1);
247+
return -EOPNOTSUPP;
248+
}
249+
243250
switch (EROFS_I(m->inode)->datalayout) {
244251
case EROFS_INODE_COMPRESSED_FULL:
245252
return z_erofs_load_full_lcluster(m, lcn);
@@ -265,12 +272,7 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
265272
if (err)
266273
return err;
267274

268-
if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) {
269-
erofs_err(sb, "unknown type %u @ lcn %lu of nid %llu",
270-
m->type, lcn, vi->nid);
271-
DBG_BUGON(1);
272-
return -EOPNOTSUPP;
273-
} else if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
275+
if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
274276
lookback_distance = m->delta[0];
275277
if (!lookback_distance)
276278
break;
@@ -325,25 +327,18 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
325327
DBG_BUGON(lcn == initial_lcn &&
326328
m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD);
327329

328-
if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
329-
if (m->delta[0] != 1) {
330-
erofs_err(sb, "bogus CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);
331-
DBG_BUGON(1);
332-
return -EFSCORRUPTED;
333-
}
334-
if (m->compressedblks)
335-
goto out;
336-
} else if (m->type < Z_EROFS_LCLUSTER_TYPE_MAX) {
337-
/*
338-
* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
339-
* rather than CBLKCNT, it's a 1 block-sized pcluster.
340-
*/
341-
m->compressedblks = 1;
342-
goto out;
330+
if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD && m->delta[0] != 1) {
331+
erofs_err(sb, "bogus CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);
332+
DBG_BUGON(1);
333+
return -EFSCORRUPTED;
343334
}
344-
erofs_err(sb, "cannot found CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);
345-
DBG_BUGON(1);
346-
return -EFSCORRUPTED;
335+
336+
/*
337+
* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type rather
338+
* than CBLKCNT, it's a 1 block-sized pcluster.
339+
*/
340+
if (m->type != Z_EROFS_LCLUSTER_TYPE_NONHEAD || !m->compressedblks)
341+
m->compressedblks = 1;
347342
out:
348343
m->map->m_plen = erofs_pos(sb, m->compressedblks);
349344
return 0;
@@ -379,11 +374,6 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
379374
if (lcn != headlcn)
380375
break; /* ends at the next HEAD lcluster */
381376
m->delta[1] = 1;
382-
} else {
383-
erofs_err(inode->i_sb, "unknown type %u @ lcn %llu of nid %llu",
384-
m->type, lcn, vi->nid);
385-
DBG_BUGON(1);
386-
return -EOPNOTSUPP;
387377
}
388378
lcn += m->delta[1];
389379
}
@@ -421,44 +411,33 @@ static int z_erofs_do_map_blocks(struct inode *inode,
421411
map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_ENCODED;
422412
end = (m.lcn + 1ULL) << lclusterbits;
423413

424-
switch (m.type) {
425-
case Z_EROFS_LCLUSTER_TYPE_PLAIN:
426-
case Z_EROFS_LCLUSTER_TYPE_HEAD1:
427-
case Z_EROFS_LCLUSTER_TYPE_HEAD2:
428-
if (endoff >= m.clusterofs) {
429-
m.headtype = m.type;
430-
map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
431-
/*
432-
* For ztailpacking files, in order to inline data more
433-
* effectively, special EOF lclusters are now supported
434-
* which can have three parts at most.
435-
*/
436-
if (ztailpacking && end > inode->i_size)
437-
end = inode->i_size;
438-
break;
439-
}
440-
/* m.lcn should be >= 1 if endoff < m.clusterofs */
441-
if (!m.lcn) {
442-
erofs_err(sb, "invalid logical cluster 0 at nid %llu",
443-
vi->nid);
444-
err = -EFSCORRUPTED;
445-
goto unmap_out;
414+
if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD && endoff >= m.clusterofs) {
415+
m.headtype = m.type;
416+
map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
417+
/*
418+
* For ztailpacking files, in order to inline data more
419+
* effectively, special EOF lclusters are now supported
420+
* which can have three parts at most.
421+
*/
422+
if (ztailpacking && end > inode->i_size)
423+
end = inode->i_size;
424+
} else {
425+
if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
426+
/* m.lcn should be >= 1 if endoff < m.clusterofs */
427+
if (!m.lcn) {
428+
erofs_err(sb, "invalid logical cluster 0 at nid %llu",
429+
vi->nid);
430+
err = -EFSCORRUPTED;
431+
goto unmap_out;
432+
}
433+
end = (m.lcn << lclusterbits) | m.clusterofs;
434+
map->m_flags |= EROFS_MAP_FULL_MAPPED;
435+
m.delta[0] = 1;
446436
}
447-
end = (m.lcn << lclusterbits) | m.clusterofs;
448-
map->m_flags |= EROFS_MAP_FULL_MAPPED;
449-
m.delta[0] = 1;
450-
fallthrough;
451-
case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
452437
/* get the corresponding first chunk */
453438
err = z_erofs_extent_lookback(&m, m.delta[0]);
454439
if (err)
455440
goto unmap_out;
456-
break;
457-
default:
458-
erofs_err(sb, "unknown type %u @ offset %llu of nid %llu",
459-
m.type, ofs, vi->nid);
460-
err = -EOPNOTSUPP;
461-
goto unmap_out;
462441
}
463442
if (m.partialref)
464443
map->m_flags |= EROFS_MAP_PARTIAL_REF;

0 commit comments

Comments
 (0)