From bcb5a6e74ac97004acc9a4937285f001b895e0d7 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 22 Sep 2019 16:10:52 +0200 Subject: Use inode structures in the data writer instead of fstree file info Changes are minor, but needs some temporary hacks in fstree again. Signed-off-by: David Oberhollenzer --- include/data_writer.h | 4 +- include/fstree.h | 2 + include/highlevel.h | 2 +- lib/sqfshelper/data_writer.c | 58 +++++++++++++--------- lib/sqfshelper/serialize_fstree.c | 3 +- lib/sqfshelper/tree_node_to_inode.c | 97 +++++++++---------------------------- mkfs/mkfs.c | 22 ++++++++- tar/tar2sqfs.c | 23 ++++++++- 8 files changed, 106 insertions(+), 105 deletions(-) diff --git a/include/data_writer.h b/include/data_writer.h index 4d5fa12..1ff0d69 100644 --- a/include/data_writer.h +++ b/include/data_writer.h @@ -84,7 +84,7 @@ int data_writer_sync(data_writer_t *data); Returns 0 on success, prints errors to stderr. */ -int write_data_from_file(data_writer_t *data, file_info_t *fi, +int write_data_from_file(data_writer_t *data, sqfs_inode_generic_t *inode, sqfs_file_t *file, int flags); /* @@ -98,7 +98,7 @@ int write_data_from_file(data_writer_t *data, file_info_t *fi, Returns 0 on success, prints errors to stderr. */ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, - file_info_t *fi, + sqfs_inode_generic_t *inode, const sqfs_sparse_map_t *map, int flags); data_writer_stats_t *data_writer_get_stats(data_writer_t *data); diff --git a/include/fstree.h b/include/fstree.h index 8e35269..85e2258 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -78,6 +78,8 @@ struct file_info_t { uint64_t size; + void *user_ptr; + /* Number of bytes not written to disk because they are 0 */ uint64_t sparse; diff --git a/include/highlevel.h b/include/highlevel.h index 46a2330..b2bbd82 100644 --- a/include/highlevel.h +++ b/include/highlevel.h @@ -72,7 +72,7 @@ int compressor_cfg_init_options(sqfs_compressor_config_t *cfg, void compressor_print_help(E_SQFS_COMPRESSOR id); -sqfs_inode_generic_t *tree_node_to_inode(fstree_t *fs, sqfs_id_table_t *idtbl, +sqfs_inode_generic_t *tree_node_to_inode(sqfs_id_table_t *idtbl, tree_node_t *node); int inode_stat(const sqfs_tree_node_t *node, struct stat *sb); diff --git a/lib/sqfshelper/data_writer.c b/lib/sqfshelper/data_writer.c index f7d8805..9f418f1 100644 --- a/lib/sqfshelper/data_writer.c +++ b/lib/sqfshelper/data_writer.c @@ -113,7 +113,7 @@ static size_t deduplicate_blocks(data_writer_t *data, size_t count) static int block_callback(void *user, sqfs_block_t *blk) { - file_info_t *fi = blk->user; + sqfs_inode_generic_t *inode = blk->user; data_writer_t *data = user; size_t start, count; uint64_t offset; @@ -144,7 +144,7 @@ static int block_callback(void *user, sqfs_block_t *blk) data->stats.frag_blocks_written += 1; } else { - fi->block_size[blk->index] = htole32(out); + inode->block_sizes[blk->index] = htole32(out); data->stats.blocks_written += 1; } @@ -164,8 +164,9 @@ static int block_callback(void *user, sqfs_block_t *blk) count = data->num_blocks - data->file_start; start = deduplicate_blocks(data, count); + offset = data->blocks[start].offset; - fi->startblock = data->blocks[start].offset; + sqfs_inode_set_file_block_start(inode, offset); if (start < data->file_start) { offset = start + count; @@ -221,7 +222,7 @@ static int flush_fragment_block(data_writer_t *data) static int handle_fragment(data_writer_t *data, sqfs_block_t *frag) { - file_info_t *fi = frag->user; + sqfs_inode_generic_t *inode = frag->user; size_t i, size, new_sz; uint64_t signature; void *new; @@ -231,8 +232,9 @@ static int handle_fragment(data_writer_t *data, sqfs_block_t *frag) for (i = 0; i < data->frag_list_num; ++i) { if (data->frag_list[i].signature == signature) { - fi->fragment_offset = data->frag_list[i].offset; - fi->fragment = data->frag_list[i].index; + sqfs_inode_set_frag_location(inode, + data->frag_list[i].index, + data->frag_list[i].offset); free(frag); data->stats.frag_dup += 1; @@ -280,8 +282,8 @@ static int handle_fragment(data_writer_t *data, sqfs_block_t *frag) data->frag_list[data->frag_list_num].signature = signature; data->frag_list_num += 1; - fi->fragment_offset = data->frag_block->size; - fi->fragment = data->num_fragments; + sqfs_inode_set_frag_location(inode, data->num_fragments, + data->frag_block->size); data->frag_block->flags |= (frag->flags & SQFS_BLK_DONT_COMPRESS); memcpy(data->frag_block->data + data->frag_block->size, @@ -302,7 +304,7 @@ static bool is_zero_block(unsigned char *ptr, size_t size) return ptr[0] == 0 && memcmp(ptr, ptr + 1, size - 1) == 0; } -static int add_sentinel_block(data_writer_t *data, file_info_t *fi, +static int add_sentinel_block(data_writer_t *data, sqfs_inode_generic_t *inode, uint32_t flags) { sqfs_block_t *blk = calloc(1, sizeof(*blk)); @@ -312,20 +314,20 @@ static int add_sentinel_block(data_writer_t *data, file_info_t *fi, return -1; } - blk->user = fi; + blk->user = inode; blk->flags = SQFS_BLK_DONT_COMPRESS | SQFS_BLK_DONT_CHECKSUM | flags; return sqfs_block_processor_enqueue(data->proc, blk); } int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, - file_info_t *fi, + sqfs_inode_generic_t *inode, const sqfs_sparse_map_t *map, int flags) { uint32_t blk_flags = SQFS_BLK_FIRST_BLOCK; + uint64_t filesz, offset; size_t diff, i = 0; sqfs_block_t *blk; - uint64_t offset; int ret; if (flags & DW_DONT_COMPRESS) @@ -334,19 +336,21 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, if (flags & DW_ALLIGN_DEVBLK) blk_flags |= SQFS_BLK_ALLIGN; - for (offset = 0; offset < fi->size; offset += diff) { - if (fi->size - offset > (uint64_t)data->super->block_size) { + sqfs_inode_get_file_size(inode, &filesz); + + for (offset = 0; offset < filesz; offset += diff) { + if (filesz - offset > (uint64_t)data->super->block_size) { diff = data->super->block_size; } else { - diff = fi->size - offset; + diff = filesz - offset; } if (map == NULL) { - ret = sqfs_file_create_block(file, offset, diff, fi, + ret = sqfs_file_create_block(file, offset, diff, inode, blk_flags, &blk); } else { ret = sqfs_file_create_block_dense(file, offset, diff, - fi, blk_flags, + inode, blk_flags, map, &blk); } @@ -358,7 +362,11 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, if (is_zero_block(blk->data, blk->size)) { data->stats.sparse_blocks += 1; - fi->block_size[blk->index] = 0; + sqfs_inode_make_extended(inode); + inode->data.file_ext.sparse += blk->size; + inode->num_file_blocks += 1; + + inode->block_sizes[blk->index] = 0; free(blk); continue; } @@ -369,7 +377,8 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, SQFS_BLK_LAST_BLOCK))) { blk_flags |= SQFS_BLK_LAST_BLOCK; - if (add_sentinel_block(data, fi, blk_flags)) { + if (add_sentinel_block(data, inode, + blk_flags)) { free(blk); return -1; } @@ -382,25 +391,28 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, return -1; blk_flags &= ~SQFS_BLK_FIRST_BLOCK; + inode->num_file_blocks += 1; } } if (!(blk_flags & (SQFS_BLK_FIRST_BLOCK | SQFS_BLK_LAST_BLOCK))) { blk_flags |= SQFS_BLK_LAST_BLOCK; - if (add_sentinel_block(data, fi, blk_flags)) + if (add_sentinel_block(data, inode, blk_flags)) return -1; } - data->stats.bytes_read += fi->size; + sqfs_inode_make_basic(inode); + + data->stats.bytes_read += filesz; data->stats.file_count += 1; return 0; } -int write_data_from_file(data_writer_t *data, file_info_t *fi, +int write_data_from_file(data_writer_t *data, sqfs_inode_generic_t *inode, sqfs_file_t *file, int flags) { - return write_data_from_file_condensed(data, file, fi, NULL, flags); + return write_data_from_file_condensed(data, file, inode, NULL, flags); } data_writer_t *data_writer_create(sqfs_super_t *super, sqfs_compressor_t *cmp, diff --git a/lib/sqfshelper/serialize_fstree.c b/lib/sqfshelper/serialize_fstree.c index 61f9ae2..e012902 100644 --- a/lib/sqfshelper/serialize_fstree.c +++ b/lib/sqfshelper/serialize_fstree.c @@ -92,8 +92,7 @@ int sqfs_serialize_fstree(sqfs_file_t *file, sqfs_super_t *super, fstree_t *fs, inode = write_dir_entries(dirwr, fs->inode_table[i], idtbl); } else { - inode = tree_node_to_inode(fs, idtbl, - fs->inode_table[i]); + inode = tree_node_to_inode(idtbl, fs->inode_table[i]); } if (inode == NULL) diff --git a/lib/sqfshelper/tree_node_to_inode.c b/lib/sqfshelper/tree_node_to_inode.c index fa8c538..5cb04a4 100644 --- a/lib/sqfshelper/tree_node_to_inode.c +++ b/lib/sqfshelper/tree_node_to_inode.c @@ -39,69 +39,38 @@ static int get_type(tree_node_t *node) if (node->xattr != NULL) return SQFS_INODE_EXT_CDEV; return SQFS_INODE_CDEV; - case S_IFREG: { - file_info_t *fi = node->data.file; - - if (node->xattr != NULL || fi->sparse > 0) - return SQFS_INODE_EXT_FILE; - - if (fi->startblock > 0xFFFFFFFFUL || fi->size > 0xFFFFFFFFUL) - return SQFS_INODE_EXT_FILE; - - return SQFS_INODE_FILE; - } } assert(0); } -static bool has_fragment(const fstree_t *fs, const file_info_t *file) -{ - if (file->size % fs->block_size == 0) - return false; - - return file->fragment_offset < fs->block_size && - (file->fragment != 0xFFFFFFFF); -} - -sqfs_inode_generic_t *tree_node_to_inode(fstree_t *fs, sqfs_id_table_t *idtbl, +sqfs_inode_generic_t *tree_node_to_inode(sqfs_id_table_t *idtbl, tree_node_t *node) { - size_t i, extra = 0, block_count = 0; sqfs_inode_generic_t *inode; uint16_t uid_idx, gid_idx; uint32_t xattr = 0xFFFFFFFF; - file_info_t *fi = NULL; - - if (S_ISLNK(node->mode)) { - extra = strlen(node->data.slink_target); - } else if (S_ISREG(node->mode)) { - fi = node->data.file; - - block_count = fi->size / fs->block_size; - - if ((fi->size % fs->block_size) != 0 && !has_fragment(fs, fi)) - ++block_count; - - extra = block_count * sizeof(uint32_t); - } - - inode = alloc_flex(sizeof(*inode), 1, extra); - if (inode == NULL) { - perror("creating inode from file system tree node"); - return NULL; - } - - if (S_ISLNK(node->mode)) { - inode->slink_target = (char *)inode->extra; + size_t extra = 0; + + if (S_ISREG(node->mode)) { + inode = node->data.file->user_ptr; + node->data.file->user_ptr = NULL; + } else { + if (S_ISLNK(node->mode)) + extra = strlen(node->data.slink_target); + + inode = alloc_flex(sizeof(*inode), 1, extra); + if (inode == NULL) { + perror("creating inode from file system tree node"); + return NULL; + } - memcpy(inode->extra, node->data.slink_target, extra); - } else if (S_ISREG(node->mode)) { - inode->block_sizes = (uint32_t *)inode->extra; + if (S_ISLNK(node->mode)) { + inode->slink_target = (char *)inode->extra; - for (i = 0; i < block_count; ++i) { - inode->block_sizes[i] = - node->data.file->block_size[i]; + memcpy(inode->extra, node->data.slink_target, extra); } + + inode->base.type = get_type(node); } if (sqfs_id_table_id_to_index(idtbl, node->uid, &uid_idx)) @@ -113,7 +82,6 @@ sqfs_inode_generic_t *tree_node_to_inode(fstree_t *fs, sqfs_id_table_t *idtbl, if (node->xattr != NULL) xattr = node->xattr->index; - inode->base.type = get_type(node); inode->base.mode = node->mode; inode->base.uid_idx = uid_idx; inode->base.gid_idx = gid_idx; @@ -151,36 +119,17 @@ sqfs_inode_generic_t *tree_node_to_inode(fstree_t *fs, sqfs_id_table_t *idtbl, inode->data.dev_ext.xattr_idx = xattr; break; case SQFS_INODE_FILE: - inode->data.file.blocks_start = fi->startblock; - inode->data.file.fragment_index = 0xFFFFFFFF; - inode->data.file.fragment_offset = 0xFFFFFFFF; - inode->data.file.file_size = fi->size; - - if (has_fragment(fs, fi)) { - inode->data.file.fragment_index = fi->fragment; - inode->data.file.fragment_offset = fi->fragment_offset; + if (xattr != 0xFFFFFFFF) { + sqfs_inode_make_extended(inode); + inode->data.file_ext.xattr_idx = xattr; } break; case SQFS_INODE_EXT_FILE: - inode->data.file_ext.blocks_start = fi->startblock; - inode->data.file_ext.file_size = fi->size; - inode->data.file_ext.sparse = fi->sparse; - inode->data.file_ext.nlink = 1; - inode->data.file_ext.fragment_idx = 0xFFFFFFFF; - inode->data.file_ext.fragment_offset = 0xFFFFFFFF; - inode->data.file_ext.xattr_idx = xattr; - - if (has_fragment(fs, fi)) { - inode->data.file_ext.fragment_idx = fi->fragment; - inode->data.file_ext.fragment_offset = - fi->fragment_offset; - } break; default: goto fail; } - inode->num_file_blocks = block_count; return inode; fail: free(inode); diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index 9ebafc5..e67b517 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -30,6 +30,8 @@ static int restore_working_dir(options_t *opt) static int pack_files(data_writer_t *data, fstree_t *fs, options_t *opt) { + sqfs_inode_generic_t *inode; + size_t max_blk_count; sqfs_file_t *file; file_info_t *fi; int ret; @@ -41,6 +43,24 @@ static int pack_files(data_writer_t *data, fstree_t *fs, options_t *opt) if (!opt->quiet) printf("packing %s\n", fi->input_file); + max_blk_count = fi->size / fs->block_size; + if (fi->size % fs->block_size) + ++max_blk_count; + + inode = alloc_flex(sizeof(*inode), sizeof(uint32_t), + max_blk_count); + if (inode == NULL) { + perror("creating file inode"); + return -1; + } + + inode->block_sizes = (uint32_t *)inode->extra; + inode->base.type = SQFS_INODE_FILE; + sqfs_inode_set_file_size(inode, fi->size); + sqfs_inode_set_frag_location(inode, 0xFFFFFFFF, 0xFFFFFFFF); + + fi->user_ptr = inode; + file = sqfs_open_file(fi->input_file, SQFS_FILE_OPEN_READ_ONLY); if (file == NULL) { @@ -48,7 +68,7 @@ static int pack_files(data_writer_t *data, fstree_t *fs, options_t *opt) return -1; } - ret = write_data_from_file(data, fi, file, 0); + ret = write_data_from_file(data, inode, file, 0); file->destroy(file); if (ret) diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c index dd0f827..583511f 100644 --- a/tar/tar2sqfs.c +++ b/tar/tar2sqfs.c @@ -226,10 +226,29 @@ static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, data_writer_t *data) { const sqfs_sparse_map_t *it; + sqfs_inode_generic_t *inode; + size_t max_blk_count; sqfs_file_t *file; uint64_t sum; int ret; + max_blk_count = fi->size / block_size; + if (fi->size % block_size) + ++max_blk_count; + + inode = alloc_flex(sizeof(*inode), sizeof(uint32_t), max_blk_count); + if (inode == NULL) { + perror("creating file inode"); + return -1; + } + + inode->block_sizes = (uint32_t *)inode->extra; + inode->base.type = SQFS_INODE_FILE; + sqfs_inode_set_file_size(inode, fi->size); + sqfs_inode_set_frag_location(inode, 0xFFFFFFFF, 0xFFFFFFFF); + + fi->user_ptr = inode; + if (hdr->sparse != NULL) { for (sum = 0, it = hdr->sparse; it != NULL; it = it->next) sum += it->count; @@ -240,7 +259,7 @@ static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, return -1; } - ret = write_data_from_file_condensed(data, file, fi, + ret = write_data_from_file_condensed(data, file, inode, hdr->sparse, 0); file->destroy(file); if (ret) @@ -255,7 +274,7 @@ static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, return -1; } - ret = write_data_from_file(data, fi, file, 0); + ret = write_data_from_file(data, inode, file, 0); file->destroy(file); if (ret) -- cgit v1.2.3