| From stable+bounces-164451-greg=kroah.com@vger.kernel.org Wed Jul 23 15:50:29 2025 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 23 Jul 2025 09:50:08 -0400 |
| Subject: erofs: clean up header parsing for ztailpacking and fragments |
| To: stable@vger.kernel.org |
| Cc: Gao Xiang <hsiangkao@linux.alibaba.com>, Chao Yu <chao@kernel.org>, Sasha Levin <sashal@kernel.org> |
| Message-ID: <20250723135009.1089152-5-sashal@kernel.org> |
| |
| From: Gao Xiang <hsiangkao@linux.alibaba.com> |
| |
| [ Upstream commit 540787d38b10dbc16a7d2bc2845752ab1605403a ] |
| |
| Simplify the logic in z_erofs_fill_inode_lazy() by combining the |
| handling of ztailpacking and fragments, as they are mutually exclusive. |
| |
| Note that `h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT` is handled |
| above, so no need to duplicate the check. |
| |
| Reviewed-by: Chao Yu <chao@kernel.org> |
| Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> |
| Link: https://lore.kernel.org/r/20250224123747.1387122-2-hsiangkao@linux.alibaba.com |
| Stable-dep-of: b44686c8391b ("erofs: fix large fragment handling") |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/erofs/zmap.c | 39 ++++++++++++++------------------------- |
| 1 file changed, 14 insertions(+), 25 deletions(-) |
| |
| --- a/fs/erofs/zmap.c |
| +++ b/fs/erofs/zmap.c |
| @@ -394,7 +394,8 @@ static int z_erofs_get_extent_decompress |
| static int z_erofs_do_map_blocks(struct inode *inode, |
| struct erofs_map_blocks *map, int flags) |
| { |
| - struct erofs_inode *const vi = EROFS_I(inode); |
| + struct erofs_inode *vi = EROFS_I(inode); |
| + struct super_block *sb = inode->i_sb; |
| bool fragment = vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER; |
| bool ztailpacking = vi->z_idata_size; |
| struct z_erofs_maprecorder m = { |
| @@ -438,7 +439,7 @@ static int z_erofs_do_map_blocks(struct |
| } |
| /* m.lcn should be >= 1 if endoff < m.clusterofs */ |
| if (!m.lcn) { |
| - erofs_err(inode->i_sb, "invalid logical cluster 0 at nid %llu", |
| + erofs_err(sb, "invalid logical cluster 0 at nid %llu", |
| vi->nid); |
| err = -EFSCORRUPTED; |
| goto unmap_out; |
| @@ -454,7 +455,7 @@ static int z_erofs_do_map_blocks(struct |
| goto unmap_out; |
| break; |
| default: |
| - erofs_err(inode->i_sb, "unknown type %u @ offset %llu of nid %llu", |
| + erofs_err(sb, "unknown type %u @ offset %llu of nid %llu", |
| m.type, ofs, vi->nid); |
| err = -EOPNOTSUPP; |
| goto unmap_out; |
| @@ -473,10 +474,16 @@ static int z_erofs_do_map_blocks(struct |
| map->m_flags |= EROFS_MAP_META; |
| map->m_pa = vi->z_fragmentoff; |
| map->m_plen = vi->z_idata_size; |
| + if (erofs_blkoff(sb, map->m_pa) + map->m_plen > sb->s_blocksize) { |
| + erofs_err(sb, "invalid tail-packing pclustersize %llu", |
| + map->m_plen); |
| + err = -EFSCORRUPTED; |
| + goto unmap_out; |
| + } |
| } else if (fragment && m.lcn == vi->z_tailextent_headlcn) { |
| map->m_flags |= EROFS_MAP_FRAGMENT; |
| } else { |
| - map->m_pa = erofs_pos(inode->i_sb, m.pblk); |
| + map->m_pa = erofs_pos(sb, m.pblk); |
| err = z_erofs_get_extent_compressedlen(&m, initial_lcn); |
| if (err) |
| goto unmap_out; |
| @@ -495,7 +502,7 @@ static int z_erofs_do_map_blocks(struct |
| afmt = m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2 ? |
| vi->z_algorithmtype[1] : vi->z_algorithmtype[0]; |
| if (!(EROFS_I_SB(inode)->available_compr_algs & (1 << afmt))) { |
| - erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu", |
| + erofs_err(sb, "inconsistent algorithmtype %u for nid %llu", |
| afmt, vi->nid); |
| err = -EFSCORRUPTED; |
| goto unmap_out; |
| @@ -596,26 +603,8 @@ static int z_erofs_fill_inode_lazy(struc |
| goto out_put_metabuf; |
| } |
| |
| - if (vi->z_idata_size) { |
| - struct erofs_map_blocks map = { |
| - .buf = __EROFS_BUF_INITIALIZER |
| - }; |
| - |
| - err = z_erofs_do_map_blocks(inode, &map, |
| - EROFS_GET_BLOCKS_FINDTAIL); |
| - erofs_put_metabuf(&map.buf); |
| - |
| - if (erofs_blkoff(sb, map.m_pa) + map.m_plen > sb->s_blocksize) { |
| - erofs_err(sb, "invalid tail-packing pclustersize %llu", |
| - map.m_plen); |
| - err = -EFSCORRUPTED; |
| - } |
| - if (err < 0) |
| - goto out_put_metabuf; |
| - } |
| - |
| - if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER && |
| - !(h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT)) { |
| + if (vi->z_idata_size || |
| + (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER)) { |
| struct erofs_map_blocks map = { |
| .buf = __EROFS_BUF_INITIALIZER |
| }; |