[PATCH v2 RESEND] erofs-utils: generate preallocated extents for tarerofs
Jingbo Xu
jefflexu at linux.alibaba.com
Wed Aug 2 00:08:09 AEST 2023
On 8/1/23 9:27 PM, Gao Xiang wrote:
> It is also useful to fill data blocks from tarballs at runtime in
> order to implement image lazy pulling.
>
> Let's generate an additional mapfile for such use cases:
> mkfs.erofs --tar=0,MAPFILE IMAGE TARBALL
>
> Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
Reviewed-by: Jingbo Xu <jefflexu at linux.alibaba.com>
> ---
> sent out a wrong version.
>
> include/erofs/blobchunk.h | 7 +-
> include/erofs/block_list.h | 7 +-
> include/erofs/tar.h | 1 +
> lib/Makefile.am | 3 +-
> lib/blobchunk.c | 162 +++++++++++++++++++++++++++++--------
> lib/block_list.c | 23 ++++--
> lib/tar.c | 88 +-------------------
> mkfs/main.c | 41 ++++++----
> 8 files changed, 185 insertions(+), 147 deletions(-)
>
> diff --git a/include/erofs/blobchunk.h b/include/erofs/blobchunk.h
> index 7c5645e..010aee1 100644
> --- a/include/erofs/blobchunk.h
> +++ b/include/erofs/blobchunk.h
> @@ -14,14 +14,13 @@ extern "C"
>
> #include "erofs/internal.h"
>
> -struct erofs_blobchunk *erofs_get_unhashed_chunk(erofs_off_t chunksize,
> - unsigned int device_id, erofs_blk_t blkaddr);
> int erofs_blob_write_chunk_indexes(struct erofs_inode *inode, erofs_off_t off);
> int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd);
> -int erofs_blob_remap(struct erofs_sb_info *sbi);
> +int tarerofs_write_chunkes(struct erofs_inode *inode, erofs_off_t data_offset);
> +int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi);
> void erofs_blob_exit(void);
> int erofs_blob_init(const char *blobfile_path);
> -int erofs_generate_devtable(struct erofs_sb_info *sbi);
> +int erofs_mkfs_init_devices(struct erofs_sb_info *sbi, unsigned int devices);
>
> #ifdef __cplusplus
> }
> diff --git a/include/erofs/block_list.h b/include/erofs/block_list.h
> index 78fab44..9f9975e 100644
> --- a/include/erofs/block_list.h
> +++ b/include/erofs/block_list.h
> @@ -13,9 +13,12 @@ extern "C"
>
> #include "internal.h"
>
> +int erofs_blocklist_open(char *filename, bool srcmap);
> +void erofs_blocklist_close(void);
> +
> +void tarerofs_blocklist_write(erofs_blk_t blkaddr, erofs_blk_t nblocks,
> + erofs_off_t srcoff);
> #ifdef WITH_ANDROID
> -int erofs_droid_blocklist_fopen(void);
> -void erofs_droid_blocklist_fclose(void);
> void erofs_droid_blocklist_write(struct erofs_inode *inode,
> erofs_blk_t blk_start, erofs_blk_t nblocks);
> void erofs_droid_blocklist_write_tail_end(struct erofs_inode *inode,
> diff --git a/include/erofs/tar.h b/include/erofs/tar.h
> index a14f8ac..8d3f8de 100644
> --- a/include/erofs/tar.h
> +++ b/include/erofs/tar.h
> @@ -15,6 +15,7 @@ struct erofs_pax_header {
>
> struct erofs_tarfile {
> struct erofs_pax_header global;
> + char *mapfile;
>
> int fd;
> u64 offset;
> diff --git a/lib/Makefile.am b/lib/Makefile.am
> index ebe466b..7a5dc03 100644
> --- a/lib/Makefile.am
> +++ b/lib/Makefile.am
> @@ -30,7 +30,8 @@ noinst_HEADERS += compressor.h
> liberofs_la_SOURCES = config.c io.c cache.c super.c inode.c xattr.c exclude.c \
> namei.c data.c compress.c compressor.c zmap.c decompress.c \
> compress_hints.c hashmap.c sha256.c blobchunk.c dir.c \
> - fragments.c rb_tree.c dedupe.c uuid_unparse.c uuid.c tar.c
> + fragments.c rb_tree.c dedupe.c uuid_unparse.c uuid.c tar.c \
> + block_list.c
>
> liberofs_la_CFLAGS = -Wall ${libuuid_CFLAGS} -I$(top_srcdir)/include
> if ENABLE_LZ4
> diff --git a/lib/blobchunk.c b/lib/blobchunk.c
> index 4e4295e..cada5bb 100644
> --- a/lib/blobchunk.c
> +++ b/lib/blobchunk.c
> @@ -20,13 +20,17 @@ struct erofs_blobchunk {
> };
> char sha256[32];
> unsigned int device_id;
> - erofs_off_t chunksize;
> + union {
> + erofs_off_t chunksize;
> + erofs_off_t sourceoffset;
> + };
> erofs_blk_t blkaddr;
> };
>
> static struct hashmap blob_hashmap;
> static FILE *blobfile;
> static erofs_blk_t remapped_base;
> +static erofs_off_t datablob_size;
> static bool multidev;
> static struct erofs_buffer_head *bh_devt;
> struct erofs_blobchunk erofs_holechunk = {
> @@ -34,8 +38,8 @@ struct erofs_blobchunk erofs_holechunk = {
> };
> static LIST_HEAD(unhashed_blobchunks);
>
> -struct erofs_blobchunk *erofs_get_unhashed_chunk(erofs_off_t chunksize,
> - unsigned int device_id, erofs_blk_t blkaddr)
> +static struct erofs_blobchunk *erofs_get_unhashed_chunk(unsigned int device_id,
> + erofs_blk_t blkaddr, erofs_off_t sourceoffset)
> {
> struct erofs_blobchunk *chunk;
>
> @@ -43,9 +47,9 @@ struct erofs_blobchunk *erofs_get_unhashed_chunk(erofs_off_t chunksize,
> if (!chunk)
> return ERR_PTR(-ENOMEM);
>
> - chunk->chunksize = chunksize;
> chunk->device_id = device_id;
> chunk->blkaddr = blkaddr;
> + chunk->sourceoffset = sourceoffset;
> list_add_tail(&chunk->list, &unhashed_blobchunks);
> return chunk;
> }
> @@ -78,7 +82,7 @@ static struct erofs_blobchunk *erofs_blob_getchunk(struct erofs_sb_info *sbi,
> blkpos = ftell(blobfile);
> DBG_BUGON(erofs_blkoff(sbi, blkpos));
>
> - if (multidev)
> + if (sbi->extra_devices)
> chunk->device_id = 1;
> else
> chunk->device_id = 0;
> @@ -125,6 +129,7 @@ int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
> struct erofs_inode_chunk_index idx = {0};
> erofs_blk_t extent_start = EROFS_NULL_ADDR;
> erofs_blk_t extent_end, chunkblks;
> + erofs_off_t source_offset;
> unsigned int dst, src, unit;
> bool first_extent = true;
>
> @@ -153,6 +158,9 @@ int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
> if (extent_start == EROFS_NULL_ADDR ||
> idx.blkaddr != extent_end) {
> if (extent_start != EROFS_NULL_ADDR) {
> + tarerofs_blocklist_write(extent_start,
> + extent_end - extent_start,
> + source_offset);
> erofs_droid_blocklist_write_extent(inode,
> extent_start,
> extent_end - extent_start,
> @@ -160,6 +168,7 @@ int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
> first_extent = false;
> }
> extent_start = idx.blkaddr;
> + source_offset = chunk->sourceoffset;
> }
> extent_end = idx.blkaddr + chunkblks;
> idx.device_id = cpu_to_le16(chunk->device_id);
> @@ -171,6 +180,9 @@ int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
> memcpy(inode->chunkindexes + dst, &idx, sizeof(idx));
> }
> off = roundup(off, unit);
> + if (extent_start != EROFS_NULL_ADDR)
> + tarerofs_blocklist_write(extent_start, extent_end - extent_start,
> + source_offset);
> erofs_droid_blocklist_write_extent(inode, extent_start,
> extent_start == EROFS_NULL_ADDR ?
> 0 : extent_end - extent_start,
> @@ -236,7 +248,7 @@ int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd)
> chunksize = 1ULL << chunkbits;
> count = DIV_ROUND_UP(inode->i_size, chunksize);
>
> - if (multidev)
> + if (sbi->extra_devices)
> inode->u.chunkformat |= EROFS_CHUNK_FORMAT_INDEXES;
> if (inode->u.chunkformat & EROFS_CHUNK_FORMAT_INDEXES)
> unit = sizeof(struct erofs_inode_chunk_index);
> @@ -320,46 +332,123 @@ err:
> return ret;
> }
>
> -int erofs_blob_remap(struct erofs_sb_info *sbi)
> +int tarerofs_write_chunkes(struct erofs_inode *inode, erofs_off_t data_offset)
> +{
> + struct erofs_sb_info *sbi = inode->sbi;
> + unsigned int chunkbits = ilog2(inode->i_size - 1) + 1;
> + unsigned int count, unit, device_id;
> + erofs_off_t chunksize, len, pos;
> + erofs_blk_t blkaddr;
> + struct erofs_inode_chunk_index *idx;
> +
> + if (chunkbits < sbi->blkszbits)
> + chunkbits = sbi->blkszbits;
> + if (chunkbits - sbi->blkszbits > EROFS_CHUNK_FORMAT_BLKBITS_MASK)
> + chunkbits = EROFS_CHUNK_FORMAT_BLKBITS_MASK + sbi->blkszbits;
> +
> + inode->u.chunkformat |= chunkbits - sbi->blkszbits;
> + if (sbi->extra_devices) {
> + device_id = 1;
> + inode->u.chunkformat |= EROFS_CHUNK_FORMAT_INDEXES;
> + unit = sizeof(struct erofs_inode_chunk_index);
> + DBG_BUGON(erofs_blkoff(sbi, data_offset));
> + blkaddr = erofs_blknr(sbi, data_offset);
> + } else {
> + device_id = 0;
> + unit = EROFS_BLOCK_MAP_ENTRY_SIZE;
> + DBG_BUGON(erofs_blkoff(sbi, datablob_size));
> + blkaddr = erofs_blknr(sbi, datablob_size);
> + datablob_size += round_up(inode->i_size, erofs_blksiz(sbi));
> + }
> + chunksize = 1ULL << chunkbits;
> + count = DIV_ROUND_UP(inode->i_size, chunksize);
> +
> + inode->extent_isize = count * unit;
> + idx = calloc(count, max(sizeof(*idx), sizeof(void *)));
> + if (!idx)
> + return -ENOMEM;
> + inode->chunkindexes = idx;
> +
> + for (pos = 0; pos < inode->i_size; pos += len) {
> + struct erofs_blobchunk *chunk;
> +
> + len = min_t(erofs_off_t, inode->i_size - pos, chunksize);
> +
> + chunk = erofs_get_unhashed_chunk(device_id, blkaddr,
> + data_offset);
> + if (IS_ERR(chunk)) {
> + free(inode->chunkindexes);
> + inode->chunkindexes = NULL;
> + return PTR_ERR(chunk);
> + }
> +
> + *(void **)idx++ = chunk;
> + blkaddr += erofs_blknr(sbi, len);
> + data_offset += len;
> + }
> + inode->datalayout = EROFS_INODE_CHUNK_BASED;
> + return 0;
> +}
> +
> +int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi)
> {
> struct erofs_buffer_head *bh;
> ssize_t length;
> erofs_off_t pos_in, pos_out;
> ssize_t ret;
>
> - fflush(blobfile);
> - length = ftell(blobfile);
> - if (length < 0)
> - return -errno;
> - if (multidev) {
> - struct erofs_deviceslot dis = {
> - .blocks = erofs_blknr(sbi, length),
> - };
> + if (blobfile) {
> + fflush(blobfile);
> + length = ftell(blobfile);
> + if (length < 0)
> + return -errno;
>
> - pos_out = erofs_btell(bh_devt, false);
> - ret = dev_write(sbi, &dis, pos_out, sizeof(dis));
> - if (ret)
> - return ret;
> + if (sbi->extra_devices)
> + sbi->devs[0].blocks = erofs_blknr(sbi, length);
> + else
> + datablob_size = length;
> + }
> +
> + if (sbi->extra_devices) {
> + unsigned int i;
>
> + pos_out = erofs_btell(bh_devt, false);
> + i = 0;
> + do {
> + struct erofs_deviceslot dis = {
> + .blocks = cpu_to_le32(sbi->devs[i].blocks),
> + };
> + int ret;
> +
> + ret = dev_write(sbi, &dis, pos_out, sizeof(dis));
> + if (ret)
> + return ret;
> + pos_out += sizeof(dis);
> + } while (++i < sbi->extra_devices);
> bh_devt->op = &erofs_drop_directly_bhops;
> erofs_bdrop(bh_devt, false);
> return 0;
> }
> - if (!length) /* bail out if there is no chunked data */
> - return 0;
> - bh = erofs_balloc(DATA, length, 0, 0);
> +
> + bh = erofs_balloc(DATA, blobfile ? datablob_size : 0, 0, 0);
> if (IS_ERR(bh))
> return PTR_ERR(bh);
>
> erofs_mapbh(bh->block);
> +
> pos_out = erofs_btell(bh, false);
> - pos_in = 0;
> remapped_base = erofs_blknr(sbi, pos_out);
> - ret = erofs_copy_file_range(fileno(blobfile), &pos_in,
> - sbi->devfd, &pos_out, length);
> + if (blobfile) {
> + pos_in = 0;
> + ret = erofs_copy_file_range(fileno(blobfile), &pos_in,
> + sbi->devfd, &pos_out, datablob_size);
> + ret = ret < datablob_size ? -EIO : 0;
> + } else {
> + ret = 0;
> + }
> bh->op = &erofs_drop_directly_bhops;
> erofs_bdrop(bh, false);
> - return ret < length ? -EIO : 0;
> + return ret;
> }
>
> void erofs_blob_exit(void)
> @@ -405,22 +494,25 @@ int erofs_blob_init(const char *blobfile_path)
> return 0;
> }
>
> -int erofs_generate_devtable(struct erofs_sb_info *sbi)
> +int erofs_mkfs_init_devices(struct erofs_sb_info *sbi, unsigned int devices)
> {
> - struct erofs_deviceslot dis;
> -
> - if (!multidev)
> + if (!devices)
> return 0;
>
> - bh_devt = erofs_balloc(DEVT, sizeof(dis), 0, 0);
> - if (IS_ERR(bh_devt))
> - return PTR_ERR(bh_devt);
> + sbi->devs = calloc(devices, sizeof(sbi->devs[0]));
> + if (!sbi->devs)
> + return -ENOMEM;
>
> - dis = (struct erofs_deviceslot) {};
> + bh_devt = erofs_balloc(DEVT,
> + sizeof(struct erofs_deviceslot) * devices, 0, 0);
> + if (IS_ERR(bh_devt)) {
> + free(sbi->devs);
> + return PTR_ERR(bh_devt);
> + }
> erofs_mapbh(bh_devt->block);
> bh_devt->op = &erofs_skip_write_bhops;
> sbi->devt_slotoff = erofs_btell(bh_devt, false) / EROFS_DEVT_SLOT_SIZE;
> - sbi->extra_devices = 1;
> + sbi->extra_devices = devices;
> erofs_sb_set_device_table(sbi);
> return 0;
> }
> diff --git a/lib/block_list.c b/lib/block_list.c
> index 896fb01..b45b553 100644
> --- a/lib/block_list.c
> +++ b/lib/block_list.c
> @@ -3,7 +3,6 @@
> * Copyright (C), 2021, Coolpad Group Limited.
> * Created by Yue Hu <huyue2 at yulong.com>
> */
> -#ifdef WITH_ANDROID
> #include <stdio.h>
> #include <sys/stat.h>
> #include "erofs/block_list.h"
> @@ -12,17 +11,19 @@
> #include "erofs/print.h"
>
> static FILE *block_list_fp;
> +bool srcmap_enabled;
>
> -int erofs_droid_blocklist_fopen(void)
> +int erofs_blocklist_open(char *filename, bool srcmap)
> {
> - block_list_fp = fopen(cfg.block_list_file, "w");
> + block_list_fp = fopen(filename, "w");
>
> if (!block_list_fp)
> - return -1;
> + return -errno;
> + srcmap_enabled = srcmap;
> return 0;
> }
>
> -void erofs_droid_blocklist_fclose(void)
> +void erofs_blocklist_close(void)
> {
> if (!block_list_fp)
> return;
> @@ -31,6 +32,18 @@ void erofs_droid_blocklist_fclose(void)
> block_list_fp = NULL;
> }
>
> +/* XXX: really need to be cleaned up */
> +void tarerofs_blocklist_write(erofs_blk_t blkaddr, erofs_blk_t nblocks,
> + erofs_off_t srcoff)
> +{
> + if (!block_list_fp || !nblocks || !srcmap_enabled)
> + return;
> +
> + fprintf(block_list_fp, "%08x %8x %08" PRIx64 "\n",
> + blkaddr, nblocks, srcoff);
> +}
> +
> +#ifdef WITH_ANDROID
> static void blocklist_write(const char *path, erofs_blk_t blk_start,
> erofs_blk_t nblocks, bool first_extent,
> bool last_extent)
> diff --git a/lib/tar.c b/lib/tar.c
> index 3c145e5..54ee33f 100644
> --- a/lib/tar.c
> +++ b/lib/tar.c
> @@ -341,44 +341,6 @@ out:
> return ret;
> }
>
> -int tarerofs_write_chunk_indexes(struct erofs_inode *inode, erofs_blk_t blkaddr)
> -{
> - struct erofs_sb_info *sbi = inode->sbi;
> - unsigned int chunkbits = ilog2(inode->i_size - 1) + 1;
> - unsigned int count, unit;
> - erofs_off_t chunksize, len, pos;
> - struct erofs_inode_chunk_index *idx;
> -
> - if (chunkbits < sbi->blkszbits)
> - chunkbits = sbi->blkszbits;
> - inode->u.chunkformat |= chunkbits - sbi->blkszbits;
> - inode->u.chunkformat |= EROFS_CHUNK_FORMAT_INDEXES;
> - chunksize = 1ULL << chunkbits;
> - count = DIV_ROUND_UP(inode->i_size, chunksize);
> -
> - unit = sizeof(struct erofs_inode_chunk_index);
> - inode->extent_isize = count * unit;
> - idx = calloc(count, max(sizeof(*idx), sizeof(void *)));
> - if (!idx)
> - return -ENOMEM;
> - inode->chunkindexes = idx;
> -
> - for (pos = 0; pos < inode->i_size; pos += len) {
> - struct erofs_blobchunk *chunk;
> -
> - len = min_t(erofs_off_t, inode->i_size - pos, chunksize);
> -
> - chunk = erofs_get_unhashed_chunk(chunksize, 1, blkaddr);
> - if (IS_ERR(chunk))
> - return PTR_ERR(chunk);
> -
> - *(void **)idx++ = chunk;
> - blkaddr += erofs_blknr(sbi, len);
> - }
> - inode->datalayout = EROFS_INODE_CHUNK_BASED;
> - return 0;
> -}
> -
> void tarerofs_remove_inode(struct erofs_inode *inode)
> {
> struct erofs_dentry *d;
> @@ -608,7 +570,8 @@ restart:
> eh.link = strndup(th.linkname, sizeof(th.linkname));
> }
>
> - if (tar->index_mode && erofs_blkoff(sbi, tar_offset + sizeof(th))) {
> + if (tar->index_mode && !tar->mapfile &&
> + erofs_blkoff(sbi, data_offset)) {
> erofs_err("invalid tar data alignment @ %llu", tar_offset);
> ret = -EIO;
> goto out;
> @@ -710,8 +673,7 @@ new_inode:
> inode->i_link = malloc(inode->i_size + 1);
> memcpy(inode->i_link, eh.link, inode->i_size + 1);
> } else if (tar->index_mode) {
> - ret = tarerofs_write_chunk_indexes(inode,
> - erofs_blknr(sbi, data_offset));
> + ret = tarerofs_write_chunkes(inode, data_offset);
> if (ret)
> goto out;
> if (erofs_lskip(tar->fd, inode->i_size)) {
> @@ -763,47 +725,3 @@ invalid_tar:
> ret = -EIO;
> goto out;
> }
> -
> -static struct erofs_buffer_head *bh_devt;
> -
> -int tarerofs_reserve_devtable(struct erofs_sb_info *sbi, unsigned int devices)
> -{
> - if (!devices)
> - return 0;
> -
> - bh_devt = erofs_balloc(DEVT,
> - sizeof(struct erofs_deviceslot) * devices, 0, 0);
> - if (IS_ERR(bh_devt))
> - return PTR_ERR(bh_devt);
> -
> - erofs_mapbh(bh_devt->block);
> - bh_devt->op = &erofs_skip_write_bhops;
> - sbi->devt_slotoff = erofs_btell(bh_devt, false) / EROFS_DEVT_SLOT_SIZE;
> - sbi->extra_devices = devices;
> - erofs_sb_set_device_table(sbi);
> - return 0;
> -}
> -
> -int tarerofs_write_devtable(struct erofs_sb_info *sbi, struct erofs_tarfile *tar)
> -{
> - erofs_off_t pos_out;
> - unsigned int i;
> -
> - if (!sbi->extra_devices)
> - return 0;
> - pos_out = erofs_btell(bh_devt, false);
> - for (i = 0; i < sbi->extra_devices; ++i) {
> - struct erofs_deviceslot dis = {
> - .blocks = erofs_blknr(sbi, tar->offset),
> - };
> - int ret;
> -
> - ret = dev_write(sbi, &dis, pos_out, sizeof(dis));
> - if (ret)
> - return ret;
> - pos_out += sizeof(dis);
> - }
> - bh_devt->op = &erofs_drop_directly_bhops;
> - erofs_bdrop(bh_devt, false);
> - return 0;
> -}
> diff --git a/mkfs/main.c b/mkfs/main.c
> index bc5ed87..3809c71 100644
> --- a/mkfs/main.c
> +++ b/mkfs/main.c
> @@ -484,8 +484,11 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
> break;
> case 20:
> if (optarg && (!strcmp(optarg, "i") ||
> - !strcmp(optarg, "0")))
> + !strcmp(optarg, "0") || !memcmp(optarg, "0,", 2))) {
> erofstar.index_mode = true;
> + if (!memcmp(optarg, "0,", 2))
> + erofstar.mapfile = strdup(optarg + 2);
> + }
> tar_mode = true;
> break;
> case 21:
> @@ -795,7 +798,8 @@ int main(int argc, char **argv)
> return 1;
> }
>
> - if (cfg.block_list_file && erofs_droid_blocklist_fopen() < 0) {
> + if (cfg.block_list_file &&
> + erofs_blocklist_open(cfg.block_list_file, false)) {
> erofs_err("failed to open %s", cfg.block_list_file);
> return 1;
> }
> @@ -827,8 +831,18 @@ int main(int argc, char **argv)
> if (cfg.c_random_pclusterblks)
> srand(time(NULL));
> #endif
> - if (tar_mode && erofstar.index_mode)
> - sbi.blkszbits = 9;
> + if (tar_mode && erofstar.index_mode) {
> + if (erofstar.mapfile) {
> + err = erofs_blocklist_open(erofstar.mapfile, true);
> + if (err) {
> + erofs_err("failed to open %s", erofstar.mapfile);
> + goto exit;
> + }
> + } else {
> + sbi.blkszbits = 9;
> + }
> + }
> +
> sb_bh = erofs_buffer_init();
> if (IS_ERR(sb_bh)) {
> err = PTR_ERR(sb_bh);
> @@ -884,10 +898,8 @@ int main(int argc, char **argv)
> return 1;
> }
>
> - if (tar_mode && erofstar.index_mode)
> - err = tarerofs_reserve_devtable(&sbi, 1);
> - else
> - err = erofs_generate_devtable(&sbi);
> + if ((erofstar.index_mode && !erofstar.mapfile) || cfg.c_blobdev_path)
> + err = erofs_mkfs_init_devices(&sbi, 1);
> if (err) {
> erofs_err("failed to generate device table: %s",
> erofs_strerror(err));
> @@ -942,11 +954,12 @@ int main(int argc, char **argv)
> root_nid = erofs_lookupnid(root_inode);
> erofs_iput(root_inode);
>
> - if (tar_mode)
> - tarerofs_write_devtable(&sbi, &erofstar);
> - if (cfg.c_chunkbits) {
> + if (erofstar.index_mode || cfg.c_chunkbits) {
> erofs_info("total metadata: %u blocks", erofs_mapbh(NULL));
> - err = erofs_blob_remap(&sbi);
> + if (erofstar.index_mode && !erofstar.mapfile)
> + sbi.devs[0].blocks =
> + BLK_ROUND_UP(&sbi, erofstar.offset);
> + err = erofs_mkfs_dump_blobs(&sbi);
> if (err)
> goto exit;
> }
> @@ -980,9 +993,7 @@ int main(int argc, char **argv)
> exit:
> z_erofs_compress_exit();
> z_erofs_dedupe_exit();
> -#ifdef WITH_ANDROID
> - erofs_droid_blocklist_fclose();
> -#endif
> + erofs_blocklist_close();
> dev_close(&sbi);
> erofs_cleanup_compress_hints();
> erofs_cleanup_exclude_rules();
--
Thanks,
Jingbo
More information about the Linux-erofs
mailing list