summaryrefslogtreecommitdiff
path: root/lib/sqfshelper/serialize_fstree.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfshelper/serialize_fstree.c')
-rw-r--r--lib/sqfshelper/serialize_fstree.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/lib/sqfshelper/serialize_fstree.c b/lib/sqfshelper/serialize_fstree.c
index 53e2236..f8f3913 100644
--- a/lib/sqfshelper/serialize_fstree.c
+++ b/lib/sqfshelper/serialize_fstree.c
@@ -11,17 +11,46 @@
#include "util.h"
#include <unistd.h>
+#include <stdlib.h>
#include <stdio.h>
+static int write_dir_entries(sqfs_dir_writer_t *dirw, tree_node_t *node)
+{
+ tree_node_t *it;
+ uint64_t ref;
+ int ret;
+
+ if (sqfs_dir_writer_begin(dirw))
+ return -1;
+
+ 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 (ret)
+ return -1;
+ }
+
+ if (sqfs_dir_writer_end(dirw))
+ return -1;
+
+ ref = sqfs_dir_writer_get_dir_reference(dirw);
+
+ node->data.dir->size = sqfs_dir_writer_get_size(dirw);
+ node->data.dir->start_block = ref >> 16;
+ node->data.dir->block_offset = ref & 0xFFFF;
+ return 0;
+}
+
int sqfs_serialize_fstree(int outfd, sqfs_super_t *super, fstree_t *fs,
compressor_t *cmp, id_table_t *idtbl)
{
+ sqfs_inode_generic_t *inode;
sqfs_dir_writer_t *dirwr;
meta_writer_t *im, *dm;
+ size_t i, count;
uint32_t offset;
uint64_t block;
int ret = -1;
- size_t i;
im = meta_writer_create(outfd, cmp, false);
if (im == NULL)
@@ -36,10 +65,37 @@ int sqfs_serialize_fstree(int outfd, sqfs_super_t *super, fstree_t *fs,
goto out_dm;
for (i = 2; i < fs->inode_tbl_size; ++i) {
- if (meta_writer_write_inode(fs, idtbl, im, dirwr,
- fs->inode_table[i])) {
+ if (S_ISDIR(fs->inode_table[i]->mode)) {
+ if (write_dir_entries(dirwr, fs->inode_table[i]))
+ goto out;
+ }
+
+ inode = tree_node_to_inode(fs, idtbl, fs->inode_table[i],
+ &count);
+ if (inode == NULL)
+ goto out;
+
+ if (inode->base.type == SQFS_INODE_EXT_DIR) {
+ inode->data.dir_ext.inodex_count =
+ sqfs_dir_writer_get_index_size(dirwr);
+ }
+
+ meta_writer_get_position(im, &block, &offset);
+ fs->inode_table[i]->inode_ref = (block << 16) | offset;
+
+ if (meta_writer_write_inode(im, inode, count)) {
+ free(inode);
goto out;
}
+
+ if (inode->base.type == SQFS_INODE_EXT_DIR) {
+ if (sqfs_dir_writer_write_index(dirwr, im)) {
+ free(inode);
+ goto out;
+ }
+ }
+
+ free(inode);
}
if (meta_writer_flush(im))