Contact: "Huang Jianan" <huangjianan@oppo.com>
Description: Shows all enabled kernel features.
Supported features:
- zero_padding, compr_cfgs, big_pcluster, chunked_file,
- device_table, compr_head2, sb_chksum, ztailpacking,
- dedupe, fragments, 48bit, metabox.
+ compr_cfgs, big_pcluster, chunked_file, device_table,
+ compr_head2, sb_chksum, ztailpacking, dedupe, fragments,
+ 48bit, metabox.
What: /sys/fs/erofs/<disk>/sync_decompress
Date: November 2021
}
} else {
distance = le16_to_cpu(dsb->u1.lz4_max_distance);
+ if (!distance && !erofs_sb_has_lz4_0padding(sbi))
+ return 0;
sbi->lz4.max_pclusterblks = 1;
+ sbi->available_compr_algs = 1 << Z_EROFS_COMPRESSION_LZ4;
}
sbi->lz4.max_distance_pages = distance ?
static const char *__z_erofs_lz4_decompress(struct z_erofs_decompress_req *rq,
u8 *dst)
{
- bool zeropadded = erofs_sb_has_zero_padding(EROFS_SB(rq->sb));
bool may_inplace = false;
unsigned int inputmargin;
u8 *out, *headpage, *src;
int ret, maptype;
headpage = kmap_local_page(*rq->in);
- /* LZ4 decompression inplace is only safe if zero_padding is enabled */
- if (zeropadded) {
- reason = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in,
- min_t(unsigned int, rq->inputsize,
- rq->sb->s_blocksize - rq->pageofs_in));
- if (reason) {
- kunmap_local(headpage);
- return reason;
- }
- may_inplace = !((rq->pageofs_in + rq->inputsize) &
- (rq->sb->s_blocksize - 1));
+ reason = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in,
+ min_t(unsigned int, rq->inputsize,
+ rq->sb->s_blocksize - rq->pageofs_in));
+ if (reason) {
+ kunmap_local(headpage);
+ return reason;
}
+ may_inplace = !((rq->pageofs_in + rq->inputsize) &
+ (rq->sb->s_blocksize - 1));
inputmargin = rq->pageofs_in;
src = z_erofs_lz4_handle_overlap(rq, headpage, dst, &inputmargin,
return ERR_CAST(src);
out = dst + rq->pageofs_out;
- /* legacy format could compress extra data in a pcluster. */
- if (rq->partial_decoding || !zeropadded)
+ if (rq->partial_decoding)
ret = LZ4_decompress_safe_partial(src + inputmargin, out,
rq->inputsize, rq->outputsize, rq->outputsize);
else
erofs_off_t offset;
int size, ret = 0;
- if (!erofs_sb_has_compr_cfgs(sbi)) {
- sbi->available_compr_algs = 1 << Z_EROFS_COMPRESSION_LZ4;
+ if (!erofs_sb_has_compr_cfgs(sbi))
return z_erofs_load_lz4_config(sb, dsb, NULL, 0);
- }
algs = le16_to_cpu(dsb->u1.available_compr_algs);
sbi->available_compr_algs = algs;
* Any bits that aren't in EROFS_ALL_FEATURE_INCOMPAT should
* be incompatible with this kernel version.
*/
-#define EROFS_FEATURE_INCOMPAT_ZERO_PADDING 0x00000001
+#define EROFS_FEATURE_INCOMPAT_LZ4_0PADDING 0x00000001
#define EROFS_FEATURE_INCOMPAT_COMPR_CFGS 0x00000002
#define EROFS_FEATURE_INCOMPAT_BIG_PCLUSTER 0x00000002
#define EROFS_FEATURE_INCOMPAT_CHUNKED_FILE 0x00000004
goto err_out;
}
- if (erofs_inode_is_data_compressed(vi->datalayout))
- inode->i_blocks = le32_to_cpu(copied.i_u.blocks_lo) <<
- (sb->s_blocksize_bits - 9);
- else
+ if (!erofs_inode_is_data_compressed(vi->datalayout)) {
inode->i_blocks = round_up(inode->i_size, sb->s_blocksize) >> 9;
+ } else if (!IS_ENABLED(CONFIG_EROFS_FS_ZIP) || !sbi->available_compr_algs) {
+ erofs_err(sb, "compressed inode (nid %llu) is invalid in a plain filesystem",
+ vi->nid);
+ err = -EFSCORRUPTED;
+ goto err_out;
+ } else {
+ inode->i_blocks = le32_to_cpu(copied.i_u.blocks_lo) <<
+ (sb->s_blocksize_bits - 9);
+ }
if (vi->datalayout == EROFS_INODE_CHUNK_BASED) {
/* fill chunked inode summary info */
unsigned int sync_decompress; /* strategy for sync decompression */
unsigned int shrinker_run_no;
- u16 available_compr_algs;
/* pseudo inode to manage cached pages */
struct inode *managed_cache;
char *volume_name;
u32 feature_compat;
u32 feature_incompat;
+ u16 available_compr_algs;
/* sysfs support */
struct kobject s_kobj; /* /sys/fs/erofs/<devname> */
return sbi->feature_##compat & EROFS_FEATURE_##feature; \
}
-EROFS_FEATURE_FUNCS(zero_padding, incompat, INCOMPAT_ZERO_PADDING)
+EROFS_FEATURE_FUNCS(lz4_0padding, incompat, INCOMPAT_LZ4_0PADDING)
EROFS_FEATURE_FUNCS(compr_cfgs, incompat, INCOMPAT_COMPR_CFGS)
EROFS_FEATURE_FUNCS(big_pcluster, incompat, INCOMPAT_BIG_PCLUSTER)
EROFS_FEATURE_FUNCS(chunked_file, incompat, INCOMPAT_CHUNKED_FILE)
int z_erofs_gbuf_growsize(unsigned int nrpages);
int __init z_erofs_gbuf_init(void);
void z_erofs_gbuf_exit(void);
-int z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb);
#else
static inline void erofs_shrinker_register(struct super_block *sb) {}
static inline void erofs_shrinker_unregister(struct super_block *sb) {}
static inline void z_erofs_exit_subsystem(void) {}
static inline int z_erofs_init_super(struct super_block *sb) { return 0; }
#endif /* !CONFIG_EROFS_FS_ZIP */
+int z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb);
#ifdef CONFIG_EROFS_FS_BACKED_BY_FILE
struct bio *erofs_fileio_bio_alloc(struct erofs_map_dev *mdev);
return buffer;
}
-#ifndef CONFIG_EROFS_FS_ZIP
-static int z_erofs_parse_cfgs(struct super_block *sb,
- struct erofs_super_block *dsb)
-{
- if (!dsb->u1.available_compr_algs)
- return 0;
-
- erofs_err(sb, "compression disabled, unable to mount compressed EROFS");
- return -EOPNOTSUPP;
-}
-#endif
-
static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
struct erofs_device_info *dif, erofs_off_t *pos)
{
}
}
- /* parse on-disk compression configurations */
- ret = z_erofs_parse_cfgs(sb, dsb);
- if (ret < 0)
+ if (IS_ENABLED(CONFIG_EROFS_FS_ZIP)) {
+ ret = z_erofs_parse_cfgs(sb, dsb);
+ if (ret < 0)
+ goto out;
+ } else if (dsb->u1.available_compr_algs ||
+ erofs_sb_has_lz4_0padding(sbi)) {
+ erofs_err(sb, "compression disabled, unable to mount compressed EROFS");
+ ret = -EOPNOTSUPP;
goto out;
+ }
ret = erofs_scan_devices(sb, dsb);
ATTRIBUTE_GROUPS(erofs);
/* Features this copy of erofs supports */
-EROFS_ATTR_FEATURE(zero_padding);
EROFS_ATTR_FEATURE(compr_cfgs);
EROFS_ATTR_FEATURE(big_pcluster);
EROFS_ATTR_FEATURE(chunked_file);
EROFS_ATTR_FEATURE(metabox);
static struct attribute *erofs_feat_attrs[] = {
- ATTR_LIST(zero_padding),
ATTR_LIST(compr_cfgs),
ATTR_LIST(big_pcluster),
ATTR_LIST(chunked_file),