summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-07-23 16:12:40 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-07-25 22:10:24 +0200
commit22fba34bcd0f2944def234fa684d1c9cc4d65310 (patch)
treebb7d122e7d2bd06583b358f0530dc7ee189ef279
parent8cc66cf51bdbf50e3476b58106627afc7adc1300 (diff)
Generate linear file list in fstree
Instead of doing DFS on the fly in gensquashfs, churn out a linked list of all files in an archive. Future improvements in packing strategies can go into this file. This can also be usefull for other purposes in the future, such as file deduplication or as a work queue for the unpacker. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--include/fstree.h8
-rw-r--r--lib/Makemodule.am1
-rw-r--r--lib/fstree/gen_file_list.c36
-rw-r--r--mkfs/mkfs.c41
4 files changed, 59 insertions, 27 deletions
diff --git a/include/fstree.h b/include/fstree.h
index 2ba2b80..eb7b65f 100644
--- a/include/fstree.h
+++ b/include/fstree.h
@@ -57,6 +57,9 @@ struct tree_xattr_t {
/* Additional meta data stored in a tree_node_t for regular files. */
struct file_info_t {
+ /* Linked list pointer for files in fstree_t */
+ file_info_t *next;
+
/* Path to the input file. */
char *input_file;
@@ -157,6 +160,9 @@ struct fstree_t {
/* linear array of tree nodes. inode number is array index */
tree_node_t **inode_table;
+
+ /* linear linked list of all regular files */
+ file_info_t *files;
};
/*
@@ -252,6 +258,8 @@ int fstree_relabel_selinux(fstree_t *fs, const char *filename);
/* Returns 0 on success. Prints to stderr on failure */
int fstree_gen_inode_table(fstree_t *fs);
+void fstree_gen_file_list(fstree_t *fs);
+
/*
Generate a string holding the full path of a node. Returned
string must be freed.
diff --git a/lib/Makemodule.am b/lib/Makemodule.am
index c6674c0..0cc1847 100644
--- a/lib/Makemodule.am
+++ b/lib/Makemodule.am
@@ -4,6 +4,7 @@ libfstree_a_SOURCES += lib/fstree/gen_inode_table.c lib/fstree/get_path.c
libfstree_a_SOURCES += lib/fstree/node_stat.c lib/fstree/mknode.c
libfstree_a_SOURCES += lib/fstree/add_by_path.c lib/fstree/xattr.c
libfstree_a_SOURCES += lib/fstree/node_from_path.c include/fstree.h
+libfstree_a_SOURCES += lib/fstree/gen_file_list.c
libfstree_a_CFLAGS = $(AM_CFLAGS)
libfstree_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/lib/fstree/gen_file_list.c b/lib/fstree/gen_file_list.c
new file mode 100644
index 0000000..30cd2f6
--- /dev/null
+++ b/lib/fstree/gen_file_list.c
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+#include "config.h"
+#include "fstree.h"
+
+static file_info_t *file_list_dfs(tree_node_t *n)
+{
+ if (S_ISREG(n->mode))
+ return n->data.file;
+
+ if (S_ISDIR(n->mode)) {
+ file_info_t *list = NULL, *last = NULL;
+
+ for (n = n->data.dir->children; n != NULL; n = n->next) {
+ if (list == NULL) {
+ list = file_list_dfs(n);
+ if (list == NULL)
+ continue;
+ last = list;
+ } else {
+ last->next = file_list_dfs(n);
+ }
+
+ while (last->next != NULL)
+ last = last->next;
+ }
+
+ return list;
+ }
+
+ return NULL;
+}
+
+void fstree_gen_file_list(fstree_t *fs)
+{
+ fs->files = file_list_dfs(fs->root);
+}
diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c
index 654534d..a739322 100644
--- a/mkfs/mkfs.c
+++ b/mkfs/mkfs.c
@@ -1,44 +1,25 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
#include "mkfs.h"
-static int process_file(data_writer_t *data, tree_node_t *n, bool quiet)
+static int process_file(data_writer_t *data, file_info_t *fi, bool quiet)
{
int ret, infd;
- char *name;
- if (!quiet) {
- name = fstree_get_path(n);
- printf("packing %s\n", name);
- free(name);
- }
+ if (!quiet)
+ printf("packing %s\n", fi->input_file);
- infd = open(n->data.file->input_file, O_RDONLY);
+ infd = open(fi->input_file, O_RDONLY);
if (infd < 0) {
- perror(n->data.file->input_file);
+ perror(fi->input_file);
return -1;
}
- ret = write_data_from_fd(data, n->data.file, infd, 0);
+ ret = write_data_from_fd(data, fi, infd, 0);
close(infd);
return ret;
}
-static int pack_files_dfs(data_writer_t *data, tree_node_t *n, bool quiet)
-{
- if (S_ISREG(n->mode))
- return process_file(data, n, quiet);
-
- if (S_ISDIR(n->mode)) {
- for (n = n->data.dir->children; n != NULL; n = n->next) {
- if (pack_files_dfs(data, n, quiet))
- return -1;
- }
- }
-
- return 0;
-}
-
static int set_working_dir(options_t *opt)
{
const char *ptr;
@@ -63,11 +44,15 @@ static int restore_working_dir(options_t *opt)
static int pack_files(data_writer_t *data, fstree_t *fs, options_t *opt)
{
+ file_info_t *fi;
+
if (set_working_dir(opt))
return -1;
- if (pack_files_dfs(data, fs->root, opt->quiet))
- return -1;
+ for (fi = fs->files; fi != NULL; fi = fi->next) {
+ if (process_file(data, fi, opt->quiet))
+ return -1;
+ }
if (data_writer_flush_fragments(data))
return -1;
@@ -145,6 +130,8 @@ int main(int argc, char **argv)
if (fstree_gen_inode_table(&fs))
goto out_outfd;
+ fstree_gen_file_list(&fs);
+
super.inode_count = fs.inode_tbl_size - 2;
#ifdef WITH_SELINUX