- erofs_mkfs_format_fs  Create a new filesystem

 - erofs_mkfs_load_fs    Load an existing filesystem, especially for
                         incremental builds;

Unlike importer APIs (designed for multiple data sources), this can
only be executed once.

Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com>
---
 include/erofs/compress.h |  3 +-
 include/erofs/internal.h |  6 ++-
 lib/cache.c              |  1 +
 lib/compress.c           |  5 +-
 lib/importer.c           |  4 ++
 lib/super.c              | 55 +++++++++++++++++++++-
 mkfs/main.c              | 99 ++++++++++++----------------------------
 7 files changed, 98 insertions(+), 75 deletions(-)

diff --git a/include/erofs/compress.h b/include/erofs/compress.h
index d5b2519..00e7715 100644
--- a/include/erofs/compress.h
+++ b/include/erofs/compress.h
@@ -23,8 +23,7 @@ void z_erofs_drop_inline_pcluster(struct erofs_inode *inode);
 void *erofs_begin_compressed_file(struct erofs_inode *inode, int fd, u64 fpos);
 int erofs_write_compressed_file(struct z_erofs_compress_ictx *ictx);
 
-int z_erofs_compress_init(struct erofs_sb_info *sbi,
-                         struct erofs_buffer_head *bh);
+int z_erofs_compress_init(struct erofs_sb_info *sbi);
 int z_erofs_compress_exit(struct erofs_sb_info *sbi);
 
 const char *z_erofs_list_supported_algorithms(int i, unsigned int *mask);
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 92e83fd..a609fbd 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -150,6 +150,7 @@ struct erofs_sb_info {
        struct z_erofs_mgr *zmgr;
        struct erofs_metaboxmgr *m2gr;
        struct erofs_packed_inode *packedinode;
+       struct erofs_buffer_head *bh_sb;
        struct erofs_buffer_head *bh_devt;
        bool useqpl;
 };
@@ -432,12 +433,15 @@ void liberofs_global_exit(void);
 /* super.c */
 int erofs_read_superblock(struct erofs_sb_info *sbi);
 void erofs_put_super(struct erofs_sb_info *sbi);
-int erofs_writesb(struct erofs_sb_info *sbi, struct erofs_buffer_head *sb_bh);
+int erofs_writesb(struct erofs_sb_info *sbi);
 struct erofs_buffer_head *erofs_reserve_sb(struct erofs_bufmgr *bmgr);
 int erofs_mkfs_init_devices(struct erofs_sb_info *sbi, unsigned int devices);
 int erofs_write_device_table(struct erofs_sb_info *sbi);
 int erofs_enable_sb_chksum(struct erofs_sb_info *sbi, u32 *crc);
 int erofs_superblock_csum_verify(struct erofs_sb_info *sbi);
+int erofs_mkfs_format_fs(struct erofs_sb_info *sbi,
+                        unsigned int blkszbits, unsigned int dsunit);
+int erofs_mkfs_load_fs(struct erofs_sb_info *sbi, unsigned int dsunit);
 
 /* namei.c */
 int erofs_read_inode_from_disk(struct erofs_inode *vi);
diff --git a/lib/cache.c b/lib/cache.c
index 079465e..cd11737 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -533,5 +533,6 @@ erofs_blk_t erofs_total_metablocks(struct erofs_bufmgr 
*bmgr)
 
 void erofs_buffer_exit(struct erofs_bufmgr *bmgr)
 {
+       DBG_BUGON(!list_empty(&bmgr->blkh.list));
        free(bmgr);
 }
diff --git a/lib/compress.c b/lib/compress.c
index 0bfad3f..0049199 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -2035,11 +2035,12 @@ static int z_erofs_build_compr_cfgs(struct 
erofs_sb_info *sbi,
        return ret;
 }
 
-int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head 
*sb_bh)
+int z_erofs_compress_init(struct erofs_sb_info *sbi)
 {
-       int i, ret, id;
+       struct erofs_buffer_head *sb_bh = sbi->bh_sb;
        u32 max_dict_size[Z_EROFS_COMPRESSION_MAX] = {};
        u32 available_compr_algs = 0;
+       int i, ret, id;
 
        if (!sbi->zmgr) {
                sbi->zmgr = calloc(1, sizeof(*sbi->zmgr));
diff --git a/lib/importer.c b/lib/importer.c
index a65fa39..95f006d 100644
--- a/lib/importer.c
+++ b/lib/importer.c
@@ -39,6 +39,7 @@ void erofs_importer_global_init(void)
 int erofs_importer_init(struct erofs_importer *im)
 {
        struct erofs_sb_info *sbi = im->sbi;
+       struct erofs_importer_params *params = im->params;
        const char *subsys = NULL;
        int err;
 
@@ -67,6 +68,9 @@ int erofs_importer_init(struct erofs_importer *im)
                if (err)
                        goto out_err;
        }
+
+       if (params->dot_omitted)
+               erofs_sb_set_48bit(sbi);
        return 0;
 
 out_err:
diff --git a/lib/super.c b/lib/super.c
index 57849fb..97d955f 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -172,8 +172,9 @@ void erofs_put_super(struct erofs_sb_info *sbi)
        }
 }
 
-int erofs_writesb(struct erofs_sb_info *sbi, struct erofs_buffer_head *sb_bh)
+int erofs_writesb(struct erofs_sb_info *sbi)
 {
+       struct erofs_buffer_head *sb_bh = sbi->bh_sb;
        struct erofs_super_block sb = {
                .magic     = cpu_to_le32(EROFS_SUPER_MAGIC_V1),
                .blkszbits = sbi->blkszbits,
@@ -408,3 +409,55 @@ out:
        sbi->total_blocks = nblocks;
        return 0;
 }
+
+int erofs_mkfs_format_fs(struct erofs_sb_info *sbi,
+                        unsigned int blkszbits, unsigned int dsunit)
+{
+       struct erofs_buffer_head *bh;
+       struct erofs_bufmgr *bmgr;
+
+       sbi->blkszbits = blkszbits;
+       bmgr = erofs_buffer_init(sbi, 0, NULL);
+       if (!bmgr)
+               return -ENOMEM;
+       sbi->bmgr = bmgr;
+       bmgr->dsunit = dsunit;
+
+       bh = erofs_reserve_sb(bmgr);
+       if (IS_ERR(bh))
+               return PTR_ERR(bh);
+       sbi->bh_sb = bh;
+       return 0;
+}
+
+int erofs_mkfs_load_fs(struct erofs_sb_info *sbi, unsigned int dsunit)
+{
+       union {
+               struct stat st;
+               erofs_blk_t startblk;
+       } u;
+       struct erofs_bufmgr *bmgr;
+       int err;
+
+       sbi->bh_sb = NULL;
+       erofs_warn("EXPERIMENTAL incremental build in use. Use at your own 
risk!");
+       err = erofs_read_superblock(sbi);
+       if (err) {
+               erofs_err("failed to read superblock of %s: %s", sbi->devname,
+                         erofs_strerror(err));
+               return err;
+       }
+
+       err = erofs_io_fstat(&sbi->bdev, &u.st);
+       if (!err && S_ISREG(u.st.st_mode))
+               u.startblk = DIV_ROUND_UP(u.st.st_size, erofs_blksiz(sbi));
+       else
+               u.startblk = sbi->primarydevice_blocks;
+
+       bmgr = erofs_buffer_init(sbi, u.startblk, NULL);
+       if (!bmgr)
+               return -ENOMEM;
+       sbi->bmgr = bmgr;
+       bmgr->dsunit = dsunit;
+       return 0;
+}
diff --git a/mkfs/main.c b/mkfs/main.c
index 0a8f477..d2950b7 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -372,6 +372,7 @@ static int erofs_mkfs_feat_set_48bit(bool en, const char 
*val,
 }
 
 static bool mkfs_dot_omitted;
+static unsigned char mkfs_blkszbits;
 
 static int erofs_mkfs_feat_set_dot_omitted(bool en, const char *val,
                                           unsigned int vallen)
@@ -884,7 +885,7 @@ static int mkfs_parse_options_cfg(struct 
erofs_importer_params *params,
                                erofs_err("invalid block size %s", optarg);
                                return -EINVAL;
                        }
-                       g_sbi.blkszbits = ilog2(i);
+                       mkfs_blkszbits = ilog2(i);
                        break;
 
                case 'd':
@@ -1234,7 +1235,7 @@ static int mkfs_parse_options_cfg(struct 
erofs_importer_params *params,
                }
        }
 
-       if (cfg.c_blobdev_path && cfg.c_chunkbits < g_sbi.blkszbits) {
+       if (cfg.c_blobdev_path && cfg.c_chunkbits < mkfs_blkszbits) {
                erofs_err("--blobdev must be used together with --chunksize");
                return -EINVAL;
        }
@@ -1283,8 +1284,8 @@ static int mkfs_parse_options_cfg(struct 
erofs_importer_params *params,
        }
 
        if (pclustersize_max) {
-               if (pclustersize_max < erofs_blksiz(&g_sbi) ||
-                   pclustersize_max % erofs_blksiz(&g_sbi)) {
+               if (pclustersize_max < (1U << mkfs_blkszbits) ||
+                   pclustersize_max % (1U << mkfs_blkszbits)) {
                        erofs_err("invalid physical clustersize %u",
                                  pclustersize_max);
                        return -EINVAL;
@@ -1292,15 +1293,15 @@ static int mkfs_parse_options_cfg(struct 
erofs_importer_params *params,
                cfg.c_mkfs_pclustersize_max = pclustersize_max;
                cfg.c_mkfs_pclustersize_def = cfg.c_mkfs_pclustersize_max;
        }
-       if (cfg.c_chunkbits && cfg.c_chunkbits < g_sbi.blkszbits) {
+       if (cfg.c_chunkbits && cfg.c_chunkbits < mkfs_blkszbits) {
                erofs_err("chunksize %u must be larger than block size",
                          1u << cfg.c_chunkbits);
                return -EINVAL;
        }
 
        if (pclustersize_packed) {
-               if (pclustersize_packed < erofs_blksiz(&g_sbi) ||
-                   pclustersize_packed % erofs_blksiz(&g_sbi)) {
+               if (pclustersize_packed < (1U << mkfs_blkszbits) ||
+                   pclustersize_packed % (1U << mkfs_blkszbits)) {
                        erofs_err("invalid pcluster size for the packed file 
%u",
                                  pclustersize_packed);
                        return -EINVAL;
@@ -1310,8 +1311,8 @@ static int mkfs_parse_options_cfg(struct 
erofs_importer_params *params,
 
        if (pclustersize_metabox >= 0) {
                if (pclustersize_metabox &&
-                   (pclustersize_metabox < erofs_blksiz(&g_sbi) ||
-                    pclustersize_metabox % erofs_blksiz(&g_sbi))) {
+                   (pclustersize_metabox < (1U << mkfs_blkszbits) ||
+                    pclustersize_metabox % (1U << mkfs_blkszbits))) {
                        erofs_err("invalid pcluster size %u for the metabox 
inode",
                                  pclustersize_metabox);
                        return -EINVAL;
@@ -1334,8 +1335,8 @@ static void erofs_mkfs_default_options(void)
        cfg.c_mt_workers = erofs_get_available_processors();
        cfg.c_mkfs_segment_size = 16ULL * 1024 * 1024;
 #endif
-       g_sbi.blkszbits = ilog2(min_t(u32, getpagesize(), 
EROFS_MAX_BLOCK_SIZE));
-       cfg.c_mkfs_pclustersize_max = erofs_blksiz(&g_sbi);
+       mkfs_blkszbits = ilog2(min_t(u32, getpagesize(), EROFS_MAX_BLOCK_SIZE));
+       cfg.c_mkfs_pclustersize_max = 1U << mkfs_blkszbits;
        cfg.c_mkfs_pclustersize_def = cfg.c_mkfs_pclustersize_max;
        g_sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_ZERO_PADDING;
        g_sbi.feature_compat = EROFS_FEATURE_COMPAT_SB_CHKSUM |
@@ -1468,7 +1469,7 @@ static void erofs_mkfs_showsummaries(void)
                "Filesystem total inodes: %llu\n"
                "Filesystem %s metadata blocks: %llu\n"
                "Filesystem %s deduplicated bytes (of source files): %llu\n",
-               uuid_str, g_sbi.total_blocks | 0ULL, 1U << g_sbi.blkszbits,
+               uuid_str, g_sbi.total_blocks | 0ULL, 1U << mkfs_blkszbits,
                g_sbi.inos | 0ULL,
                incr, erofs_total_metablocks(g_sbi.bmgr) | 0ULL,
                incr, g_sbi.saved_by_deduplication | 0ULL);
@@ -1481,7 +1482,6 @@ int main(int argc, char **argv)
                .params = &importer_params,
                .sbi = &g_sbi,
        };
-       struct erofs_buffer_head *sb_bh;
        struct erofs_inode *root = NULL;
        bool tar_index_512b = false;
        struct timeval t;
@@ -1539,16 +1539,6 @@ int main(int argc, char **argv)
 #endif
        erofs_show_config();
 
-       importer_params.source = cfg.c_src_path;
-       importer_params.no_datainline = mkfs_no_datainline;
-       importer_params.dot_omitted = mkfs_dot_omitted;
-       if (importer_params.dot_omitted)
-               erofs_sb_set_48bit(&g_sbi);
-
-       err = erofs_importer_init(&importer);
-       if (err)
-               goto exit;
-
 #ifndef NDEBUG
        if (cfg.c_random_pclusterblks)
                srand(time(NULL));
@@ -1570,7 +1560,7 @@ int main(int argc, char **argv)
                         * If mapfile is unspecified for tarfs index mode,
                         * 512-byte block size is enforced here.
                         */
-                       g_sbi.blkszbits = 9;
+                       mkfs_blkszbits = 9;
                        tar_index_512b = true;
                }
        } else if (source_mode == EROFS_MKFS_SOURCE_REBUILD) {
@@ -1586,46 +1576,15 @@ int main(int argc, char **argv)
                        erofs_err("failed to read superblock of %s", 
src->devname);
                        goto exit;
                }
-               g_sbi.blkszbits = src->blkszbits;
+               mkfs_blkszbits = src->blkszbits;
        }
 
-       if (!incremental_mode) {
-               g_sbi.bmgr = erofs_buffer_init(&g_sbi, 0, NULL);
-               if (!g_sbi.bmgr) {
-                       err = -ENOMEM;
-                       goto exit;
-               }
-               sb_bh = erofs_reserve_sb(g_sbi.bmgr);
-               if (IS_ERR(sb_bh)) {
-                       err = PTR_ERR(sb_bh);
-                       goto exit;
-               }
-       } else {
-               union {
-                       struct stat st;
-                       erofs_blk_t startblk;
-               } u;
-
-               erofs_warn("EXPERIMENTAL incremental build in use. Use at your 
own risk!");
-               err = erofs_read_superblock(&g_sbi);
-               if (err) {
-                       erofs_err("failed to read superblock of %s", 
g_sbi.devname);
-                       goto exit;
-               }
-
-               err = erofs_io_fstat(&g_sbi.bdev, &u.st);
-               if (!err && S_ISREG(u.st.st_mode))
-                       u.startblk = DIV_ROUND_UP(u.st.st_size, 
erofs_blksiz(&g_sbi));
-               else
-                       u.startblk = g_sbi.primarydevice_blocks;
-               g_sbi.bmgr = erofs_buffer_init(&g_sbi, u.startblk, NULL);
-               if (!g_sbi.bmgr) {
-                       err = -ENOMEM;
-                       goto exit;
-               }
-               sb_bh = NULL;
-       }
-       g_sbi.bmgr->dsunit = dsunit;
+       if (!incremental_mode)
+               err = erofs_mkfs_format_fs(&g_sbi, mkfs_blkszbits, dsunit);
+       else
+               err = erofs_mkfs_load_fs(&g_sbi, dsunit);
+       if (err)
+               goto exit;
 
        /* Use the user-defined UUID or generate one for clean builds */
        if (valid_fixeduuid)
@@ -1650,13 +1609,20 @@ int main(int argc, char **argv)
                goto exit;
        }
 
-       err = z_erofs_compress_init(&g_sbi, sb_bh);
+       err = z_erofs_compress_init(&g_sbi);
        if (err) {
                erofs_err("failed to initialize compressor: %s",
                          erofs_strerror(err));
                goto exit;
        }
 
+       importer_params.source = cfg.c_src_path;
+       importer_params.no_datainline = mkfs_no_datainline;
+       importer_params.dot_omitted = mkfs_dot_omitted;
+       err = erofs_importer_init(&importer);
+       if (err)
+               goto exit;
+
        if (cfg.c_dedupe) {
                if (!cfg.c_compr_opts[0].alg) {
                        erofs_err("Compression is not enabled.  Turn on 
chunk-based data deduplication instead.");
@@ -1771,12 +1737,7 @@ int main(int argc, char **argv)
        erofs_iput(root);
        root = NULL;
 
-       err = erofs_writesb(&g_sbi, sb_bh);
-       if (err)
-               goto exit;
-
-       /* flush all remaining buffers */
-       err = erofs_bflush(g_sbi.bmgr, NULL);
+       err = erofs_writesb(&g_sbi);
        if (err)
                goto exit;
 
-- 
2.43.5


Reply via email to