From e123eaf4330b24f765f7cc874a8790f44d2021d5 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Wed, 17 Apr 2019 23:22:12 +0200 Subject: [PATCH] pkg2sqfs: implement meta data compression Signed-off-by: David Oberhollenzer --- sqfs/meta.c | 8 +++----- sqfs/meta_writer.c | 20 +++++++++++++++----- sqfs/pkg2sqfs.c | 6 +++--- sqfs/pkg2sqfs.h | 10 ++++++---- sqfs/table.c | 16 ++++++++-------- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/sqfs/meta.c b/sqfs/meta.c index 1886fb7..497bbbb 100644 --- a/sqfs/meta.c +++ b/sqfs/meta.c @@ -208,7 +208,7 @@ out_file_blocks: return 0; } -int sqfs_write_inodes(sqfs_info_t *info) +int sqfs_write_inodes(sqfs_info_t *info, compressor_stream_t *strm) { meta_writer_t *im, *dm; size_t i, diff; @@ -224,11 +224,11 @@ int sqfs_write_inodes(sqfs_info_t *info) tmpfd = fileno(tmp); - im = meta_writer_create(info->outfd); + im = meta_writer_create(info->outfd, strm); if (im == NULL) goto fail_tmp; - dm = meta_writer_create(tmpfd); + dm = meta_writer_create(tmpfd, strm); if (dm == NULL) goto fail_im; @@ -280,8 +280,6 @@ int sqfs_write_inodes(sqfs_info_t *info) } } - info->super.flags |= SQFS_FLAG_UNCOMPRESSED_INODES; - meta_writer_destroy(dm); meta_writer_destroy(im); fclose(tmp); diff --git a/sqfs/meta_writer.c b/sqfs/meta_writer.c index 6df08bd..95ae52e 100644 --- a/sqfs/meta_writer.c +++ b/sqfs/meta_writer.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: ISC */ #include "pkg2sqfs.h" -meta_writer_t *meta_writer_create(int fd) +meta_writer_t *meta_writer_create(int fd, compressor_stream_t *strm) { meta_writer_t *m = calloc(1, sizeof(*m)); @@ -10,6 +10,7 @@ meta_writer_t *meta_writer_create(int fd) return NULL; } + m->strm = strm; m->outfd = fd; return m; } @@ -23,13 +24,22 @@ int meta_writer_flush(meta_writer_t *m) { ssize_t ret, count; - /* TODO: compress buffer */ - if (m->offset == 0) return 0; - ((uint16_t *)m->data)[0] = htole16(m->offset | 0x8000); - count = m->offset + 2; + ret = m->strm->do_block(m->strm, m->data + 2, m->scratch, + m->offset, sizeof(m->scratch)); + if (ret < 0) + return -1; + + if (ret > 0 && (size_t)ret < m->offset) { + memcpy(m->data + 2, m->scratch, ret); + ((uint16_t *)m->data)[0] = htole16(ret); + count = ret + 2; + } else { + ((uint16_t *)m->data)[0] = htole16(m->offset | 0x8000); + count = m->offset + 2; + } ret = write_retry(m->outfd, m->data, count); if (ret < 0) { diff --git a/sqfs/pkg2sqfs.c b/sqfs/pkg2sqfs.c index 77dab14..bbe979e 100644 --- a/sqfs/pkg2sqfs.c +++ b/sqfs/pkg2sqfs.c @@ -284,13 +284,13 @@ int main(int argc, char **argv) free(info.block); info.block = NULL; - if (sqfs_write_inodes(&info)) + if (sqfs_write_inodes(&info, cmp)) goto out_fragments; - if (sqfs_write_fragment_table(&info)) + if (sqfs_write_fragment_table(&info, cmp)) goto out_fragments; - if (sqfs_write_ids(&info)) + if (sqfs_write_ids(&info, cmp)) goto out_fragments; if (sqfs_super_write(&info)) diff --git a/sqfs/pkg2sqfs.h b/sqfs/pkg2sqfs.h index e349ab4..82ef1ec 100644 --- a/sqfs/pkg2sqfs.h +++ b/sqfs/pkg2sqfs.h @@ -30,9 +30,11 @@ typedef struct { uint8_t data[SQFS_META_BLOCK_SIZE + 2]; + uint8_t scratch[SQFS_META_BLOCK_SIZE]; size_t offset; size_t written; int outfd; + compressor_stream_t *strm; } meta_writer_t; typedef struct file_info_t { @@ -121,13 +123,13 @@ void destroy_vfs_tree(vfs_t *fs); node_t *vfs_node_from_file_id(vfs_t *fs, uint32_t id); -int sqfs_write_inodes(sqfs_info_t *info); +int sqfs_write_inodes(sqfs_info_t *info, compressor_stream_t *strm); -int sqfs_write_ids(sqfs_info_t *info); +int sqfs_write_ids(sqfs_info_t *info, compressor_stream_t *strm); -int sqfs_write_fragment_table(sqfs_info_t *info); +int sqfs_write_fragment_table(sqfs_info_t *info, compressor_stream_t *strm); -meta_writer_t *meta_writer_create(int fd); +meta_writer_t *meta_writer_create(int fd, compressor_stream_t *strm); void meta_writer_destroy(meta_writer_t *m); diff --git a/sqfs/table.c b/sqfs/table.c index 4024b83..c3fa2b5 100644 --- a/sqfs/table.c +++ b/sqfs/table.c @@ -2,7 +2,8 @@ #include "pkg2sqfs.h" static int sqfs_write_table(sqfs_info_t *info, const void *data, - size_t entsize, size_t count, uint64_t *startblock) + size_t entsize, size_t count, uint64_t *startblock, + compressor_stream_t *strm) { size_t ent_per_blocks = SQFS_META_BLOCK_SIZE / entsize; uint64_t blocks[count / ent_per_blocks + 1]; @@ -12,7 +13,7 @@ static int sqfs_write_table(sqfs_info_t *info, const void *data, /* Write actual data. Whenever we cross a block boundary, remember the block start offset */ - m = meta_writer_create(info->outfd); + m = meta_writer_create(info->outfd, strm); if (m == NULL) return -1; @@ -57,21 +58,20 @@ fail: return -1; } -int sqfs_write_fragment_table(sqfs_info_t *info) +int sqfs_write_fragment_table(sqfs_info_t *info, compressor_stream_t *strm) { info->super.fragment_entry_count = info->num_fragments; return sqfs_write_table(info, info->fragments, sizeof(info->fragments[0]), info->num_fragments, - &info->super.fragment_table_start); + &info->super.fragment_table_start, strm); } -int sqfs_write_ids(sqfs_info_t *info) +int sqfs_write_ids(sqfs_info_t *info, compressor_stream_t *strm) { - info->super.flags |= SQFS_FLAG_UNCOMPRESSED_IDS; - return sqfs_write_table(info, info->fs.id_tbl, sizeof(info->fs.id_tbl[0]), - info->fs.num_ids, &info->super.id_table_start); + info->fs.num_ids, + &info->super.id_table_start, strm); }