In order to adjust pclustersize on the per-(sub)file basis, generating per-file map headers are needed instead.
In addition to that, we could use COMPACT_4B on the per-file basis as well after this patch. Signed-off-by: Gao Xiang <[email protected]> --- lib/compress.c | 80 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/lib/compress.c b/lib/compress.c index e146416890f0..89f87dc4096c 100644 --- a/lib/compress.c +++ b/lib/compress.c @@ -22,7 +22,7 @@ static struct erofs_compress compresshandle; static int compressionlevel; -static struct z_erofs_map_header mapheader; +static unsigned int algorithmtype[2]; struct z_erofs_vle_compress_ctx { u8 *metacur; @@ -149,12 +149,17 @@ static int write_uncompressed_extent(struct z_erofs_vle_compress_ctx *ctx, return count; } +/* TODO: apply per-(sub)file strategies here */ +static unsigned int z_erofs_get_max_pclustersize(struct erofs_inode *inode) +{ + return cfg.c_physical_clusterblks * EROFS_BLKSIZ; +} + static int vle_compress_one(struct erofs_inode *inode, struct z_erofs_vle_compress_ctx *ctx, bool final) { - const unsigned int pclusterblks = cfg.c_physical_clusterblks; - const unsigned int pclustersize = pclusterblks * EROFS_BLKSIZ; + const unsigned int pclustersize = z_erofs_get_max_pclustersize(inode); struct erofs_compress *const h = &compresshandle; unsigned int len = ctx->tail - ctx->head; unsigned int count; @@ -342,13 +347,14 @@ static void *write_compacted_indexes(u8 *out, int z_erofs_convert_to_compacted_format(struct erofs_inode *inode, erofs_blk_t blkaddr, unsigned int legacymetasize, - unsigned int logical_clusterbits) + void *compressmeta) { const unsigned int mpos = Z_EROFS_VLE_EXTENT_ALIGN(inode->inode_isize + inode->xattr_isize) + sizeof(struct z_erofs_map_header); const unsigned int totalidx = (legacymetasize - Z_EROFS_LEGACY_MAP_HEADER_SIZE) / 8; + const unsigned int logical_clusterbits = inode->z_logical_clusterbits; u8 *out, *in; struct z_erofs_compressindex_vec cv[16]; /* # of 8-byte units so that it can be aligned with 32 bytes */ @@ -379,9 +385,9 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode, compacted_4b_end = totalidx; } - out = in = inode->compressmeta; + out = in = compressmeta; - out += sizeof(mapheader); + out += sizeof(struct z_erofs_map_header); in += Z_EROFS_LEGACY_MAP_HEADER_SIZE; dummy_head = false; @@ -428,11 +434,26 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode, 4, logical_clusterbits, true, &dummy_head); } - inode->extent_isize = out - (u8 *)inode->compressmeta; - inode->datalayout = EROFS_INODE_FLAT_COMPRESSION; + inode->extent_isize = out - (u8 *)compressmeta; return 0; } +static void z_erofs_write_mapheader(struct erofs_inode *inode, + void *compressmeta) +{ + struct z_erofs_map_header h = { + .h_advise = cpu_to_le16(inode->z_advise), + .h_algorithmtype = inode->z_algorithmtype[1] << 4 | + inode->z_algorithmtype[0], + /* lclustersize */ + .h_clusterbits = inode->z_logical_clusterbits - 12, + }; + + memset(compressmeta, 0, Z_EROFS_LEGACY_MAP_HEADER_SIZE); + /* write out map header */ + memcpy(compressmeta, &h, sizeof(struct z_erofs_map_header)); +} + int erofs_write_compressed_file(struct erofs_inode *inode) { struct erofs_buffer_head *bh; @@ -459,9 +480,25 @@ int erofs_write_compressed_file(struct erofs_inode *inode) goto err_close; } - memset(compressmeta, 0, Z_EROFS_LEGACY_MAP_HEADER_SIZE); - /* write out compressed header */ - memcpy(compressmeta, &mapheader, sizeof(mapheader)); + /* initialize per-file compression setting */ + inode->z_advise = 0; + if (!cfg.c_legacy_compress) { + inode->z_advise |= Z_EROFS_ADVISE_COMPACTED_2B; + inode->datalayout = EROFS_INODE_FLAT_COMPRESSION; + } else { + inode->datalayout = EROFS_INODE_FLAT_COMPRESSION_LEGACY; + } + + if (cfg.c_physical_clusterblks > 1) { + inode->z_advise |= Z_EROFS_ADVISE_BIG_PCLUSTER_1; + if (inode->datalayout == EROFS_INODE_FLAT_COMPRESSION) + inode->z_advise |= Z_EROFS_ADVISE_BIG_PCLUSTER_2; + } + inode->z_algorithmtype[0] = algorithmtype[0]; + inode->z_algorithmtype[1] = algorithmtype[1]; + inode->z_logical_clusterbits = LOG_BLOCK_SIZE; + + z_erofs_write_mapheader(inode, compressmeta); blkaddr = erofs_mapbh(bh->block); /* start_blkaddr */ ctx.blkaddr = blkaddr; @@ -516,19 +553,19 @@ int erofs_write_compressed_file(struct erofs_inode *inode) * when both mkfs & kernel support compression inline. */ erofs_bdrop(bh, false); - inode->compressmeta = compressmeta; inode->idata_size = 0; inode->u.i_blocks = compressed_blocks; legacymetasize = ctx.metacur - compressmeta; - if (cfg.c_legacy_compress) { + if (inode->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { inode->extent_isize = legacymetasize; - inode->datalayout = EROFS_INODE_FLAT_COMPRESSION_LEGACY; } else { ret = z_erofs_convert_to_compacted_format(inode, blkaddr, - legacymetasize, 12); + legacymetasize, + compressmeta); DBG_BUGON(ret); } + inode->compressmeta = compressmeta; return 0; err_bdrop: @@ -580,7 +617,6 @@ int z_erofs_build_compr_cfgs(struct erofs_buffer_head *sb_bh) int z_erofs_compress_init(struct erofs_buffer_head *sb_bh) { - unsigned int algorithmtype[2]; /* initialize for primary compression algorithm */ int ret = erofs_compressor_init(&compresshandle, cfg.c_compr_alg_master); @@ -603,16 +639,13 @@ int z_erofs_compress_init(struct erofs_buffer_head *sb_bh) compresshandle.alg->default_level : cfg.c_compr_level_master; - /* figure out mapheader */ + /* figure out primary algorithm */ ret = erofs_get_compress_algorithm_id(cfg.c_compr_alg_master); if (ret < 0) return ret; algorithmtype[0] = ret; /* primary algorithm (head 0) */ algorithmtype[1] = 0; /* secondary algorithm (head 1) */ - mapheader.h_advise = 0; - if (!cfg.c_legacy_compress) - mapheader.h_advise |= Z_EROFS_ADVISE_COMPACTED_2B; /* * if big pcluster is enabled, an extra CBLKCNT lcluster index needs * to be loaded in order to get those compressed block counts. @@ -625,15 +658,8 @@ int z_erofs_compress_init(struct erofs_buffer_head *sb_bh) return -EINVAL; } erofs_sb_set_big_pcluster(); - mapheader.h_advise |= Z_EROFS_ADVISE_BIG_PCLUSTER_1; - if (!cfg.c_legacy_compress) - mapheader.h_advise |= Z_EROFS_ADVISE_BIG_PCLUSTER_2; - erofs_warn("EXPERIMENTAL big pcluster feature in use. Use at your own risk!"); } - mapheader.h_algorithmtype = algorithmtype[1] << 4 | - algorithmtype[0]; - mapheader.h_clusterbits = LOG_BLOCK_SIZE - 12; if (erofs_sb_has_compr_cfgs()) { sbi.available_compr_algs |= 1 << ret; -- 2.20.1
