diff options
-rw-r--r-- | doc/rdsquashfs.1 | 7 | ||||
-rw-r--r-- | include/fstree.h | 7 | ||||
-rw-r--r-- | lib/fstree/optimize_unpack_order.c | 55 | ||||
-rw-r--r-- | unpack/fill_files.c | 62 | ||||
-rw-r--r-- | unpack/options.c | 19 | ||||
-rw-r--r-- | unpack/rdsquashfs.c | 2 | ||||
-rw-r--r-- | unpack/rdsquashfs.h | 4 |
7 files changed, 14 insertions, 142 deletions
diff --git a/doc/rdsquashfs.1 b/doc/rdsquashfs.1 index 72c602a..338138a 100644 --- a/doc/rdsquashfs.1 +++ b/doc/rdsquashfs.1 @@ -57,13 +57,6 @@ Skip directories that would end up empty after applying the above rules. The following options are specific to unpacking files from a SquashFS image to disk: .TP -\fB\-\-jobs\fR, \fB\-j\fR <count> -Specify a number of parallel jobs to spawn for unpacking file data. -The file hierarchy is created sequentially but the data unpacking is -distributed over the given number of jobs so that each job has to unpack -roughly the same amount of data. This can be used to speed up unpacking -of large SquashFS archives. -.TP \fB\-\-no\-sparse\fR, \fB\-Z\fR Do not create sparse files. Always unpack sparse files by writing blocks of zeros to disk. diff --git a/include/fstree.h b/include/fstree.h index 880a870..05e1ebe 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -295,12 +295,9 @@ tree_node_t *fstree_node_from_path(fstree_t *fs, const char *path); /* Optimize the order of the fstree file list for unpacking as to avoid unpacking fragment blocks more than once and to improve locality when - fetching data from disk. The resulting list is returned in 'out'. - If num_jobs is > 1, the list is split up for parallel processing. + fetching data from disk. */ -void optimize_unpack_order(fstree_t *fs, size_t num_jobs, - file_info_t *out[num_jobs]); - +file_info_t *optimize_unpack_order(fstree_t *fs); /* Convert back to forward slashed, remove all preceeding and trailing slashes, diff --git a/lib/fstree/optimize_unpack_order.c b/lib/fstree/optimize_unpack_order.c index 51576bd..972d4b3 100644 --- a/lib/fstree/optimize_unpack_order.c +++ b/lib/fstree/optimize_unpack_order.c @@ -106,65 +106,14 @@ static file_info_t *list_sort(const fstree_t *fs, file_info_t *head) return merge(fs, list_sort(fs, head), list_sort(fs, half)); } -static file_info_t *split_list(file_info_t *list, uint64_t threashold) -{ - file_info_t *it, *new = NULL; - uint64_t size = 0; - - for (it = list; it != NULL; it = it->next) { - size += it->size - it->sparse; - - if (size >= threashold) { - new = it->next; - it->next = NULL; - break; - } - } - - return new; -} - -static uint64_t total_size(file_info_t *list) -{ - uint64_t size = 0; - file_info_t *it; - - for (it = list; it != NULL; it = it->next) - size += it->size - it->sparse; - - return size; -} - -void optimize_unpack_order(fstree_t *fs, size_t num_jobs, - file_info_t *out[num_jobs]) +file_info_t *optimize_unpack_order(fstree_t *fs) { file_info_t *file_list; - uint64_t threshold; - size_t i; - - if (num_jobs < 1) - return; - - for (i = 0; i < num_jobs; ++i) - out[i] = NULL; file_list = list_sort(fs, fs->files); while (file_list != NULL && file_list->input_file == NULL) file_list = file_list->next; fs->files = NULL; - - if (num_jobs < 2) { - out[0] = file_list; - return; - } - - threshold = total_size(file_list) / num_jobs; - - for (i = 0; i < (num_jobs - 1); ++i) { - out[i] = file_list; - file_list = split_list(file_list, threshold); - } - - out[i] = file_list; + return file_list; } diff --git a/unpack/fill_files.c b/unpack/fill_files.c index c0fc26c..df6ca7e 100644 --- a/unpack/fill_files.c +++ b/unpack/fill_files.c @@ -38,65 +38,17 @@ static int fill_files(data_reader_t *data, file_info_t *list, int flags) return 0; } -int fill_unpacked_files(fstree_t *fs, data_reader_t *data, int flags, - unsigned int num_jobs) +int fill_unpacked_files(fstree_t *fs, data_reader_t *data, int flags) { - file_info_t **sublists, *it; - int exitstatus, status = 0; - unsigned int i; - pid_t pid; + file_info_t *list, *it; + int status = 0; - if (num_jobs < 1) - num_jobs = 1; + list = optimize_unpack_order(fs); - sublists = alloca(sizeof(sublists[0]) * num_jobs); - optimize_unpack_order(fs, num_jobs, sublists); + status = fill_files(data, list, flags); - if (num_jobs < 2) { - status = fill_files(data, sublists[0], flags); - goto out; - } - - for (i = 0; i < num_jobs; ++i) { - pid = fork(); - - if (pid == 0) { - /* Kill the child when the parent process dies */ - prctl(PR_SET_PDEATHSIG, SIGKILL); - - if (fill_files(data, sublists[i], flags)) - exit(EXIT_FAILURE); - exit(EXIT_SUCCESS); - } - - if (pid < 0) { - perror("fork"); - status = -1; - break; - } - } - - for (;;) { - errno = 0; - pid = waitpid(-1, &exitstatus, 0); - - if (pid < 0) { - if (errno == EINTR) - continue; - if (errno == ECHILD) - break; - } - - if (!WIFEXITED(exitstatus) || - WEXITSTATUS(exitstatus) != EXIT_SUCCESS) { - status = -1; - } - } -out: - for (i = 0; i < num_jobs; ++i) { - for (it = sublists[i]; it != NULL; it = it->next) - free(it->input_file); - } + for (it = list; it != NULL; it = it->next) + free(it->input_file); return status; } diff --git a/unpack/options.c b/unpack/options.c index e880656..c7689eb 100644 --- a/unpack/options.c +++ b/unpack/options.c @@ -22,7 +22,6 @@ static struct option long_opts[] = { { "set-xattr", no_argument, NULL, 'X' }, #endif { "set-times", no_argument, NULL, 'T' }, - { "jobs", required_argument, NULL, 'j' }, { "describe", no_argument, NULL, 'd' }, { "chmod", no_argument, NULL, 'C' }, { "chown", no_argument, NULL, 'O' }, @@ -74,7 +73,6 @@ static const char *help_string = #endif " --set-times, -T When unpacking files to disk, set the create\n" " and modify timestamps from the squashfs image.\n" -" --jobs, -j <count> Number of parallel unpacking jobs to start.\n" " --chmod, -C Change permission flags of unpacked files to\n" " those store in the squashfs image.\n" " --chown, -O Change ownership of unpacked files to the\n" @@ -110,7 +108,7 @@ static char *get_path(char *old, const char *arg) void process_command_line(options_t *opt, int argc, char **argv) { - int i, j; + int i; opt->op = OP_NONE; opt->rdtree_flags = 0; @@ -118,7 +116,6 @@ void process_command_line(options_t *opt, int argc, char **argv) opt->cmdpath = NULL; opt->unpack_root = NULL; opt->image_name = NULL; - opt->num_jobs = 1; for (;;) { i = getopt_long(argc, argv, short_opts, long_opts, NULL); @@ -159,17 +156,6 @@ void process_command_line(options_t *opt, int argc, char **argv) case 'T': opt->flags |= UNPACK_SET_TIMES; break; - case 'j': - for (j = 0; optarg[j] != '\0'; ++j) { - if (j > 6 || !isdigit(optarg[j])) - goto fail_num_jobs; - } - - opt->num_jobs = atoi(optarg); - - if (opt->num_jobs < 1) - goto fail_num_jobs; - break; case 'c': opt->op = OP_CAT; opt->cmdpath = get_path(opt->cmdpath, optarg); @@ -227,7 +213,4 @@ fail_arg: fprintf(stderr, "Try `%s --help' for more information.\n", __progname); free(opt->cmdpath); exit(EXIT_FAILURE); -fail_num_jobs: - fputs("Expected a positive integer for --jobs.\n", stderr); - goto fail_arg; } diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c index e0cfaba..ea21318 100644 --- a/unpack/rdsquashfs.c +++ b/unpack/rdsquashfs.c @@ -115,7 +115,7 @@ int main(int argc, char **argv) if (restore_fstree(n, opt.flags)) goto out; - if (fill_unpacked_files(&fs, data, opt.flags, opt.num_jobs)) + if (fill_unpacked_files(&fs, data, opt.flags)) goto out; if (update_tree_attribs(&fs, n, opt.flags)) diff --git a/unpack/rdsquashfs.h b/unpack/rdsquashfs.h index 6805bed..b5570dd 100644 --- a/unpack/rdsquashfs.h +++ b/unpack/rdsquashfs.h @@ -57,7 +57,6 @@ typedef struct { int op; int rdtree_flags; int flags; - unsigned int num_jobs; char *cmdpath; const char *unpack_root; const char *image_name; @@ -69,8 +68,7 @@ int restore_fstree(tree_node_t *root, int flags); int update_tree_attribs(fstree_t *fs, tree_node_t *root, int flags); -int fill_unpacked_files(fstree_t *fs, data_reader_t *data, int flags, - unsigned int num_jobs); +int fill_unpacked_files(fstree_t *fs, data_reader_t *data, int flags); int describe_tree(tree_node_t *root, const char *unpack_root); |