diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-12-19 16:10:39 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-12-22 22:07:44 +0100 |
commit | 1466f1f8571aca423156ee7ef4094a0c082f88d7 (patch) | |
tree | 76863754fe3a0546ec8279da97cbeae7700b0abc /lib/common | |
parent | 0a6c5d7fa2f276b8e155d69bea17650bad46f089 (diff) |
Add basic support for handling and serializing hard links
In libfstree, add a function to add a hard link to the fstree. The
hard links stores the target in the data.target field, canonicalizes
the target and sets a sentinel mode. A second function is used to
resolve link, i.e. replacing it with a direct pointer, setting another
sentinel mode and increasing the targets link count.
The post process function tries to resolve unresolved hard links and
only allocates inode numbers for nodes that aren't hard links. If the
target node of a hard link does not have an inode number yet, the two
need to be swapped, since this is also the order in which they are
serialized.
The serialization function in libcommon simply has to skip hard link
nodes and when writing directory entries, use the inode num/ref of
the target node.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/common')
-rw-r--r-- | lib/common/serialize_fstree.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/common/serialize_fstree.c b/lib/common/serialize_fstree.c index 73f4e67..a5f5d71 100644 --- a/lib/common/serialize_fstree.c +++ b/lib/common/serialize_fstree.c @@ -64,7 +64,7 @@ static sqfs_inode_generic_t *write_dir_entries(const char *filename, { sqfs_u32 xattr, parent_inode; sqfs_inode_generic_t *inode; - tree_node_t *it; + tree_node_t *it, *tgt; int ret; ret = sqfs_dir_writer_begin(dirw, 0); @@ -72,8 +72,14 @@ static sqfs_inode_generic_t *write_dir_entries(const char *filename, goto fail; for (it = node->data.dir.children; it != NULL; it = it->next) { - ret = sqfs_dir_writer_add_entry(dirw, it->name, it->inode_num, - it->inode_ref, it->mode); + if (it->mode == FSTREE_MODE_HARD_LINK_RESOLVED) { + tgt = it->data.target_node; + } else { + tgt = it; + } + + ret = sqfs_dir_writer_add_entry(dirw, it->name, tgt->inode_num, + tgt->inode_ref, tgt->mode); if (ret) goto fail; } @@ -111,6 +117,9 @@ static int serialize_tree_node(const char *filename, sqfs_writer_t *wr, sqfs_u64 block; int ret; + if (n->mode == FSTREE_MODE_HARD_LINK_RESOLVED) + return 0; + if (S_ISDIR(n->mode)) { inode = write_dir_entries(filename, wr->dirwr, n); ret = SQFS_ERROR_INTERNAL; |