...which will be filled into VMDK descriptor files. Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com> --- include/erofs/internal.h | 1 + lib/super.c | 5 + mkfs/main.c | 217 ++++++++++++++++++++++----------------- 3 files changed, 129 insertions(+), 94 deletions(-)
diff --git a/include/erofs/internal.h b/include/erofs/internal.h index 5e86943..8916be1 100644 --- a/include/erofs/internal.h +++ b/include/erofs/internal.h @@ -61,6 +61,7 @@ struct erofs_buffer_head; struct erofs_bufmgr; struct erofs_device_info { + char *src_path; u8 tag[64]; u32 blocks; u32 mapped_blkaddr; diff --git a/lib/super.c b/lib/super.c index 1541838..beab74e 100644 --- a/lib/super.c +++ b/lib/super.c @@ -145,6 +145,11 @@ int erofs_read_superblock(struct erofs_sb_info *sbi) void erofs_put_super(struct erofs_sb_info *sbi) { if (sbi->devs) { + int i; + + DBG_BUGON(!sbi->extra_devices); + for (i = 0; i < sbi->extra_devices; ++i) + free(sbi->devs[i].src_path); free(sbi->devs); sbi->devs = NULL; } diff --git a/mkfs/main.c b/mkfs/main.c index 16de894..ef83f2e 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -253,6 +253,7 @@ static u8 fixeduuid[16]; static bool valid_fixeduuid; static unsigned int dsunit; static unsigned int fsalignblks = 1; +static int tarerofs_decoder; static int erofs_mkfs_feat_set_legacy_compress(bool en, const char *val, unsigned int vallen) @@ -577,12 +578,93 @@ static void erofs_rebuild_cleanup(void) rebuild_src_count = 0; } +static int mkfs_parse_sources(int argc, char *argv[], int optind) +{ + struct stat st; + int err, fd; + char *s; + + if (tar_mode) { + cfg.c_src_path = strdup(argv[optind++]); + if (!cfg.c_src_path) + return -ENOMEM; + fd = open(cfg.c_src_path, O_RDONLY); + if (fd < 0) { + erofs_err("failed to open tar file: %s", cfg.c_src_path); + return -errno; + } + err = erofs_iostream_open(&erofstar.ios, fd, + tarerofs_decoder); + if (err) + return err; + + if (erofstar.dumpfile) { + fd = open(erofstar.dumpfile, + O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) { + erofs_err("failed to open dumpfile: %s", + erofstar.dumpfile); + return -errno; + } + erofstar.ios.dumpfd = fd; + } + } else { + err = lstat((s = argv[optind++]), &st); + if (err) { + erofs_err("failed to stat %s: %s", s, + erofs_strerror(-errno)); + return -ENOENT; + } + if (S_ISDIR(st.st_mode)) { + cfg.c_src_path = realpath(s, NULL); + if (!cfg.c_src_path) { + erofs_err("failed to parse source directory: %s", + erofs_strerror(-errno)); + return -ENOENT; + } + erofs_set_fs_root(cfg.c_src_path); + } else { + cfg.c_src_path = strdup(s); + if (!cfg.c_src_path) + return -ENOMEM; + rebuild_mode = true; + } + } + + if (rebuild_mode) { + char *srcpath = cfg.c_src_path; + struct erofs_sb_info *src; + + do { + src = calloc(1, sizeof(struct erofs_sb_info)); + if (!src) { + erofs_rebuild_cleanup(); + return -ENOMEM; + } + + err = erofs_dev_open(src, srcpath, O_RDONLY); + if (err) { + free(src); + erofs_rebuild_cleanup(); + return err; + } + + /* extra device index starts from 1 */ + src->dev = ++rebuild_src_count; + list_add(&src->list, &rebuild_src_list); + } while (optind < argc && (srcpath = argv[optind++])); + } else if (optind < argc) { + erofs_err("unexpected argument: %s\n", argv[optind]); + return -EINVAL; + } + return 0; +} + static int mkfs_parse_options_cfg(int argc, char *argv[]) { char *endptr; int opt, i, err; bool quiet = false; - int tarerofs_decoder = 0; bool has_timestamp = false; while ((opt = getopt_long(argc, argv, "C:E:L:T:U:b:d:x:z:Vh", @@ -939,93 +1021,28 @@ static int mkfs_parse_options_cfg(int argc, char *argv[]) if (!cfg.c_img_path) return -ENOMEM; - if (optind >= argc) { - if (!tar_mode) { - erofs_err("missing argument: SOURCE(s)"); - return -EINVAL; - } else { - int dupfd; - - dupfd = dup(STDIN_FILENO); - if (dupfd < 0) { - erofs_err("failed to duplicate STDIN_FILENO: %s", - strerror(errno)); - return -errno; - } - err = erofs_iostream_open(&erofstar.ios, dupfd, - tarerofs_decoder); - if (err) - return err; - } + if (optind < argc) { + err = mkfs_parse_sources(argc, argv, optind); + if (err) + return err; + } else if (!tar_mode) { + erofs_err("missing argument: SOURCE(s)"); + return -EINVAL; } else { - struct stat st; - - cfg.c_src_path = realpath(argv[optind++], NULL); - if (!cfg.c_src_path) { - erofs_err("failed to parse source directory: %s", - erofs_strerror(-errno)); - return -ENOENT; - } - - if (tar_mode) { - int fd = open(cfg.c_src_path, O_RDONLY); - - if (fd < 0) { - erofs_err("failed to open file: %s", cfg.c_src_path); - return -errno; - } - err = erofs_iostream_open(&erofstar.ios, fd, - tarerofs_decoder); - if (err) - return err; + int dupfd; - if (erofstar.dumpfile) { - fd = open(erofstar.dumpfile, - O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd < 0) { - erofs_err("failed to open dumpfile: %s", - erofstar.dumpfile); - return -errno; - } - erofstar.ios.dumpfd = fd; - } - } 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) { - char *srcpath = cfg.c_src_path; - struct erofs_sb_info *src; - - do { - src = calloc(1, sizeof(struct erofs_sb_info)); - if (!src) { - erofs_rebuild_cleanup(); - return -ENOMEM; - } - - err = erofs_dev_open(src, srcpath, O_RDONLY); - if (err) { - free(src); - erofs_rebuild_cleanup(); - return err; - } - - /* extra device index starts from 1 */ - src->dev = ++rebuild_src_count; - list_add(&src->list, &rebuild_src_list); - } while (optind < argc && (srcpath = argv[optind++])); - } else if (optind < argc) { - erofs_err("unexpected argument: %s\n", argv[optind]); - return -EINVAL; + dupfd = dup(STDIN_FILENO); + if (dupfd < 0) { + erofs_err("failed to duplicate STDIN_FILENO: %s", + strerror(errno)); + return -errno; } + err = erofs_iostream_open(&erofstar.ios, dupfd, + tarerofs_decoder); + if (err) + return err; } + if (quiet) { cfg.c_dbg_lvl = EROFS_ERR; cfg.c_showprogress = false; @@ -1115,6 +1132,7 @@ void erofs_show_progs(int argc, char *argv[]) static int erofs_mkfs_rebuild_load_trees(struct erofs_inode *root) { + struct erofs_device_info *devs; struct erofs_sb_info *src; unsigned int extra_devices = 0; erofs_blk_t nblocks; @@ -1163,20 +1181,22 @@ static int erofs_mkfs_rebuild_load_trees(struct erofs_inode *root) if (ret) return ret; + devs = g_sbi.devs; list_for_each_entry(src, &rebuild_src_list, list) { u8 *tag = NULL; + DBG_BUGON(src->dev < 1); + idx = src->dev - 1; if (extra_devices) { nblocks = src->devs[0].blocks; tag = src->devs[0].tag; } else { nblocks = src->primarydevice_blocks; + devs[idx].src_path = strdup(src->devname); } - DBG_BUGON(src->dev < 1); - idx = src->dev - 1; - g_sbi.devs[idx].blocks = nblocks; + devs[idx].blocks = nblocks; if (tag && *tag) - memcpy(g_sbi.devs[idx].tag, tag, sizeof(g_sbi.devs[0].tag)); + memcpy(devs[idx].tag, tag, sizeof(devs[0].tag)); else /* convert UUID of the source image to a hex string */ sprintf((char *)g_sbi.devs[idx].tag, @@ -1216,11 +1236,12 @@ static void erofs_mkfs_showsummaries(void) int main(int argc, char **argv) { - int err = 0; struct erofs_buffer_head *sb_bh; struct erofs_inode *root = NULL; + bool tar_index_512b = false; struct timeval t; FILE *blklst = NULL; + int err = 0; u32 crc; erofs_init_configure(); @@ -1291,12 +1312,13 @@ int main(int argc, char **argv) erofs_err("failed to open %s", erofstar.mapfile); goto exit; } - } else if (erofstar.index_mode) { + } else if (erofstar.index_mode && !erofstar.headeronly_mode) { /* * If mapfile is unspecified for tarfs index mode, * 512-byte block size is enforced here. */ g_sbi.blkszbits = 9; + tar_index_512b = true; } } @@ -1412,8 +1434,7 @@ int main(int argc, char **argv) return 1; } - if (((erofstar.index_mode && !erofstar.headeronly_mode) && - !erofstar.mapfile) || cfg.c_blobdev_path) { + if (tar_index_512b || cfg.c_blobdev_path) { err = erofs_mkfs_init_devices(&g_sbi, 1); if (err) { erofs_err("failed to generate device table: %s", @@ -1471,8 +1492,16 @@ int main(int argc, char **argv) } } - if (erofstar.index_mode && g_sbi.extra_devices && !erofstar.mapfile) - g_sbi.devs[0].blocks = BLK_ROUND_UP(&g_sbi, erofstar.offset); + if (tar_index_512b) { + if (!g_sbi.extra_devices) { + DBG_BUGON(1); + } else { + if (cfg.c_src_path) + g_sbi.devs[0].src_path = strdup(cfg.c_src_path); + g_sbi.devs[0].blocks = + BLK_ROUND_UP(&g_sbi, erofstar.offset); + } + } if ((cfg.c_fragments || cfg.c_extra_ea_name_prefixes) && erofs_sb_has_fragments(&g_sbi)) { -- 2.43.5