[PATCH v2 16/16] erofs-utils: mkfs: introduce rebuild mode
Jingbo Xu
jefflexu at linux.alibaba.com
Wed Aug 2 19:17:50 AEST 2023
Introduce a new rebuild mode merging multiple erofs images generated
from tarfs mode. This can be called like:
mkfs.erofs IMAGE UPPER_IMAGE LOWER_IMAGE ...
Signed-off-by: Jingbo Xu <jefflexu at linux.alibaba.com>
---
include/erofs/rebuild.h | 1 +
lib/rebuild.c | 25 ++++++++++
mkfs/main.c | 108 +++++++++++++++++++++++++---------------
3 files changed, 93 insertions(+), 41 deletions(-)
diff --git a/include/erofs/rebuild.h b/include/erofs/rebuild.h
index 55cd856..04fcb26 100644
--- a/include/erofs/rebuild.h
+++ b/include/erofs/rebuild.h
@@ -23,6 +23,7 @@ void erofs_cleanup_imgs(void);
int erofs_rebuild_load_tree(struct erofs_inode *root, struct erofs_img *img,
unsigned long **datablk_map, unsigned long *datablks);
+struct erofs_inode *erofs_rebuild_load_trees(void);
struct erofs_dentry *erofs_rebuild_get_dentry(struct erofs_inode *pwd,
char *path, bool aufs, bool *whout, bool *opq);
diff --git a/lib/rebuild.c b/lib/rebuild.c
index f641c40..d23bbdf 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -417,6 +417,31 @@ exit:
return ret;
}
+struct erofs_inode *erofs_rebuild_load_trees(void)
+{
+ struct erofs_img *img;
+ struct erofs_inode *root;
+ int ret, index = 0;
+
+ root = erofs_new_inode();
+ if (IS_ERR(root))
+ return root;
+ root->i_srcpath = strdup("/");
+ root->i_mode = S_IFDIR | 0777;
+ root->i_parent = root;
+ root->i_mtime = root->sbi->build_time;
+ root->i_mtime_nsec = root->sbi->build_time_nsec;
+ erofs_init_empty_dir(root);
+
+ list_for_each_entry(img, &imgs_list, list) {
+ ret = erofs_rebuild_load_tree(root, img, NULL, NULL);
+ if (ret)
+ return ERR_PTR(ret);
+ sbi.devs[index++].blocks = img->sbi.devs[0].blocks;
+ }
+ return root;
+}
+
struct erofs_img *erofs_get_img(const char *path)
{
struct erofs_img *img = malloc(sizeof(*img));
diff --git a/mkfs/main.c b/mkfs/main.c
index b495a54..3290ec8 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -26,6 +26,7 @@
#include "erofs/compress_hints.h"
#include "erofs/blobchunk.h"
#include "erofs/fragments.h"
+#include "erofs/rebuild.h"
#include "../lib/liberofs_private.h"
#include "../lib/liberofs_uuid.h"
@@ -132,6 +133,7 @@ static void usage(void)
static unsigned int pclustersize_packed, pclustersize_max;
static struct erofs_tarfile erofstar;
static bool tar_mode;
+static bool rebuild_mode;
static int parse_extended_opts(const char *opts)
{
@@ -275,7 +277,8 @@ static int mkfs_parse_compress_algs(char *algs)
static int mkfs_parse_options_cfg(int argc, char *argv[])
{
char *endptr;
- int opt, i;
+ struct stat st;
+ int opt, i, err;
bool quiet = false;
while ((opt = getopt_long(argc, argv, "C:E:L:T:U:b:d:x:z:",
@@ -531,7 +534,7 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
} else {
erofstar.fd = STDIN_FILENO;
}
- }else {
+ } else {
cfg.c_src_path = realpath(argv[optind++], NULL);
if (!cfg.c_src_path) {
erofs_err("failed to parse source directory: %s",
@@ -539,11 +542,39 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
return -ENOENT;
}
- if (optind < argc) {
+ if (tar_mode) {
+ erofstar.fd = open(cfg.c_src_path, O_RDONLY);
+ if (erofstar.fd < 0) {
+ erofs_err("failed to open file: %s", cfg.c_src_path);
+ usage();
+ return -errno;
+ }
+ } else {
+ err = lstat(cfg.c_src_path, &st);
+ if (err)
+ return -errno;
+ if (S_ISDIR(st.st_mode))
+ erofs_set_fs_root(cfg.c_src_path);
+ else
+ rebuild_mode = true;
+ }
+
+ if (rebuild_mode) {
+ optind--;
+ while (optind < argc) {
+ err = erofs_add_img(argv[optind++]);
+ if (err) {
+ erofs_err("failed to parse image file");
+ erofs_cleanup_imgs();
+ return err;
+ }
+ }
+ } else if (optind < argc) {
erofs_err("unexpected argument: %s\n", argv[optind]);
return -EINVAL;
}
}
+
if (quiet) {
cfg.c_dbg_lvl = EROFS_ERR;
cfg.c_showprogress = false;
@@ -734,7 +765,6 @@ int main(int argc, char **argv)
struct erofs_buffer_head *sb_bh;
struct erofs_inode *root_inode, *packed_inode;
erofs_nid_t root_nid, packed_nid;
- struct stat st;
erofs_blk_t nblocks;
struct timeval t;
char uuid_str[37];
@@ -757,26 +787,6 @@ int main(int argc, char **argv)
return 1;
}
- if (!tar_mode) {
- err = lstat(cfg.c_src_path, &st);
- if (err)
- return 1;
- if (!S_ISDIR(st.st_mode)) {
- erofs_err("root of the filesystem is not a directory - %s",
- cfg.c_src_path);
- usage();
- return 1;
- }
- erofs_set_fs_root(cfg.c_src_path);
- } else if (cfg.c_src_path) {
- erofstar.fd = open(cfg.c_src_path, O_RDONLY);
- if (erofstar.fd < 0) {
- erofs_err("failed to open file: %s", cfg.c_src_path);
- usage();
- return 1;
- }
- }
-
if (cfg.c_unix_timestamp != -1) {
sbi.build_time = cfg.c_unix_timestamp;
sbi.build_time_nsec = 0;
@@ -843,6 +853,9 @@ int main(int argc, char **argv)
}
}
+ if (rebuild_mode)
+ sbi.blkszbits = 9;
+
sb_bh = erofs_buffer_init();
if (IS_ERR(sb_bh)) {
err = PTR_ERR(sb_bh);
@@ -900,6 +913,8 @@ int main(int argc, char **argv)
if ((erofstar.index_mode && !erofstar.mapfile) || cfg.c_blobdev_path)
err = erofs_mkfs_init_devices(&sbi, 1);
+ else if (rebuild_mode)
+ err = erofs_mkfs_init_devices(&sbi, imgs_count);
if (err) {
erofs_err("failed to generate device table: %s",
erofs_strerror(err));
@@ -913,23 +928,7 @@ int main(int argc, char **argv)
if (cfg.c_extra_ea_name_prefixes)
erofs_xattr_write_name_prefixes(&sbi, packedfile);
- if (!tar_mode) {
- err = erofs_build_shared_xattrs_from_path(&sbi, cfg.c_src_path);
- if (err) {
- erofs_err("failed to build shared xattrs: %s",
- erofs_strerror(err));
- goto exit;
- }
-
- if (cfg.c_extra_ea_name_prefixes)
- erofs_xattr_write_name_prefixes(&sbi, packedfile);
-
- root_inode = erofs_mkfs_build_tree_from_path(cfg.c_src_path);
- if (IS_ERR(root_inode)) {
- err = PTR_ERR(root_inode);
- goto exit;
- }
- } else {
+ if (tar_mode) {
root_inode = erofs_new_inode();
if (IS_ERR(root_inode)) {
err = PTR_ERR(root_inode);
@@ -950,6 +949,32 @@ int main(int argc, char **argv)
err = erofs_rebuild_dump_tree(root_inode, false);
if (err < 0)
goto exit;
+ } else if (rebuild_mode) {
+ root_inode = erofs_rebuild_load_trees();
+ if (IS_ERR(root_inode)) {
+ err = PTR_ERR(root_inode);
+ goto exit;
+ }
+
+ err = erofs_rebuild_dump_tree(root_inode, true);
+ if (err)
+ goto exit;
+ } else {
+ err = erofs_build_shared_xattrs_from_path(&sbi, cfg.c_src_path);
+ if (err) {
+ erofs_err("failed to build shared xattrs: %s",
+ erofs_strerror(err));
+ goto exit;
+ }
+
+ if (cfg.c_extra_ea_name_prefixes)
+ erofs_xattr_write_name_prefixes(&sbi, packedfile);
+
+ root_inode = erofs_mkfs_build_tree_from_path(cfg.c_src_path);
+ if (IS_ERR(root_inode)) {
+ err = PTR_ERR(root_inode);
+ goto exit;
+ }
}
root_nid = erofs_lookupnid(root_inode);
erofs_iput(root_inode);
@@ -1003,6 +1028,7 @@ exit:
z_erofs_fragments_exit();
erofs_packedfile_exit();
erofs_xattr_cleanup_name_prefixes();
+ erofs_cleanup_imgs();
erofs_exit_configure();
if (err) {
--
2.19.1.6.gb485710b
More information about the Linux-erofs
mailing list