mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
erofs: simplify compression configuration parser
commitefb4fb02ce
upstream. Move erofs_load_compr_cfgs() into decompressor.c as well as introduce a callback instead of a hard-coded switch for each algorithm for simplicity. Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20231022130957.11398-1-xiang@kernel.org Stable-dep-of:118a8cf504
("erofs: fix inconsistent per-file compression format") Signed-off-by: Yue Hu <huyue2@coolpad.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b1301f15dd
commit
54407d9bc5
@ -21,6 +21,8 @@ struct z_erofs_decompress_req {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct z_erofs_decompressor {
|
struct z_erofs_decompressor {
|
||||||
|
int (*config)(struct super_block *sb, struct erofs_super_block *dsb,
|
||||||
|
void *data, int size);
|
||||||
int (*decompress)(struct z_erofs_decompress_req *rq,
|
int (*decompress)(struct z_erofs_decompress_req *rq,
|
||||||
struct page **pagepool);
|
struct page **pagepool);
|
||||||
char *name;
|
char *name;
|
||||||
@ -93,6 +95,8 @@ int z_erofs_decompress(struct z_erofs_decompress_req *rq,
|
|||||||
struct page **pagepool);
|
struct page **pagepool);
|
||||||
|
|
||||||
/* prototypes for specific algorithms */
|
/* prototypes for specific algorithms */
|
||||||
|
int z_erofs_load_lzma_config(struct super_block *sb,
|
||||||
|
struct erofs_super_block *dsb, void *data, int size);
|
||||||
int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
|
int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
|
||||||
struct page **pagepool);
|
struct page **pagepool);
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,11 +24,11 @@ struct z_erofs_lz4_decompress_ctx {
|
|||||||
unsigned int oend;
|
unsigned int oend;
|
||||||
};
|
};
|
||||||
|
|
||||||
int z_erofs_load_lz4_config(struct super_block *sb,
|
static int z_erofs_load_lz4_config(struct super_block *sb,
|
||||||
struct erofs_super_block *dsb,
|
struct erofs_super_block *dsb, void *data, int size)
|
||||||
struct z_erofs_lz4_cfgs *lz4, int size)
|
|
||||||
{
|
{
|
||||||
struct erofs_sb_info *sbi = EROFS_SB(sb);
|
struct erofs_sb_info *sbi = EROFS_SB(sb);
|
||||||
|
struct z_erofs_lz4_cfgs *lz4 = data;
|
||||||
u16 distance;
|
u16 distance;
|
||||||
|
|
||||||
if (lz4) {
|
if (lz4) {
|
||||||
@ -374,17 +374,71 @@ static struct z_erofs_decompressor decompressors[] = {
|
|||||||
.name = "interlaced"
|
.name = "interlaced"
|
||||||
},
|
},
|
||||||
[Z_EROFS_COMPRESSION_LZ4] = {
|
[Z_EROFS_COMPRESSION_LZ4] = {
|
||||||
|
.config = z_erofs_load_lz4_config,
|
||||||
.decompress = z_erofs_lz4_decompress,
|
.decompress = z_erofs_lz4_decompress,
|
||||||
.name = "lz4"
|
.name = "lz4"
|
||||||
},
|
},
|
||||||
#ifdef CONFIG_EROFS_FS_ZIP_LZMA
|
#ifdef CONFIG_EROFS_FS_ZIP_LZMA
|
||||||
[Z_EROFS_COMPRESSION_LZMA] = {
|
[Z_EROFS_COMPRESSION_LZMA] = {
|
||||||
|
.config = z_erofs_load_lzma_config,
|
||||||
.decompress = z_erofs_lzma_decompress,
|
.decompress = z_erofs_lzma_decompress,
|
||||||
.name = "lzma"
|
.name = "lzma"
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb)
|
||||||
|
{
|
||||||
|
struct erofs_sb_info *sbi = EROFS_SB(sb);
|
||||||
|
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
|
||||||
|
unsigned int algs, alg;
|
||||||
|
erofs_off_t offset;
|
||||||
|
int size, ret = 0;
|
||||||
|
|
||||||
|
if (!erofs_sb_has_compr_cfgs(sbi)) {
|
||||||
|
sbi->available_compr_algs = Z_EROFS_COMPRESSION_LZ4;
|
||||||
|
return z_erofs_load_lz4_config(sb, dsb, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sbi->available_compr_algs = le16_to_cpu(dsb->u1.available_compr_algs);
|
||||||
|
if (sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS) {
|
||||||
|
erofs_err(sb, "unidentified algorithms %x, please upgrade kernel",
|
||||||
|
sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = EROFS_SUPER_OFFSET + sbi->sb_size;
|
||||||
|
alg = 0;
|
||||||
|
for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) {
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
if (!(algs & 1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
data = erofs_read_metadata(sb, &buf, &offset, &size);
|
||||||
|
if (IS_ERR(data)) {
|
||||||
|
ret = PTR_ERR(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alg >= ARRAY_SIZE(decompressors) ||
|
||||||
|
!decompressors[alg].config) {
|
||||||
|
erofs_err(sb, "algorithm %d isn't enabled on this kernel",
|
||||||
|
alg);
|
||||||
|
ret = -EOPNOTSUPP;
|
||||||
|
} else {
|
||||||
|
ret = decompressors[alg].config(sb,
|
||||||
|
dsb, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(data);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
erofs_put_metabuf(&buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int z_erofs_decompress(struct z_erofs_decompress_req *rq,
|
int z_erofs_decompress(struct z_erofs_decompress_req *rq,
|
||||||
struct page **pagepool)
|
struct page **pagepool)
|
||||||
{
|
{
|
||||||
|
@ -72,10 +72,10 @@ int z_erofs_lzma_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int z_erofs_load_lzma_config(struct super_block *sb,
|
int z_erofs_load_lzma_config(struct super_block *sb,
|
||||||
struct erofs_super_block *dsb,
|
struct erofs_super_block *dsb, void *data, int size)
|
||||||
struct z_erofs_lzma_cfgs *lzma, int size)
|
|
||||||
{
|
{
|
||||||
static DEFINE_MUTEX(lzma_resize_mutex);
|
static DEFINE_MUTEX(lzma_resize_mutex);
|
||||||
|
struct z_erofs_lzma_cfgs *lzma = data;
|
||||||
unsigned int dict_size, i;
|
unsigned int dict_size, i;
|
||||||
struct z_erofs_lzma *strm, *head = NULL;
|
struct z_erofs_lzma *strm, *head = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
@ -471,6 +471,8 @@ struct erofs_map_dev {
|
|||||||
|
|
||||||
/* data.c */
|
/* data.c */
|
||||||
extern const struct file_operations erofs_file_fops;
|
extern const struct file_operations erofs_file_fops;
|
||||||
|
void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
|
||||||
|
erofs_off_t *offset, int *lengthp);
|
||||||
void erofs_unmap_metabuf(struct erofs_buf *buf);
|
void erofs_unmap_metabuf(struct erofs_buf *buf);
|
||||||
void erofs_put_metabuf(struct erofs_buf *buf);
|
void erofs_put_metabuf(struct erofs_buf *buf);
|
||||||
void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
|
void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
|
||||||
@ -565,9 +567,7 @@ void z_erofs_exit_zip_subsystem(void);
|
|||||||
int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi,
|
int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi,
|
||||||
struct erofs_workgroup *egrp);
|
struct erofs_workgroup *egrp);
|
||||||
int erofs_try_to_free_cached_page(struct page *page);
|
int erofs_try_to_free_cached_page(struct page *page);
|
||||||
int z_erofs_load_lz4_config(struct super_block *sb,
|
int z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb);
|
||||||
struct erofs_super_block *dsb,
|
|
||||||
struct z_erofs_lz4_cfgs *lz4, int len);
|
|
||||||
#else
|
#else
|
||||||
static inline void erofs_shrinker_register(struct super_block *sb) {}
|
static inline void erofs_shrinker_register(struct super_block *sb) {}
|
||||||
static inline void erofs_shrinker_unregister(struct super_block *sb) {}
|
static inline void erofs_shrinker_unregister(struct super_block *sb) {}
|
||||||
@ -575,36 +575,14 @@ static inline int erofs_init_shrinker(void) { return 0; }
|
|||||||
static inline void erofs_exit_shrinker(void) {}
|
static inline void erofs_exit_shrinker(void) {}
|
||||||
static inline int z_erofs_init_zip_subsystem(void) { return 0; }
|
static inline int z_erofs_init_zip_subsystem(void) { return 0; }
|
||||||
static inline void z_erofs_exit_zip_subsystem(void) {}
|
static inline void z_erofs_exit_zip_subsystem(void) {}
|
||||||
static inline int z_erofs_load_lz4_config(struct super_block *sb,
|
|
||||||
struct erofs_super_block *dsb,
|
|
||||||
struct z_erofs_lz4_cfgs *lz4, int len)
|
|
||||||
{
|
|
||||||
if (lz4 || dsb->u1.lz4_max_distance) {
|
|
||||||
erofs_err(sb, "lz4 algorithm isn't enabled");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* !CONFIG_EROFS_FS_ZIP */
|
#endif /* !CONFIG_EROFS_FS_ZIP */
|
||||||
|
|
||||||
#ifdef CONFIG_EROFS_FS_ZIP_LZMA
|
#ifdef CONFIG_EROFS_FS_ZIP_LZMA
|
||||||
int z_erofs_lzma_init(void);
|
int z_erofs_lzma_init(void);
|
||||||
void z_erofs_lzma_exit(void);
|
void z_erofs_lzma_exit(void);
|
||||||
int z_erofs_load_lzma_config(struct super_block *sb,
|
|
||||||
struct erofs_super_block *dsb,
|
|
||||||
struct z_erofs_lzma_cfgs *lzma, int size);
|
|
||||||
#else
|
#else
|
||||||
static inline int z_erofs_lzma_init(void) { return 0; }
|
static inline int z_erofs_lzma_init(void) { return 0; }
|
||||||
static inline int z_erofs_lzma_exit(void) { return 0; }
|
static inline int z_erofs_lzma_exit(void) { return 0; }
|
||||||
static inline int z_erofs_load_lzma_config(struct super_block *sb,
|
|
||||||
struct erofs_super_block *dsb,
|
|
||||||
struct z_erofs_lzma_cfgs *lzma, int size) {
|
|
||||||
if (lzma) {
|
|
||||||
erofs_err(sb, "lzma algorithm isn't enabled");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* !CONFIG_EROFS_FS_ZIP */
|
#endif /* !CONFIG_EROFS_FS_ZIP */
|
||||||
|
|
||||||
/* flags for erofs_fscache_register_cookie() */
|
/* flags for erofs_fscache_register_cookie() */
|
||||||
|
@ -126,8 +126,8 @@ static bool check_layout_compatibility(struct super_block *sb,
|
|||||||
|
|
||||||
#ifdef CONFIG_EROFS_FS_ZIP
|
#ifdef CONFIG_EROFS_FS_ZIP
|
||||||
/* read variable-sized metadata, offset will be aligned by 4-byte */
|
/* read variable-sized metadata, offset will be aligned by 4-byte */
|
||||||
static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
|
void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
|
||||||
erofs_off_t *offset, int *lengthp)
|
erofs_off_t *offset, int *lengthp)
|
||||||
{
|
{
|
||||||
u8 *buffer, *ptr;
|
u8 *buffer, *ptr;
|
||||||
int len, i, cnt;
|
int len, i, cnt;
|
||||||
@ -159,64 +159,15 @@ static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
|
|||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int erofs_load_compr_cfgs(struct super_block *sb,
|
|
||||||
struct erofs_super_block *dsb)
|
|
||||||
{
|
|
||||||
struct erofs_sb_info *sbi = EROFS_SB(sb);
|
|
||||||
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
|
|
||||||
unsigned int algs, alg;
|
|
||||||
erofs_off_t offset;
|
|
||||||
int size, ret = 0;
|
|
||||||
|
|
||||||
sbi->available_compr_algs = le16_to_cpu(dsb->u1.available_compr_algs);
|
|
||||||
if (sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS) {
|
|
||||||
erofs_err(sb, "try to load compressed fs with unsupported algorithms %x",
|
|
||||||
sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = EROFS_SUPER_OFFSET + sbi->sb_size;
|
|
||||||
alg = 0;
|
|
||||||
for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) {
|
|
||||||
void *data;
|
|
||||||
|
|
||||||
if (!(algs & 1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
data = erofs_read_metadata(sb, &buf, &offset, &size);
|
|
||||||
if (IS_ERR(data)) {
|
|
||||||
ret = PTR_ERR(data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (alg) {
|
|
||||||
case Z_EROFS_COMPRESSION_LZ4:
|
|
||||||
ret = z_erofs_load_lz4_config(sb, dsb, data, size);
|
|
||||||
break;
|
|
||||||
case Z_EROFS_COMPRESSION_LZMA:
|
|
||||||
ret = z_erofs_load_lzma_config(sb, dsb, data, size);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBG_BUGON(1);
|
|
||||||
ret = -EFAULT;
|
|
||||||
}
|
|
||||||
kfree(data);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
erofs_put_metabuf(&buf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
static int erofs_load_compr_cfgs(struct super_block *sb,
|
static int z_erofs_parse_cfgs(struct super_block *sb,
|
||||||
struct erofs_super_block *dsb)
|
struct erofs_super_block *dsb)
|
||||||
{
|
{
|
||||||
if (dsb->u1.available_compr_algs) {
|
if (!dsb->u1.available_compr_algs)
|
||||||
erofs_err(sb, "try to load compressed fs when compression is disabled");
|
return 0;
|
||||||
return -EINVAL;
|
|
||||||
}
|
erofs_err(sb, "compression disabled, unable to mount compressed EROFS");
|
||||||
return 0;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -398,10 +349,7 @@ static int erofs_read_superblock(struct super_block *sb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* parse on-disk compression configurations */
|
/* parse on-disk compression configurations */
|
||||||
if (erofs_sb_has_compr_cfgs(sbi))
|
ret = z_erofs_parse_cfgs(sb, dsb);
|
||||||
ret = erofs_load_compr_cfgs(sb, dsb);
|
|
||||||
else
|
|
||||||
ret = z_erofs_load_lz4_config(sb, dsb, NULL, 0);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user