From c2e01ed987e942005fa66f11d96b8edb1d930c99 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Mon, 20 May 2019 11:01:10 +0200 Subject: cleanup: internalize meta reader/writer implementations Signed-off-by: David Oberhollenzer --- include/fstree.h | 2 +- include/meta_reader.h | 42 +----------------------------------------- include/meta_writer.h | 42 ++++++------------------------------------ lib/sqfs/meta_reader.c | 23 +++++++++++++++++++++++ lib/sqfs/meta_writer.c | 33 +++++++++++++++++++++++++++++++++ lib/sqfs/table.c | 12 ++++++++---- mkfs/meta.c | 35 +++++++++++++++++++++++------------ mkfs/xattr.c | 26 +++++++++++++++----------- 8 files changed, 110 insertions(+), 105 deletions(-) diff --git a/include/fstree.h b/include/fstree.h index e8324a9..4986ec2 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -28,7 +28,7 @@ struct tree_xattr_t { size_t num_attr; size_t max_attr; - uint32_t block; + uint64_t block; uint32_t offset; uint32_t size; diff --git a/include/meta_reader.h b/include/meta_reader.h index 78c0db3..a662959 100644 --- a/include/meta_reader.h +++ b/include/meta_reader.h @@ -5,47 +5,7 @@ #include "compress.h" #include "squashfs.h" -/** - * @struct meta_reader_t - * - * @brief Abstracts away I/O on SquashFS meta data - */ -typedef struct { - /** - * @brief The location of the current block in the file - */ - uint64_t block_offset; - - /** - * @brief The location of the next block after the current one - */ - uint64_t next_block; - - /** - * @brief A byte offset into the uncompressed data of the current block - */ - size_t offset; - - /** - * @brief The underlying file descriptor to read from - */ - int fd; - - /** - * @brief A pointer to the compressor to use for extracting data - */ - compressor_t *cmp; - - /** - * @brief The raw data read from the input file - */ - uint8_t data[SQFS_META_BLOCK_SIZE]; - - /** - * @brief The uncompressed data read from the input file - */ - uint8_t scratch[SQFS_META_BLOCK_SIZE]; -} meta_reader_t; +typedef struct meta_reader_t meta_reader_t; /** * @brief Create a meta data reader diff --git a/include/meta_writer.h b/include/meta_writer.h index 9dcc22d..6bcb29b 100644 --- a/include/meta_writer.h +++ b/include/meta_writer.h @@ -5,42 +5,7 @@ #include "compress.h" #include "squashfs.h" -/** - * @struct meta_writer_t - * - * @brief Abstracts away I/O on SquashFS meta data - */ -typedef struct { - /** - * @brief A byte offset into the uncompressed data of the current block - */ - size_t offset; - - /** - * @brief The location of the current block in the file - */ - size_t block_offset; - - /** - * @brief The underlying file descriptor to write to - */ - int outfd; - - /** - * @brief A pointer to the compressor to use for compressing the data - */ - compressor_t *cmp; - - /** - * @brief The raw data chunk that data is appended to - */ - uint8_t data[SQFS_META_BLOCK_SIZE + 2]; - - /** - * @brief Scratch buffer for compressing data - */ - uint8_t scratch[SQFS_META_BLOCK_SIZE + 2]; -} meta_writer_t; +typedef struct meta_writer_t meta_writer_t; /** * @brief Create a meta data writer @@ -102,4 +67,9 @@ int meta_writer_flush(meta_writer_t *m); */ int meta_writer_append(meta_writer_t *m, const void *data, size_t size); +void meta_writer_get_position(const meta_writer_t *m, uint64_t *block_start, + uint32_t *offset); + +void meta_writer_reset(meta_writer_t *m); + #endif /* META_WRITER_H */ diff --git a/lib/sqfs/meta_reader.c b/lib/sqfs/meta_reader.c index 1a70238..e9b599f 100644 --- a/lib/sqfs/meta_reader.c +++ b/lib/sqfs/meta_reader.c @@ -7,6 +7,29 @@ #include #include +struct meta_reader_t { + /* The location of the current block in the image */ + uint64_t block_offset; + + /* The location of the next block after the current one */ + uint64_t next_block; + + /* A byte offset into the uncompressed data of the current block */ + size_t offset; + + /* The underlying file descriptor to read from */ + int fd; + + /* A pointer to the compressor to use for extracting data */ + compressor_t *cmp; + + /* The raw data read from the input file */ + uint8_t data[SQFS_META_BLOCK_SIZE]; + + /* The uncompressed data read from the input file */ + uint8_t scratch[SQFS_META_BLOCK_SIZE]; +}; + meta_reader_t *meta_reader_create(int fd, compressor_t *cmp) { meta_reader_t *m = calloc(1, sizeof(*m)); diff --git a/lib/sqfs/meta_writer.c b/lib/sqfs/meta_writer.c index 77ceeb9..2dacaa0 100644 --- a/lib/sqfs/meta_writer.c +++ b/lib/sqfs/meta_writer.c @@ -8,6 +8,26 @@ #include #include +struct meta_writer_t { + /* A byte offset into the uncompressed data of the current block */ + size_t offset; + + /* The location of the current block in the file */ + size_t block_offset; + + /* The underlying file descriptor to write to */ + int outfd; + + /* A pointer to the compressor to use for compressing the data */ + compressor_t *cmp; + + /* The raw data chunk that data is appended to */ + uint8_t data[SQFS_META_BLOCK_SIZE + 2]; + + /* Scratch buffer for compressing data */ + uint8_t scratch[SQFS_META_BLOCK_SIZE + 2]; +}; + meta_writer_t *meta_writer_create(int fd, compressor_t *cmp) { meta_writer_t *m = calloc(1, sizeof(*m)); @@ -95,3 +115,16 @@ int meta_writer_append(meta_writer_t *m, const void *data, size_t size) return 0; } + +void meta_writer_get_position(const meta_writer_t *m, uint64_t *block_start, + uint32_t *offset) +{ + *block_start = m->block_offset; + *offset = m->offset; +} + +void meta_writer_reset(meta_writer_t *m) +{ + m->block_offset = 0; + m->offset = 0; +} diff --git a/lib/sqfs/table.c b/lib/sqfs/table.c index 882d9ba..4e0f9d1 100644 --- a/lib/sqfs/table.c +++ b/lib/sqfs/table.c @@ -11,9 +11,10 @@ int sqfs_write_table(int outfd, sqfs_super_t *super, const void *data, compressor_t *cmp) { size_t ent_per_blocks = SQFS_META_BLOCK_SIZE / entsize; - uint64_t blocks[count / ent_per_blocks + 1]; + uint64_t blocks[count / ent_per_blocks + 1], block; size_t i, blkidx = 0, tblsize; meta_writer_t *m; + uint32_t offset; ssize_t ret; /* Write actual data. Whenever we cross a block boundary, remember @@ -23,8 +24,10 @@ int sqfs_write_table(int outfd, sqfs_super_t *super, const void *data, return -1; for (i = 0; i < count; ++i) { - if (blkidx == 0 || m->block_offset > blocks[blkidx - 1]) - blocks[blkidx++] = m->block_offset; + meta_writer_get_position(m, &block, &offset); + + if (blkidx == 0 || block > blocks[blkidx - 1]) + blocks[blkidx++] = block; if (meta_writer_append(m, data, entsize)) goto fail; @@ -38,7 +41,8 @@ int sqfs_write_table(int outfd, sqfs_super_t *super, const void *data, for (i = 0; i < blkidx; ++i) blocks[i] = htole64(blocks[i] + super->bytes_used); - super->bytes_used += m->block_offset; + meta_writer_get_position(m, &block, &offset); + super->bytes_used += block; meta_writer_destroy(m); /* write new index table */ diff --git a/mkfs/meta.c b/mkfs/meta.c index 58f82d7..ee37054 100644 --- a/mkfs/meta.c +++ b/mkfs/meta.c @@ -65,16 +65,19 @@ static int write_dir(meta_writer_t *dm, dir_info_t *dir, dir_index_t **index) 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; - dir->start_block = dm->block_offset; - dir->block_offset = dm->offset; + meta_writer_get_position(dm, &dir->start_block, &dir->block_offset); while (c != NULL) { + meta_writer_get_position(dm, &block, &offset); + count = 0; - size = (dm->offset + sizeof(hdr)) % SQFS_META_BLOCK_SIZE; + 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)) @@ -96,10 +99,12 @@ static int write_dir(meta_writer_t *dm, dir_info_t *dir, dir_index_t **index) 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 = dm->block_offset; - (*index)->idx_nodes[i].offset = dm->offset; + (*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); @@ -136,9 +141,9 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, uint16_t uid_idx, gid_idx; file_info_t *fi = NULL; dir_info_t *di = NULL; + uint32_t bs, offset; sqfs_inode_t base; - uint32_t bs; - uint64_t i; + uint64_t i, block; if (id_table_id_to_index(&info->idtbl, node->uid, &uid_idx)) return -1; @@ -146,7 +151,8 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, if (id_table_id_to_index(&info->idtbl, node->gid, &gid_idx)) return -1; - node->inode_ref = (im->block_offset << 16) | im->offset; + meta_writer_get_position(im, &block, &offset); + node->inode_ref = (block << 16) | offset; node->inode_num = info->inode_counter++; info->super.inode_count += 1; @@ -433,6 +439,9 @@ static int write_child_inodes(sqfs_info_t *info, meta_writer_t *im, int sqfs_write_inodes(sqfs_info_t *info) { meta_writer_t *im, *dm; + uint8_t buffer[1024]; + uint32_t offset; + uint64_t block; size_t diff; ssize_t ret; FILE *tmp; @@ -470,11 +479,13 @@ int sqfs_write_inodes(sqfs_info_t *info) info->super.root_inode_ref = info->fs.root->inode_ref; + meta_writer_get_position(im, &block, &offset); info->super.inode_table_start = info->super.bytes_used; - info->super.bytes_used += im->block_offset; + info->super.bytes_used += block; info->super.directory_table_start = info->super.bytes_used; - info->super.bytes_used += dm->block_offset; + meta_writer_get_position(dm, &block, &offset); + info->super.bytes_used += block; if (lseek(tmpfd, 0, SEEK_SET) == (off_t)-1) { perror("rewind on directory temp file"); @@ -482,7 +493,7 @@ int sqfs_write_inodes(sqfs_info_t *info) } for (;;) { - ret = read_retry(tmpfd, dm->data, sizeof(dm->data)); + ret = read_retry(tmpfd, buffer, sizeof(buffer)); if (ret < 0) { perror("read from temp file"); @@ -492,7 +503,7 @@ int sqfs_write_inodes(sqfs_info_t *info) break; diff = ret; - ret = write_retry(info->outfd, dm->data, diff); + ret = write_retry(info->outfd, buffer, diff); if (ret < 0) { perror("write to image file"); diff --git a/mkfs/xattr.c b/mkfs/xattr.c index 8f1a816..b7f433e 100644 --- a/mkfs/xattr.c +++ b/mkfs/xattr.c @@ -89,12 +89,13 @@ static int write_kv_pairs(sqfs_info_t *info, meta_writer_t *mw, int write_xattr(sqfs_info_t *info) { - uint64_t kv_start, id_start, *tbl; + uint64_t kv_start, id_start, block, *tbl; size_t i = 0, count = 0, blocks; sqfs_xattr_id_table_t idtbl; sqfs_xattr_id_t id_ent; meta_writer_t *mw; tree_xattr_t *it; + uint32_t offset; ssize_t ret; if (info->fs.xattr == NULL) @@ -108,8 +109,7 @@ int write_xattr(sqfs_info_t *info) kv_start = info->super.bytes_used; for (it = info->fs.xattr; it != NULL; it = it->next) { - it->block = mw->block_offset; - it->offset = mw->offset; + meta_writer_get_position(mw, &it->block, &it->offset); it->size = 0; if (write_kv_pairs(info, mw, it)) @@ -121,8 +121,10 @@ int write_xattr(sqfs_info_t *info) if (meta_writer_flush(mw)) goto fail_mw; - info->super.bytes_used += mw->block_offset; - mw->block_offset = 0; + meta_writer_get_position(mw, &block, &offset); + meta_writer_reset(mw); + + info->super.bytes_used += block; /* allocate location table */ blocks = (count * sizeof(id_ent)) / SQFS_META_BLOCK_SIZE; @@ -138,8 +140,8 @@ int write_xattr(sqfs_info_t *info) } /* write ID table referring to key value pairs, record offsets */ - id_start = mw->block_offset; - tbl[i++] = htole64(info->super.bytes_used + id_start); + id_start = 0; + tbl[i++] = htole64(info->super.bytes_used); for (it = info->fs.xattr; it != NULL; it = it->next) { id_ent.xattr = htole64((it->block << 16) | it->offset); @@ -149,8 +151,10 @@ int write_xattr(sqfs_info_t *info) if (meta_writer_append(mw, &id_ent, sizeof(id_ent))) goto fail_tbl; - if (mw->block_offset != id_start) { - id_start = mw->block_offset; + meta_writer_get_position(mw, &block, &offset); + + if (block != id_start) { + id_start = block; tbl[i++] = htole64(info->super.bytes_used + id_start); } } @@ -158,8 +162,8 @@ int write_xattr(sqfs_info_t *info) if (meta_writer_flush(mw)) goto fail_tbl; - info->super.bytes_used += mw->block_offset; - mw->block_offset = 0; + meta_writer_get_position(mw, &block, &offset); + info->super.bytes_used += block; /* write offset table */ idtbl.xattr_table_start = htole64(kv_start); -- cgit v1.2.3