From 9eec700a703f62e27768f37a1c6c0e859212320c Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Wed, 1 May 2019 02:24:22 +0200 Subject: Write out the missing tables Signed-off-by: David Oberhollenzer --- lib/Makemodule.am | 1 + lib/sqfs/table.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 lib/sqfs/table.c (limited to 'lib') diff --git a/lib/Makemodule.am b/lib/Makemodule.am index b12367d..7de4c83 100644 --- a/lib/Makemodule.am +++ b/lib/Makemodule.am @@ -9,6 +9,7 @@ libcompress_a_CPPFLAGS = $(AM_CPPFLAGS) libsquashfs_a_SOURCES = include/meta_writer.h include/squashfs.h libsquashfs_a_SOURCES += lib/sqfs/meta_writer.c lib/sqfs/super.c libsquashfs_a_SOURCES += lib/sqfs/id_table.c include/id_table.h +libsquashfs_a_SOURCES += lib/sqfs/table.c include/table.h libutil_a_SOURCES = lib/util/canonicalize_name.c lib/util/write_retry.c libutil_a_SOURCES += lib/util/read_retry.c include/util.h diff --git a/lib/sqfs/table.c b/lib/sqfs/table.c new file mode 100644 index 0000000..2fab3cc --- /dev/null +++ b/lib/sqfs/table.c @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +#include "meta_writer.h" +#include "table.h" +#include "util.h" + +#include +#include + +static int sqfs_write_table(int outfd, sqfs_super_t *super, const void *data, + size_t entsize, size_t count, uint64_t *startblock, + compressor_t *cmp) +{ + size_t ent_per_blocks = SQFS_META_BLOCK_SIZE / entsize; + uint64_t blocks[count / ent_per_blocks + 1]; + size_t i, blkidx = 0, tblsize; + meta_writer_t *m; + ssize_t ret; + + /* Write actual data. Whenever we cross a block boundary, remember + the block start offset */ + m = meta_writer_create(outfd, cmp); + if (m == NULL) + return -1; + + for (i = 0; i < count; ++i) { + if (blkidx == 0 || m->block_offset > blocks[blkidx - 1]) + blocks[blkidx++] = m->block_offset; + + if (meta_writer_append(m, data, entsize)) + goto fail; + + data = (const char *)data + entsize; + } + + if (meta_writer_flush(m)) + goto fail; + + for (i = 0; i < blkidx; ++i) + blocks[i] = htole64(blocks[i] + super->bytes_used); + + super->bytes_used += m->block_offset; + meta_writer_destroy(m); + + /* write new index table */ + *startblock = super->bytes_used; + tblsize = sizeof(blocks[0]) * blkidx; + + ret = write_retry(outfd, blocks, tblsize); + if (ret < 0) { + perror("writing index table"); + return -1; + } + + if ((size_t)ret < tblsize) { + fputs("index table truncated\n", stderr); + return -1; + } + + super->bytes_used += tblsize; + return 0; +fail: + meta_writer_destroy(m); + return -1; +} + +int sqfs_write_fragment_table(int outfd, sqfs_super_t *super, + sqfs_fragment_t *fragments, size_t count, + compressor_t *cmp) +{ + super->fragment_entry_count = count; + + return sqfs_write_table(outfd, super, fragments, sizeof(fragments[0]), + count, &super->fragment_table_start, cmp); +} + +int sqfs_write_ids(int outfd, sqfs_super_t *super, uint32_t *id_tbl, + size_t count, compressor_t *cmp) +{ + size_t i; + int ret; + + for (i = 0; i < count; ++i) + id_tbl[i] = htole32(id_tbl[i]); + + super->id_count = count; + + ret = sqfs_write_table(outfd, super, id_tbl, sizeof(id_tbl[0]), + count, &super->id_table_start, cmp); + + for (i = 0; i < count; ++i) + id_tbl[i] = htole32(id_tbl[i]); + + return ret; +} -- cgit v1.2.3