diff options
-rw-r--r-- | include/table.h | 18 | ||||
-rw-r--r-- | lib/Makemodule.am | 1 | ||||
-rw-r--r-- | lib/sqfs/table.c | 94 | ||||
-rw-r--r-- | mkfs/mksquashfs.c | 10 | ||||
-rw-r--r-- | mkfs/mksquashfs.h | 1 |
5 files changed, 124 insertions, 0 deletions
diff --git a/include/table.h b/include/table.h new file mode 100644 index 0000000..5a39797 --- /dev/null +++ b/include/table.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +#ifndef TABLE_H +#define TABLE_H + +#include "squashfs.h" +#include "compress.h" + +#include <stdint.h> +#include <stddef.h> + +int sqfs_write_fragment_table(int outfd, sqfs_super_t *super, + sqfs_fragment_t *fragments, size_t count, + compressor_t *cmp); + +int sqfs_write_ids(int outfd, sqfs_super_t *super, uint32_t *id_tbl, + size_t count, compressor_t *cmp); + +#endif /* TABLE_H */ 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 <endian.h> +#include <stdio.h> + +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; +} diff --git a/mkfs/mksquashfs.c b/mkfs/mksquashfs.c index 7e19d49..e554e62 100644 --- a/mkfs/mksquashfs.c +++ b/mkfs/mksquashfs.c @@ -122,6 +122,15 @@ int main(int argc, char **argv) if (sqfs_write_inodes(&info)) goto out_cmp; + if (sqfs_write_fragment_table(info.outfd, &info.super, + info.fragments, info.num_fragments, + info.cmp)) + goto out_cmp; + + if (sqfs_write_ids(info.outfd, &info.super, info.idtbl.ids, + info.idtbl.num_ids, info.cmp)) + goto out_cmp; + if (sqfs_super_write(&info.super, info.outfd)) goto out_cmp; @@ -130,6 +139,7 @@ int main(int argc, char **argv) status = EXIT_SUCCESS; out_cmp: + free(info.fragments); info.cmp->destroy(info.cmp); out_fstree: fstree_cleanup(&info.fs); diff --git a/mkfs/mksquashfs.h b/mkfs/mksquashfs.h index 0ffa721..f4ab53a 100644 --- a/mkfs/mksquashfs.h +++ b/mkfs/mksquashfs.h @@ -7,6 +7,7 @@ #include "id_table.h" #include "fstree.h" #include "config.h" +#include "table.h" #include <unistd.h> #include <stdlib.h> |