summaryrefslogtreecommitdiff
path: root/lib/common/writer/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common/writer/init.c')
-rw-r--r--lib/common/writer/init.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/lib/common/writer/init.c b/lib/common/writer/init.c
new file mode 100644
index 0000000..d606d26
--- /dev/null
+++ b/lib/common/writer/init.c
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * init.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "simple_writer.h"
+#include "compress_cli.h"
+#include "common.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_SYSINFO_H
+#include <sys/sysinfo.h>
+
+static size_t os_get_num_jobs(void)
+{
+ int nprocs;
+
+ nprocs = get_nprocs_conf();
+ return nprocs < 1 ? 1 : nprocs;
+}
+#else
+static size_t os_get_num_jobs(void)
+{
+ return 1;
+}
+#endif
+
+void sqfs_writer_cfg_init(sqfs_writer_cfg_t *cfg)
+{
+ memset(cfg, 0, sizeof(*cfg));
+
+ cfg->num_jobs = os_get_num_jobs();
+ cfg->block_size = SQFS_DEFAULT_BLOCK_SIZE;
+ cfg->devblksize = SQFS_DEVBLK_SIZE;
+ cfg->comp_id = compressor_get_default();
+}
+
+int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg)
+{
+ sqfs_compressor_config_t cfg;
+ int ret, flags;
+
+ sqfs->filename = wrcfg->filename;
+
+ if (compressor_cfg_init_options(&cfg, wrcfg->comp_id,
+ wrcfg->block_size,
+ wrcfg->comp_extra)) {
+ return -1;
+ }
+
+ sqfs->outfile = sqfs_open_file(wrcfg->filename, wrcfg->outmode);
+ if (sqfs->outfile == NULL) {
+ perror(wrcfg->filename);
+ return -1;
+ }
+
+ if (fstree_init(&sqfs->fs, wrcfg->fs_defaults))
+ goto fail_file;
+
+ ret = sqfs_compressor_create(&cfg, &sqfs->cmp);
+
+#ifdef WITH_LZO
+ if (cfg.id == SQFS_COMP_LZO) {
+ if (sqfs->cmp != NULL)
+ sqfs_destroy(sqfs->cmp);
+
+ ret = lzo_compressor_create(&cfg, &sqfs->cmp);
+ }
+#endif
+
+ if (ret != 0) {
+ sqfs_perror(wrcfg->filename, "creating compressor", ret);
+ goto fail_fs;
+ }
+
+ ret = sqfs_super_init(&sqfs->super, wrcfg->block_size,
+ sqfs->fs.defaults.st_mtime, wrcfg->comp_id);
+ if (ret) {
+ sqfs_perror(wrcfg->filename, "initializing super block", ret);
+ goto fail_cmp;
+ }
+
+ ret = sqfs_super_write(&sqfs->super, sqfs->outfile);
+ if (ret) {
+ sqfs_perror(wrcfg->filename, "writing super block", ret);
+ goto fail_cmp;
+ }
+
+ ret = sqfs->cmp->write_options(sqfs->cmp, sqfs->outfile);
+ if (ret < 0) {
+ sqfs_perror(wrcfg->filename, "writing compressor options", ret);
+ goto fail_cmp;
+ }
+
+ if (ret > 0)
+ sqfs->super.flags |= SQFS_FLAG_COMPRESSOR_OPTIONS;
+
+ sqfs->blkwr = sqfs_block_writer_create(sqfs->outfile,
+ wrcfg->devblksize, 0);
+ if (sqfs->blkwr == NULL) {
+ perror("creating block writer");
+ goto fail_cmp;
+ }
+
+ sqfs->fragtbl = sqfs_frag_table_create(0);
+ if (sqfs->fragtbl == NULL) {
+ perror("creating fragment table");
+ goto fail_blkwr;
+ }
+
+ sqfs->data = sqfs_block_processor_create(sqfs->super.block_size,
+ sqfs->cmp, wrcfg->num_jobs,
+ wrcfg->max_backlog,
+ sqfs->blkwr, sqfs->fragtbl);
+ if (sqfs->data == NULL) {
+ perror("creating data block processor");
+ goto fail_fragtbl;
+ }
+
+ sqfs->idtbl = sqfs_id_table_create(0);
+ if (sqfs->idtbl == NULL) {
+ sqfs_perror(wrcfg->filename, "creating ID table",
+ SQFS_ERROR_ALLOC);
+ goto fail_data;
+ }
+
+ if (!wrcfg->no_xattr) {
+ sqfs->xwr = sqfs_xattr_writer_create(0);
+
+ if (sqfs->xwr == NULL) {
+ sqfs_perror(wrcfg->filename, "creating xattr writer",
+ SQFS_ERROR_ALLOC);
+ goto fail_id;
+ }
+ }
+
+ sqfs->im = sqfs_meta_writer_create(sqfs->outfile, sqfs->cmp, 0);
+ if (sqfs->im == NULL) {
+ fputs("Error creating inode meta data writer.\n", stderr);
+ goto fail_xwr;
+ }
+
+ sqfs->dm = sqfs_meta_writer_create(sqfs->outfile, sqfs->cmp,
+ SQFS_META_WRITER_KEEP_IN_MEMORY);
+ if (sqfs->dm == NULL) {
+ fputs("Error creating directory meta data writer.\n", stderr);
+ goto fail_im;
+ }
+
+ flags = 0;
+ if (wrcfg->exportable)
+ flags |= SQFS_DIR_WRITER_CREATE_EXPORT_TABLE;
+
+ sqfs->dirwr = sqfs_dir_writer_create(sqfs->dm, flags);
+ if (sqfs->dirwr == NULL) {
+ fputs("Error creating directory table writer.\n", stderr);
+ goto fail_dm;
+ }
+
+ return 0;
+fail_dm:
+ sqfs_destroy(sqfs->dm);
+fail_im:
+ sqfs_destroy(sqfs->im);
+fail_xwr:
+ if (sqfs->xwr != NULL)
+ sqfs_destroy(sqfs->xwr);
+fail_id:
+ sqfs_destroy(sqfs->idtbl);
+fail_data:
+ sqfs_destroy(sqfs->data);
+fail_fragtbl:
+ sqfs_destroy(sqfs->fragtbl);
+fail_blkwr:
+ sqfs_destroy(sqfs->blkwr);
+fail_cmp:
+ sqfs_destroy(sqfs->cmp);
+fail_fs:
+ fstree_cleanup(&sqfs->fs);
+fail_file:
+ sqfs_destroy(sqfs->outfile);
+ return -1;
+}