Commit 7c3ca183 authored by Gao Xiang's avatar Gao Xiang

erofs: restrict pcluster size limitations

Error out if {en,de}encoded size of a pcluster is unsupported:
  Maximum supported encoded size (of a pcluster):  1 MiB
  Maximum supported decoded size (of a pcluster): 12 MiB

Users can still choose to use supported large configurations (e.g.,
for archival purposes), but there may be performance penalties in
low-memory scenarios compared to smaller pclusters.
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20240912074156.2925394-1-hsiangkao@linux.alibaba.com
parent 79f504a2
...@@ -288,9 +288,12 @@ struct erofs_dirent { ...@@ -288,9 +288,12 @@ struct erofs_dirent {
#define EROFS_NAME_LEN 255 #define EROFS_NAME_LEN 255
/* maximum supported size of a physical compression cluster */ /* maximum supported encoded size of a physical compressed cluster */
#define Z_EROFS_PCLUSTER_MAX_SIZE (1024 * 1024) #define Z_EROFS_PCLUSTER_MAX_SIZE (1024 * 1024)
/* maximum supported decoded size of a physical compressed cluster */
#define Z_EROFS_PCLUSTER_MAX_DSIZE (12 * 1024 * 1024)
/* available compression algorithm types (for h_algorithmtype) */ /* available compression algorithm types (for h_algorithmtype) */
enum { enum {
Z_EROFS_COMPRESSION_LZ4 = 0, Z_EROFS_COMPRESSION_LZ4 = 0,
......
...@@ -687,32 +687,30 @@ int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map, ...@@ -687,32 +687,30 @@ int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map,
int err = 0; int err = 0;
trace_erofs_map_blocks_enter(inode, map, flags); trace_erofs_map_blocks_enter(inode, map, flags);
if (map->m_la >= inode->i_size) { /* post-EOF unmapped extent */
/* when trying to read beyond EOF, leave it unmapped */
if (map->m_la >= inode->i_size) {
map->m_llen = map->m_la + 1 - inode->i_size; map->m_llen = map->m_la + 1 - inode->i_size;
map->m_la = inode->i_size; map->m_la = inode->i_size;
map->m_flags = 0; map->m_flags = 0;
goto out; } else {
} err = z_erofs_fill_inode_lazy(inode);
if (!err) {
err = z_erofs_fill_inode_lazy(inode); if ((vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER) &&
if (err) !vi->z_tailextent_headlcn) {
goto out; map->m_la = 0;
map->m_llen = inode->i_size;
if ((vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER) && map->m_flags = EROFS_MAP_MAPPED |
!vi->z_tailextent_headlcn) { EROFS_MAP_FULL_MAPPED | EROFS_MAP_FRAGMENT;
map->m_la = 0; } else {
map->m_llen = inode->i_size; err = z_erofs_do_map_blocks(inode, map, flags);
map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_FULL_MAPPED | }
EROFS_MAP_FRAGMENT; }
goto out; if (!err && (map->m_flags & EROFS_MAP_ENCODED) &&
unlikely(map->m_plen > Z_EROFS_PCLUSTER_MAX_SIZE ||
map->m_llen > Z_EROFS_PCLUSTER_MAX_DSIZE))
err = -EOPNOTSUPP;
if (err)
map->m_llen = 0;
} }
err = z_erofs_do_map_blocks(inode, map, flags);
out:
if (err)
map->m_llen = 0;
trace_erofs_map_blocks_exit(inode, map, flags, err); trace_erofs_map_blocks_exit(inode, map, flags, err);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment