aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfs/write_inode.c
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-09-04 18:02:44 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-09-04 18:02:44 +0200
commit407a2baae5622b05f1e9c4137448a973fd648736 (patch)
tree475a668f763dfc83f08c7df7d811c7e141759bb9 /lib/sqfs/write_inode.c
parentf780c9542d2c96cb0ae00a8de8d67b9a8fd278cd (diff)
Split fstree inode serialization, move independend part to libsquashfs.so
This commit adds a function to libsquashfs.so for writing generic inodes to a meta writer and another function to libsqfshelper.a that turns a tree node to an inode. That way, the tree serialization code can be expressed in terms of those functions and a bulk of the independend code can be moved over to libsquashfs.so Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfs/write_inode.c')
-rw-r--r--lib/sqfs/write_inode.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/lib/sqfs/write_inode.c b/lib/sqfs/write_inode.c
new file mode 100644
index 0000000..a2d87f9
--- /dev/null
+++ b/lib/sqfs/write_inode.c
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * write_inode.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "sqfs/inode.h"
+
+static int write_block_sizes(meta_writer_t *ir, sqfs_inode_generic_t *n,
+ size_t file_num_blocks)
+{
+ uint32_t sizes[file_num_blocks];
+ size_t i;
+
+ for (i = 0; i < file_num_blocks; ++i)
+ sizes[i] = htole32(n->block_sizes[i]);
+
+ return meta_writer_append(ir, sizes,
+ sizeof(uint32_t) * file_num_blocks);
+}
+
+int meta_writer_write_inode(meta_writer_t *ir, sqfs_inode_generic_t *n,
+ size_t file_num_blocks)
+{
+ sqfs_inode_t base;
+
+ base.type = htole16(n->base.type);
+ base.mode = htole16(n->base.mode);
+ base.uid_idx = htole16(n->base.uid_idx);
+ base.gid_idx = htole16(n->base.gid_idx);
+ base.mod_time = htole32(n->base.mod_time);
+ base.inode_number = htole32(n->base.inode_number);
+
+ if (meta_writer_append(ir, &base, sizeof(base)))
+ return -1;
+
+ switch (n->base.type) {
+ case SQFS_INODE_DIR: {
+ sqfs_inode_dir_t dir = {
+ .start_block = htole32(n->data.dir.start_block),
+ .nlink = htole32(n->data.dir.nlink),
+ .size = htole16(n->data.dir.size),
+ .offset = htole16(n->data.dir.offset),
+ .parent_inode = htole32(n->data.dir.parent_inode),
+ };
+ return meta_writer_append(ir, &dir, sizeof(dir));
+ }
+ case SQFS_INODE_FILE: {
+ sqfs_inode_file_t file = {
+ .blocks_start = htole32(n->data.file.blocks_start),
+ .fragment_index = htole32(n->data.file.fragment_index),
+ .fragment_offset =
+ htole32(n->data.file.fragment_offset),
+ .file_size = htole32(n->data.file.file_size),
+ };
+ if (meta_writer_append(ir, &file, sizeof(file)))
+ return -1;
+ return write_block_sizes(ir, n, file_num_blocks);
+ }
+ case SQFS_INODE_SLINK: {
+ sqfs_inode_slink_t slink = {
+ .nlink = htole32(n->data.slink.nlink),
+ .target_size = htole32(n->data.slink.target_size),
+ };
+ if (meta_writer_append(ir, &slink, sizeof(slink)))
+ return -1;
+ return meta_writer_append(ir, n->slink_target,
+ n->data.slink.target_size);
+ }
+ case SQFS_INODE_BDEV:
+ case SQFS_INODE_CDEV: {
+ sqfs_inode_dev_t dev = {
+ .nlink = htole32(n->data.dev.nlink),
+ .devno = htole32(n->data.dev.devno),
+ };
+ return meta_writer_append(ir, &dev, sizeof(dev));
+ }
+ case SQFS_INODE_FIFO:
+ case SQFS_INODE_SOCKET: {
+ sqfs_inode_ipc_t ipc = {
+ .nlink = htole32(n->data.ipc.nlink),
+ };
+ return meta_writer_append(ir, &ipc, sizeof(ipc));
+ }
+ case SQFS_INODE_EXT_DIR: {
+ sqfs_inode_dir_ext_t dir = {
+ .nlink = htole32(n->data.dir_ext.nlink),
+ .size = htole32(n->data.dir_ext.size),
+ .start_block = htole32(n->data.dir_ext.start_block),
+ .parent_inode = htole32(n->data.dir_ext.parent_inode),
+ .inodex_count = htole16(n->data.dir_ext.inodex_count),
+ .offset = htole16(n->data.dir_ext.offset),
+ .xattr_idx = htole32(n->data.dir_ext.xattr_idx),
+ };
+ return meta_writer_append(ir, &dir, sizeof(dir));
+ }
+ case SQFS_INODE_EXT_FILE: {
+ sqfs_inode_file_ext_t file = {
+ .blocks_start = htole64(n->data.file_ext.blocks_start),
+ .file_size = htole64(n->data.file_ext.file_size),
+ .sparse = htole64(n->data.file_ext.sparse),
+ .nlink = htole32(n->data.file_ext.nlink),
+ .fragment_idx = htole32(n->data.file_ext.fragment_idx),
+ .fragment_offset =
+ htole32(n->data.file_ext.fragment_offset),
+ .xattr_idx = htole32(n->data.file_ext.xattr_idx),
+ };
+ if (meta_writer_append(ir, &file, sizeof(file)))
+ return -1;
+ return write_block_sizes(ir, n, file_num_blocks);
+ }
+ case SQFS_INODE_EXT_SLINK: {
+ sqfs_inode_slink_t slink = {
+ .nlink = htole32(n->data.slink_ext.nlink),
+ .target_size = htole32(n->data.slink_ext.target_size),
+ };
+ uint32_t xattr = htole32(n->data.slink_ext.xattr_idx);
+
+ if (meta_writer_append(ir, &slink, sizeof(slink)))
+ return -1;
+ if (meta_writer_append(ir, n->slink_target,
+ n->data.slink_ext.target_size)) {
+ return -1;
+ }
+ return meta_writer_append(ir, &xattr, sizeof(xattr));
+ }
+ case SQFS_INODE_EXT_BDEV:
+ case SQFS_INODE_EXT_CDEV: {
+ sqfs_inode_dev_ext_t dev = {
+ .nlink = htole32(n->data.dev_ext.nlink),
+ .devno = htole32(n->data.dev_ext.devno),
+ .xattr_idx = htole32(n->data.dev_ext.xattr_idx),
+ };
+ return meta_writer_append(ir, &dev, sizeof(dev));
+ }
+ case SQFS_INODE_EXT_FIFO:
+ case SQFS_INODE_EXT_SOCKET: {
+ sqfs_inode_ipc_ext_t ipc = {
+ .nlink = htole32(n->data.ipc_ext.nlink),
+ .xattr_idx = htole32(n->data.ipc_ext.xattr_idx),
+ };
+ return meta_writer_append(ir, &ipc, sizeof(ipc));
+ }
+ }
+
+ return -1;
+}