summaryrefslogtreecommitdiff
path: root/mkfs
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-06-10 22:10:46 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-06-10 22:10:58 +0200
commit69de75de97c17ef7370b26944ee286e4b3dc6266 (patch)
tree3f35ecefdb56aaae6fc806a099dba50777f01a3d /mkfs
parent41fd1d4b9cd42eb28bf889719b8ce1a81af444b9 (diff)
cleanup: move entire fstree serialization to libsqfs.a
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'mkfs')
-rw-r--r--mkfs/Makemodule.am3
-rw-r--r--mkfs/meta.c96
-rw-r--r--mkfs/mkfs.c4
-rw-r--r--mkfs/mkfs.h12
-rw-r--r--mkfs/write_dir.c123
-rw-r--r--mkfs/write_inode.c290
6 files changed, 3 insertions, 525 deletions
diff --git a/mkfs/Makemodule.am b/mkfs/Makemodule.am
index 55f30c7..3dd639d 100644
--- a/mkfs/Makemodule.am
+++ b/mkfs/Makemodule.am
@@ -1,6 +1,5 @@
gensquashfs_SOURCES = mkfs/mkfs.c mkfs/mkfs.h mkfs/block.c
-gensquashfs_SOURCES += mkfs/options.c mkfs/meta.c mkfs/xattr.c
-gensquashfs_SOURCES += mkfs/write_dir.c mkfs/write_inode.c
+gensquashfs_SOURCES += mkfs/options.c mkfs/xattr.c
gensquashfs_LDADD = libsquashfs.a libfstree.a libcompress.a libutil.a
gensquashfs_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/mkfs/meta.c b/mkfs/meta.c
deleted file mode 100644
index 369149f..0000000
--- a/mkfs/meta.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-#include "mkfs.h"
-#include "util.h"
-
-int sqfs_write_inodes(sqfs_super_t *super, fstree_t *fs, int outfd,
- compressor_t *cmp, id_table_t *idtbl)
-{
- meta_writer_t *im, *dm;
- uint8_t buffer[1024];
- uint32_t offset;
- uint64_t block;
- size_t i, diff;
- ssize_t ret;
- FILE *tmp;
- int tmpfd;
-
- tmp = tmpfile();
- if (tmp == NULL) {
- perror("tmpfile");
- return -1;
- }
-
- tmpfd = fileno(tmp);
-
- im = meta_writer_create(outfd, cmp);
- if (im == NULL)
- goto fail_tmp;
-
- dm = meta_writer_create(tmpfd, cmp);
- if (dm == NULL)
- goto fail_im;
-
- for (i = 2; i < fs->inode_tbl_size; ++i) {
- if (write_inode(fs, idtbl, im, dm,
- fs->inode_table[i])) {
- goto fail;
- }
- }
-
- if (meta_writer_flush(im))
- goto fail;
-
- if (meta_writer_flush(dm))
- goto fail;
-
- super->root_inode_ref = fs->root->inode_ref;
-
- meta_writer_get_position(im, &block, &offset);
- super->inode_table_start = super->bytes_used;
- super->bytes_used += block;
-
- super->directory_table_start = super->bytes_used;
- meta_writer_get_position(dm, &block, &offset);
- super->bytes_used += block;
-
- if (lseek(tmpfd, 0, SEEK_SET) == (off_t)-1) {
- perror("rewind on directory temp file");
- goto fail;
- }
-
- for (;;) {
- ret = read_retry(tmpfd, buffer, sizeof(buffer));
-
- if (ret < 0) {
- perror("read from temp file");
- goto fail;
- }
- if (ret == 0)
- break;
-
- diff = ret;
- ret = write_retry(outfd, buffer, diff);
-
- if (ret < 0) {
- perror("write to image file");
- goto fail;
- }
- if ((size_t)ret < diff) {
- fputs("copying meta data to image file: "
- "truncated write\n", stderr);
- goto fail;
- }
- }
-
- meta_writer_destroy(dm);
- meta_writer_destroy(im);
- fclose(tmp);
- return 0;
-fail:
- meta_writer_destroy(dm);
-fail_im:
- meta_writer_destroy(im);
-fail_tmp:
- fclose(tmp);
- return -1;
-}
diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c
index 7c3fa28..019a233 100644
--- a/mkfs/mkfs.c
+++ b/mkfs/mkfs.c
@@ -114,8 +114,8 @@ int main(int argc, char **argv)
if (write_data_to_image(&info))
goto out_cmp;
- if (sqfs_write_inodes(&info.super, &info.fs, info.outfd,
- info.cmp, &info.idtbl)) {
+ if (sqfs_serialize_fstree(info.outfd, &info.super, &info.fs,
+ info.cmp, &info.idtbl)) {
goto out_cmp;
}
diff --git a/mkfs/mkfs.h b/mkfs/mkfs.h
index 36f412d..5d16c8b 100644
--- a/mkfs/mkfs.h
+++ b/mkfs/mkfs.h
@@ -19,18 +19,6 @@
#include <errno.h>
typedef struct {
- tree_node_t *node;
- uint32_t block;
- uint32_t offset;
-} idx_ref_t;
-
-typedef struct {
- size_t num_nodes;
- size_t max_nodes;
- idx_ref_t idx_nodes[];
-} dir_index_t;
-
-typedef struct {
unsigned int def_uid;
unsigned int def_gid;
unsigned int def_mode;
diff --git a/mkfs/write_dir.c b/mkfs/write_dir.c
deleted file mode 100644
index c8afb9b..0000000
--- a/mkfs/write_dir.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-#include "mkfs.h"
-#include "util.h"
-
-#include <assert.h>
-#include <endian.h>
-
-static int get_type(mode_t mode)
-{
- switch (mode & S_IFMT) {
- case S_IFSOCK: return SQFS_INODE_SOCKET;
- case S_IFIFO: return SQFS_INODE_FIFO;
- case S_IFLNK: return SQFS_INODE_SLINK;
- case S_IFBLK: return SQFS_INODE_BDEV;
- case S_IFCHR: return SQFS_INODE_CDEV;
- case S_IFDIR: return SQFS_INODE_DIR;
- case S_IFREG: return SQFS_INODE_FILE;
- default:
- assert(0);
- }
-}
-
-static int dir_index_grow(dir_index_t **index)
-{
- size_t size = sizeof(dir_index_t) + sizeof(idx_ref_t) * 10;
- void *new;
-
- if (*index == NULL) {
- new = calloc(1, size);
- } else {
- if ((*index)->num_nodes < (*index)->max_nodes)
- return 0;
-
- size += sizeof(idx_ref_t) * (*index)->num_nodes;
- new = realloc(*index, size);
- }
-
- if (new == NULL) {
- perror("creating directory index");
- return -1;
- }
-
- *index = new;
- (*index)->max_nodes += 10;
- return 0;
-}
-
-int write_dir(meta_writer_t *dm, dir_info_t *dir, dir_index_t **index)
-{
- size_t i, size, count;
- sqfs_dir_header_t hdr;
- sqfs_dir_entry_t ent;
- tree_node_t *c, *d;
- uint32_t offset;
- uint64_t block;
-
- c = dir->children;
- dir->size = 0;
-
- meta_writer_get_position(dm, &dir->start_block, &dir->block_offset);
-
- while (c != NULL) {
- meta_writer_get_position(dm, &block, &offset);
-
- count = 0;
- size = (offset + sizeof(hdr)) % SQFS_META_BLOCK_SIZE;
-
- for (d = c; d != NULL; d = d->next) {
- if ((d->inode_ref >> 16) != (c->inode_ref >> 16))
- break;
-
- /* XXX: difference is actually signed */
- if ((d->inode_num - c->inode_num) > 0x7FFF)
- break;
-
- size += sizeof(ent) + strlen(c->name);
-
- if (count > 0 && size > SQFS_META_BLOCK_SIZE)
- break;
-
- count += 1;
- }
-
- if (count > SQFS_MAX_DIR_ENT)
- count = SQFS_MAX_DIR_ENT;
-
- if (dir_index_grow(index))
- return -1;
-
- meta_writer_get_position(dm, &block, &offset);
-
- i = (*index)->num_nodes++;
- (*index)->idx_nodes[i].node = c;
- (*index)->idx_nodes[i].block = block;
- (*index)->idx_nodes[i].offset = offset;
-
- hdr.count = htole32(count - 1);
- hdr.start_block = htole32(c->inode_ref >> 16);
- hdr.inode_number = htole32(c->inode_num);
- dir->size += sizeof(hdr);
-
- if (meta_writer_append(dm, &hdr, sizeof(hdr)))
- return -1;
-
- d = c;
-
- for (i = 0; i < count; ++i) {
- ent.offset = htole16(c->inode_ref & 0x0000FFFF);
- ent.inode_number = htole16(c->inode_num - d->inode_num);
- ent.type = htole16(get_type(c->mode));
- ent.size = htole16(strlen(c->name) - 1);
- dir->size += sizeof(ent) + strlen(c->name);
-
- if (meta_writer_append(dm, &ent, sizeof(ent)))
- return -1;
- if (meta_writer_append(dm, c->name, strlen(c->name)))
- return -1;
-
- c = c->next;
- }
- }
- return 0;
-}
diff --git a/mkfs/write_inode.c b/mkfs/write_inode.c
deleted file mode 100644
index 6890cb6..0000000
--- a/mkfs/write_inode.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-#include "mkfs.h"
-#include "util.h"
-
-#include <assert.h>
-#include <endian.h>
-
-static int get_type(tree_node_t *node)
-{
- int type;
-
- switch (node->mode & S_IFMT) {
- case S_IFSOCK: type = SQFS_INODE_SOCKET; break;
- case S_IFIFO: type = SQFS_INODE_FIFO; break;
- case S_IFLNK: type = SQFS_INODE_SLINK; break;
- case S_IFBLK: type = SQFS_INODE_BDEV; break;
- case S_IFCHR: type = SQFS_INODE_CDEV; break;
- case S_IFDIR: type = SQFS_INODE_DIR; break;
- case S_IFREG: type = SQFS_INODE_FILE; break;
- default:
- assert(0);
- }
-
- if (node->xattr != NULL)
- type = SQFS_INODE_EXT_TYPE(type);
-
- return type;
-}
-
-static size_t hard_link_count(tree_node_t *n)
-{
- size_t count;
-
- if (S_ISDIR(n->mode)) {
- count = 2;
-
- for (n = n->data.dir->children; n != NULL; n = n->next)
- ++count;
-
- return count;
- }
-
- return 1;
-}
-
-int write_inode(fstree_t *fs, id_table_t *idtbl, meta_writer_t *im,
- meta_writer_t *dm, tree_node_t *node)
-{
- dir_index_t *diridx = NULL;
- uint16_t uid_idx, gid_idx;
- file_info_t *fi = NULL;
- dir_info_t *di = NULL;
- uint32_t bs, offset;
- sqfs_inode_t base;
- uint64_t i, block;
- int type;
-
- if (id_table_id_to_index(idtbl, node->uid, &uid_idx))
- return -1;
-
- if (id_table_id_to_index(idtbl, node->gid, &gid_idx))
- return -1;
-
- meta_writer_get_position(im, &block, &offset);
- node->inode_ref = (block << 16) | offset;
-
- type = get_type(node);
-
- if (S_ISDIR(node->mode)) {
- di = node->data.dir;
-
- if (write_dir(dm, di, &diridx))
- return -1;
-
- if ((di->start_block) > 0xFFFFFFFFUL || di->size > 0xFFFF ||
- node->xattr != NULL) {
- type = SQFS_INODE_EXT_DIR;
- } else {
- type = SQFS_INODE_DIR;
- free(diridx);
- diridx = NULL;
- }
- } else if (S_ISREG(node->mode)) {
- fi = node->data.file;
-
- if (fi->startblock > 0xFFFFFFFFUL || fi->size > 0xFFFFFFFFUL ||
- hard_link_count(node) > 1) {
- type = SQFS_INODE_EXT_FILE;
- }
- }
-
- base.type = htole16(type);
- base.mode = htole16(node->mode);
- base.uid_idx = htole16(uid_idx);
- base.gid_idx = htole16(gid_idx);
- base.mod_time = htole32(fs->default_mtime);
- base.inode_number = htole32(node->inode_num);
-
- if (meta_writer_append(im, &base, sizeof(base))) {
- free(diridx);
- return -1;
- }
-
- switch (type) {
- case SQFS_INODE_FIFO:
- case SQFS_INODE_SOCKET: {
- sqfs_inode_ipc_t ipc = {
- .nlink = hard_link_count(node),
- };
-
- return meta_writer_append(im, &ipc, sizeof(ipc));
- }
- case SQFS_INODE_EXT_FIFO:
- case SQFS_INODE_EXT_SOCKET: {
- sqfs_inode_ipc_ext_t ipc = {
- .nlink = hard_link_count(node),
- .xattr_idx = htole32(0xFFFFFFFF),
- };
-
- if (node->xattr != NULL)
- ipc.xattr_idx = htole32(node->xattr->index);
-
- return meta_writer_append(im, &ipc, sizeof(ipc));
- }
- case SQFS_INODE_SLINK: {
- sqfs_inode_slink_t slink = {
- .nlink = htole32(hard_link_count(node)),
- .target_size = htole32(strlen(node->data.slink_target)),
- };
-
- if (meta_writer_append(im, &slink, sizeof(slink)))
- return -1;
- if (meta_writer_append(im, node->data.slink_target,
- le32toh(slink.target_size))) {
- return -1;
- }
- break;
- }
- case SQFS_INODE_EXT_SLINK: {
- sqfs_inode_slink_t slink = {
- .nlink = htole32(hard_link_count(node)),
- .target_size = htole32(strlen(node->data.slink_target)),
- };
- uint32_t xattr = htole32(0xFFFFFFFF);
-
- if (node->xattr != NULL)
- xattr = htole32(node->xattr->index);
-
- if (meta_writer_append(im, &slink, sizeof(slink)))
- return -1;
- if (meta_writer_append(im, node->data.slink_target,
- le32toh(slink.target_size))) {
- return -1;
- }
- if (meta_writer_append(im, &xattr, sizeof(xattr)))
- return -1;
- break;
- }
- case SQFS_INODE_BDEV:
- case SQFS_INODE_CDEV: {
- sqfs_inode_dev_t dev = {
- .nlink = htole32(hard_link_count(node)),
- .devno = htole32(node->data.devno),
- };
-
- return meta_writer_append(im, &dev, sizeof(dev));
- }
- case SQFS_INODE_EXT_BDEV:
- case SQFS_INODE_EXT_CDEV: {
- sqfs_inode_dev_ext_t dev = {
- .nlink = htole32(hard_link_count(node)),
- .devno = htole32(node->data.devno),
- .xattr_idx = htole32(0xFFFFFFFF),
- };
-
- if (node->xattr != NULL)
- dev.xattr_idx = htole32(node->xattr->index);
-
- return meta_writer_append(im, &dev, sizeof(dev));
- }
-
- case SQFS_INODE_EXT_FILE: {
- sqfs_inode_file_ext_t ext = {
- .blocks_start = htole64(fi->startblock),
- .file_size = htole64(fi->size),
- .sparse = htole64(0xFFFFFFFFFFFFFFFFUL),
- .nlink = htole32(hard_link_count(node)),
- .fragment_idx = htole32(fi->fragment),
- .fragment_offset = htole32(fi->fragment_offset),
- .xattr_idx = htole32(0xFFFFFFFF),
- };
-
- if (node->xattr != NULL)
- ext.xattr_idx = htole32(node->xattr->index);
-
- if (meta_writer_append(im, &ext, sizeof(ext)))
- return -1;
- goto out_file_blocks;
- }
- case SQFS_INODE_FILE: {
- sqfs_inode_file_t reg = {
- .blocks_start = htole32(fi->startblock),
- .fragment_index = htole32(fi->fragment),
- .fragment_offset = htole32(fi->fragment_offset),
- .file_size = htole32(fi->size),
- };
-
- if (meta_writer_append(im, &reg, sizeof(reg)))
- return -1;
- goto out_file_blocks;
- }
- case SQFS_INODE_DIR: {
- sqfs_inode_dir_t dir = {
- .start_block = htole32(node->data.dir->start_block),
- .nlink = htole32(hard_link_count(node)),
- .size = htole16(node->data.dir->size),
- .offset = htole16(node->data.dir->block_offset),
- .parent_inode = node->parent ?
- htole32(node->parent->inode_num) : htole32(1),
- };
-
- return meta_writer_append(im, &dir, sizeof(dir));
- }
- case SQFS_INODE_EXT_DIR: {
- sqfs_dir_index_t idx;
- size_t i;
- sqfs_inode_dir_ext_t ext = {
- .nlink = htole32(hard_link_count(node)),
- .size = htole32(node->data.dir->size),
- .start_block = htole32(node->data.dir->start_block),
- .parent_inode = node->parent ?
- htole32(node->parent->inode_num) : htole32(1),
- .inodex_count = htole32(0),
- .offset = htole16(node->data.dir->block_offset),
- .xattr_idx = htole32(0xFFFFFFFF),
- };
-
- if (node->xattr != NULL)
- ext.xattr_idx = htole32(node->xattr->index);
-
- if (meta_writer_append(im, &ext, sizeof(ext))) {
- free(diridx);
- return -1;
- }
-
- /* HACK: truncated index for empty directories */
- if (node->data.dir->size == 0)
- break;
-
- ext.inodex_count = htole32(diridx->num_nodes - 1);
-
- for (i = 0; i < diridx->num_nodes; ++i) {
- idx.start_block = htole32(diridx->idx_nodes[i].block);
-
- idx.index = diridx->idx_nodes[i].offset;
- idx.index -= node->data.dir->block_offset;
- idx.index = htole32(idx.index);
-
- idx.size = strlen(diridx->idx_nodes[i].node->name) - 1;
- idx.size = htole32(idx.size);
-
- if (meta_writer_append(im, &idx, sizeof(idx))) {
- free(diridx);
- return -1;
- }
-
- if (meta_writer_append(im,
- diridx->idx_nodes[i].node->name,
- le32toh(idx.size) + 1)) {
- free(diridx);
- return -1;
- }
- }
-
- free(diridx);
- break;
- }
- default:
- assert(0);
- }
- return 0;
-out_file_blocks:
- for (i = 0; i < fi->size / fs->block_size; ++i) {
- bs = htole32(fi->blocksizes[i]);
-
- if (meta_writer_append(im, &bs, sizeof(bs)))
- return -1;
- }
- return 0;
-}