From e1e655b02f6c54177f9070eeb221ab95c6d4e20f Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Wed, 19 Apr 2023 10:13:49 +0200 Subject: libfstree: hoist file link pointer into parent structure Instead of having a file_info_t next pointer, requiring an up-cast to tree_node_t all the time, simply add a "next_by_type" pointer to the tree node itself, which can also be used for other purposes by other node types and removes the need for up-casting. Signed-off-by: David Oberhollenzer --- bin/gensquashfs/src/mkfs.c | 18 +++++++--------- bin/gensquashfs/src/sort_by_file.c | 43 +++++++++++++++++--------------------- bin/gensquashfs/test/sort_file.c | 16 +++++++------- include/fstree.h | 10 +++------ lib/fstree/src/post_process.c | 14 ++++++------- 5 files changed, 43 insertions(+), 58 deletions(-) diff --git a/bin/gensquashfs/src/mkfs.c b/bin/gensquashfs/src/mkfs.c index eb9f33b..683077b 100644 --- a/bin/gensquashfs/src/mkfs.c +++ b/bin/gensquashfs/src/mkfs.c @@ -12,9 +12,6 @@ static int pack_files(sqfs_block_processor_t *data, fstree_t *fs, sqfs_u64 filesize; sqfs_file_t *file; tree_node_t *node; - const char *path; - char *node_path; - file_info_t *fi; int flags; int ret; @@ -23,10 +20,11 @@ static int pack_files(sqfs_block_processor_t *data, fstree_t *fs, return -1; } - for (fi = fs->files; fi != NULL; fi = fi->next) { - if (fi->input_file == NULL) { - node = container_of(fi, tree_node_t, data.file); + for (node = fs->files; node != NULL; node = node->next_by_type) { + const char *path = node->data.file.input_file; + char *node_path = NULL; + if (path == NULL) { node_path = fstree_get_path(node); if (node_path == NULL) { perror("reconstructing file path"); @@ -37,9 +35,6 @@ static int pack_files(sqfs_block_processor_t *data, fstree_t *fs, assert(ret == 0); path = node_path; - } else { - node_path = NULL; - path = fi->input_file; } if (!opt->cfg.quiet) @@ -52,13 +47,14 @@ static int pack_files(sqfs_block_processor_t *data, fstree_t *fs, return -1; } - flags = fi->flags; + flags = node->data.file.flags; filesize = file->get_size(file); if (opt->no_tail_packing && filesize > opt->cfg.block_size) flags |= SQFS_BLK_DONT_FRAGMENT; - ret = write_data_from_file(path, data, &fi->inode, file, flags); + ret = write_data_from_file(path, data, &(node->data.file.inode), + file, flags); sqfs_drop(file); free(node_path); diff --git a/bin/gensquashfs/src/sort_by_file.c b/bin/gensquashfs/src/sort_by_file.c index 6a428ab..8edbb90 100644 --- a/bin/gensquashfs/src/sort_by_file.c +++ b/bin/gensquashfs/src/sort_by_file.c @@ -208,41 +208,41 @@ fail_flag: static void sort_file_list(fstree_t *fs) { - file_info_t *out = NULL, *out_last = NULL; + tree_node_t *out = NULL, *out_last = NULL; while (fs->files != NULL) { - sqfs_s64 lowest = fs->files->priority; - file_info_t *it, *prev; + sqfs_s64 lowest = fs->files->data.file.priority; + tree_node_t *it, *prev; - for (it = fs->files; it != NULL; it = it->next) { - if (it->priority < lowest) - lowest = it->priority; + for (it = fs->files; it != NULL; it = it->next_by_type) { + if (it->data.file.priority < lowest) + lowest = it->data.file.priority; } it = fs->files; prev = NULL; while (it != NULL) { - if (it->priority != lowest) { + if (it->data.file.priority != lowest) { prev = it; - it = it->next; + it = it->next_by_type; continue; } if (prev == NULL) { - fs->files = it->next; + fs->files = it->next_by_type; } else { - prev->next = it->next; + prev->next_by_type = it->next_by_type; } if (out == NULL) { out = it; } else { - out_last->next = it; + out_last->next_by_type = it; } out_last = it; - it = it->next; + it = it->next_by_type; out_last->next = NULL; } } @@ -254,13 +254,11 @@ int fstree_sort_files(fstree_t *fs, istream_t *sortfile) { const char *filename; size_t line_num = 1; - file_info_t *it; + tree_node_t *node; - for (it = fs->files; it != NULL; it = it->next) { - tree_node_t *node = container_of(it, tree_node_t, data.file); - - it->priority = 0; - it->flags = 0; + for (node = fs->files; node != NULL; node = node->next_by_type) { + node->data.file.priority = 0; + node->data.file.flags = 0; node->flags &= ~FLAG_FILE_ALREADY_MATCHED; } @@ -306,11 +304,9 @@ int fstree_sort_files(fstree_t *fs, istream_t *sortfile) have_match = false; - for (it = fs->files; it != NULL; it = it->next) { - tree_node_t *node; + for (node = fs->files; node != NULL; node = node->next_by_type) { char *path; - node = container_of(it, tree_node_t, data.file); if (node->flags & FLAG_FILE_ALREADY_MATCHED) continue; @@ -335,7 +331,6 @@ int fstree_sort_files(fstree_t *fs, istream_t *sortfile) if (do_glob) { ret = fnmatch(line, path, path_glob ? FNM_PATHNAME : 0); - } else { ret = strcmp(path, line); } @@ -344,8 +339,8 @@ int fstree_sort_files(fstree_t *fs, istream_t *sortfile) if (ret == 0) { have_match = true; - it->flags = flags; - it->priority = priority; + node->data.file.flags = flags; + node->data.file.priority = priority; node->flags |= FLAG_FILE_ALREADY_MATCHED; if (!do_glob) diff --git a/bin/gensquashfs/test/sort_file.c b/bin/gensquashfs/test/sort_file.c index 4b5caf8..8022cff 100644 --- a/bin/gensquashfs/test/sort_file.c +++ b/bin/gensquashfs/test/sort_file.c @@ -151,7 +151,7 @@ static istream_t memstream = { int main(int argc, char **argv) { fstree_defaults_t fsd; - file_info_t *fi; + tree_node_t *n; fstree_t fs; size_t i; (void)argc; (void)argv; @@ -167,8 +167,7 @@ int main(int argc, char **argv) fstree_post_process(&fs); - for (i = 0, fi = fs.files; fi != NULL; fi = fi->next, ++i) { - tree_node_t *n = container_of(fi, tree_node_t, data.file); + for (i = 0, n = fs.files; n != NULL; n = n->next_by_type, ++i) { char *path = fstree_get_path(n); int ret; @@ -180,8 +179,8 @@ int main(int argc, char **argv) TEST_STR_EQUAL(initial_order[i], path); free(path); - TEST_EQUAL_I(fi->priority, 0); - TEST_EQUAL_I(fi->flags, 0); + TEST_EQUAL_I(n->data.file.priority, 0); + TEST_EQUAL_I(n->data.file.flags, 0); } TEST_EQUAL_UI(i, sizeof(initial_order) / sizeof(initial_order[0])); @@ -194,8 +193,7 @@ int main(int argc, char **argv) TEST_ASSERT(fstree_sort_files(&fs, &memstream) == 0); - for (i = 0, fi = fs.files; fi != NULL; fi = fi->next, ++i) { - tree_node_t *n = container_of(fi, tree_node_t, data.file); + for (i = 0, n = fs.files; n != NULL; n = n->next_by_type, ++i) { char *path = fstree_get_path(n); int ret; @@ -207,8 +205,8 @@ int main(int argc, char **argv) TEST_STR_EQUAL(after_sort_order[i], path); free(path); - TEST_EQUAL_I(fi->priority, priorities[i]); - TEST_EQUAL_I(fi->flags, flags[i]); + TEST_EQUAL_I(n->data.file.priority, priorities[i]); + TEST_EQUAL_I(n->data.file.flags, flags[i]); } TEST_EQUAL_UI(i, sizeof(after_sort_order) / diff --git a/include/fstree.h b/include/fstree.h index 1a7ad30..044bb48 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -26,9 +26,6 @@ typedef struct tree_node_t tree_node_t; typedef struct file_info_t file_info_t; typedef struct fstree_t fstree_t; -#define container_of(ptr, type, member) \ - ((type *)((char *)ptr - offsetof(type, member))) - enum { FLAG_DIR_CREATED_IMPLICITLY = 0x01, FLAG_FILE_ALREADY_MATCHED = 0x02, @@ -36,9 +33,6 @@ enum { /* 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; @@ -51,6 +45,8 @@ struct file_info_t { /* A node in a file system tree */ struct tree_node_t { + tree_node_t *next_by_type; + /* Parent directory children linked list pointer. */ tree_node_t *next; @@ -108,7 +104,7 @@ struct fstree_t { tree_node_t *root; /* linear linked list of all regular files */ - file_info_t *files; + tree_node_t *files; }; /* diff --git a/lib/fstree/src/post_process.c b/lib/fstree/src/post_process.c index 5bf7e7d..f8bc0f7 100644 --- a/lib/fstree/src/post_process.c +++ b/lib/fstree/src/post_process.c @@ -55,15 +55,15 @@ fail_ov: return -1; } -static file_info_t *file_list_dfs(tree_node_t *n) +static tree_node_t *file_list_dfs(tree_node_t *n) { if (S_ISREG(n->mode)) { - n->data.file.next = NULL; - return &n->data.file; + n->next_by_type = NULL; + return n; } if (S_ISDIR(n->mode)) { - file_info_t *list = NULL, *last = NULL; + tree_node_t *list = NULL, *last = NULL; for (n = n->data.children; n != NULL; n = n->next) { if (list == NULL) { @@ -72,11 +72,11 @@ static file_info_t *file_list_dfs(tree_node_t *n) continue; last = list; } else { - last->next = file_list_dfs(n); + last->next_by_type = file_list_dfs(n); } - while (last->next != NULL) - last = last->next; + while (last->next_by_type != NULL) + last = last->next_by_type; } return list; -- cgit v1.2.3