From 4a091b656c0861e3f9335c38af25040cb3ff03c8 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 19 Jan 2020 20:05:13 +0100 Subject: Cleanup: remove the payload pointers from sqfs_inode_generic_t There are 3 types of extra payload: - Directory index - File block sizes - Symlink target This commit removes the type specific pointers and modifies the code to use the payload area directly. To simplify the file block case and mitigate alignment issues, the type of the extra field is changed to sqfs_u32. For symlink target, the extra field can simply be cast to a character pointer (it had to be cast anyway for most uses). For block sizes, probably the most common usecase, it can be used as is. For directory indices, there is a helper function anyway. Signed-off-by: David Oberhollenzer --- difftool/node_compare.c | 3 ++- extras/browse.c | 14 +++++++------- extras/list_files.c | 4 ++-- extras/mk42sqfs.c | 5 ++--- extras/mknastyfs.c | 3 +-- include/sqfs/inode.h | 24 ++++++------------------ lib/common/data_reader_dump.c | 3 +-- lib/common/serialize_fstree.c | 1 - lib/sqfs/data_reader.c | 15 ++++++--------- lib/sqfs/data_writer/block.c | 2 +- lib/sqfs/data_writer/fileapi.c | 2 +- lib/sqfs/dir_writer.c | 3 ++- lib/sqfs/inode.c | 3 --- lib/sqfs/read_inode.c | 19 +++++++------------ lib/sqfs/write_inode.c | 9 +++++---- mkfs/mkfs.c | 1 - tar/sqfs2tar.c | 2 +- tar/tar2sqfs.c | 1 - unpack/describe.c | 3 ++- unpack/list_files.c | 7 ++++--- unpack/restore_fstree.c | 4 ++-- 21 files changed, 52 insertions(+), 76 deletions(-) diff --git a/difftool/node_compare.c b/difftool/node_compare.c index d9ccf34..59d1831 100644 --- a/difftool/node_compare.c +++ b/difftool/node_compare.c @@ -150,7 +150,8 @@ int node_compare(sqfsdiff_t *sd, sqfs_tree_node_t *a, sqfs_tree_node_t *b) break; case SQFS_INODE_SLINK: case SQFS_INODE_EXT_SLINK: - if (strcmp(a->inode->slink_target, b->inode->slink_target)) { + if (strcmp((const char *)a->inode->extra, + (const char *)b->inode->extra)) { fprintf(stdout, "%s has a different link target\n", path); } diff --git a/extras/browse.c b/extras/browse.c index 1d6417f..1cd2cf1 100644 --- a/extras/browse.c +++ b/extras/browse.c @@ -293,13 +293,13 @@ static void stat_cmd(const char *filename) case SQFS_INODE_SLINK: printf("Hard link count: %u\n", inode->data.slink.nlink); printf("Link target: %.*s\n", inode->data.slink.target_size, - inode->slink_target); + (const char *)inode->extra); break; case SQFS_INODE_EXT_SLINK: printf("Hard link count: %u\n", inode->data.slink_ext.nlink); printf("Xattr index: 0x%X\n", inode->data.slink_ext.xattr_idx); - printf("Link target: %.*s\n", - inode->data.slink_ext.target_size, inode->slink_target); + printf("Link target: %.*s\n", inode->data.slink_ext.target_size, + (const char *)inode->extra); break; case SQFS_INODE_FILE: printf("Blocks start: %u\n", inode->data.file.blocks_start); @@ -313,8 +313,8 @@ static void stat_cmd(const char *filename) for (i = 0; i < inode->num_file_blocks; ++i) { printf("\tBlock #%lu size: %u (%s)\n", (unsigned long)i, - inode->block_sizes[i] & 0x00FFFFFF, - inode->block_sizes[i] & (1 << 24) ? + inode->extra[i] & 0x00FFFFFF, + inode->extra[i] & (1 << 24) ? "uncompressed" : "compressed"); } break; @@ -334,8 +334,8 @@ static void stat_cmd(const char *filename) for (i = 0; i < inode->num_file_blocks; ++i) { printf("\tBlock #%lu size: %u (%s)\n", (unsigned long)i, - inode->block_sizes[i] & 0x00FFFFFF, - inode->block_sizes[i] & (1 << 24) ? + inode->extra[i] & 0x00FFFFFF, + inode->extra[i] & (1 << 24) ? "compressed" : "uncompressed"); } break; diff --git a/extras/list_files.c b/extras/list_files.c index 3f6725a..16fe360 100644 --- a/extras/list_files.c +++ b/extras/list_files.c @@ -34,10 +34,10 @@ static void write_tree_dfs(const sqfs_tree_node_t *n) if (n->inode->base.type == SQFS_INODE_SLINK) { printf(" ⭢ %.*s", n->inode->data.slink.target_size, - n->inode->slink_target); + (const char *)n->inode->extra); } else if (n->inode->base.type == SQFS_INODE_EXT_SLINK) { printf(" ⭢ %.*s", n->inode->data.slink_ext.target_size, - n->inode->slink_target); + (const char *)n->inode->extra); } fputc('\n', stdout); diff --git a/extras/mk42sqfs.c b/extras/mk42sqfs.c index 25c9047..1c55bf1 100644 --- a/extras/mk42sqfs.c +++ b/extras/mk42sqfs.c @@ -42,8 +42,7 @@ static sqfs_inode_generic_t *create_file_inode(sqfs_id_table_t *idtbl, inode->data.file.fragment_index = 0xFFFFFFFF; inode->num_file_blocks = 1; - inode->block_sizes = (sqfs_u32 *)inode->extra; - inode->block_sizes[0] = (1 << 24) | inode->data.file.file_size; + inode->extra[0] = (1 << 24) | inode->data.file.file_size; return inode; } @@ -144,7 +143,7 @@ int main(void) inode = create_file_inode(idtbl, inode_num++); inode->data.file.blocks_start = sizeof(super); inode->data.file.file_size = strlen(README); - inode->block_sizes[0] = (1 << 24) | inode->data.file.file_size; + inode->extra[0] = (1 << 24) | inode->data.file.file_size; sqfs_meta_writer_get_position(inode_m, &block_start, &offset); sqfs_meta_writer_write_inode(inode_m, inode); diff --git a/extras/mknastyfs.c b/extras/mknastyfs.c index 823bcf8..216c7eb 100644 --- a/extras/mknastyfs.c +++ b/extras/mknastyfs.c @@ -38,8 +38,7 @@ static sqfs_inode_generic_t *create_file_inode(sqfs_id_table_t *idtbl, inode->data.file.fragment_index = 0xFFFFFFFF; inode->num_file_blocks = 1; - inode->block_sizes = (sqfs_u32 *)inode->extra; - inode->block_sizes[0] = (1 << 24) | inode->data.file.file_size; + inode->extra[0] = (1 << 24) | inode->data.file.file_size; return inode; } diff --git a/include/sqfs/inode.h b/include/sqfs/inode.h index 65ff45e..17df022 100644 --- a/include/sqfs/inode.h +++ b/include/sqfs/inode.h @@ -482,23 +482,6 @@ struct sqfs_inode_generic_t { */ sqfs_inode_t base; - /** - * @brief A pointer into the extra field holding the symlink target. - * - * @param This string is not null terminated. The helper functions rely - * entirely on the length stored in the symlink inode. - */ - char *slink_target; - - /** - * @brief A pointer into the extra field holding file blocks sizes. - * - * For file inodes, holds the consecutive block sizes. Bit number 24 is - * set if the block is stored uncompressed. If it the size is zero, - * the block is sparse. - */ - sqfs_u32 *block_sizes; - /** * @brief For file inodes, stores the number of blocks used. */ @@ -528,8 +511,13 @@ struct sqfs_inode_generic_t { /** * @brief Holds type specific extra data, such as symlink target. + * + * For regular file inodes, this is an array of block sizes. For symlink + * inodes, this is actually a string holding the target. For extended + * directory inodes, this is actually a blob of tightly packed directory + * index entries. */ - sqfs_u8 extra[]; + sqfs_u32 extra[]; }; #ifdef __cplusplus diff --git a/lib/common/data_reader_dump.c b/lib/common/data_reader_dump.c index 96103ce..bf418c6 100644 --- a/lib/common/data_reader_dump.c +++ b/lib/common/data_reader_dump.c @@ -60,8 +60,7 @@ int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data, for (i = 0; i < inode->num_file_blocks; ++i) { diff = (filesz < block_size) ? filesz : block_size; - if (SQFS_IS_SPARSE_BLOCK(inode->block_sizes[i]) && - allow_sparse) { + if (SQFS_IS_SPARSE_BLOCK(inode->extra[i]) && allow_sparse) { if (fseek(fp, diff, SEEK_CUR) < 0) goto fail_sparse; } else { diff --git a/lib/common/serialize_fstree.c b/lib/common/serialize_fstree.c index f20ae07..c69f0ea 100644 --- a/lib/common/serialize_fstree.c +++ b/lib/common/serialize_fstree.c @@ -38,7 +38,6 @@ static sqfs_inode_generic_t *tree_node_to_inode(tree_node_t *node) inode->base.type = SQFS_INODE_SLINK; inode->data.slink.nlink = node->link_count; inode->data.slink.target_size = extra; - inode->slink_target = (char *)inode->extra; memcpy(inode->extra, node->data.target, extra); break; case S_IFBLK: diff --git a/lib/sqfs/data_reader.c b/lib/sqfs/data_reader.c index 6a0db35..af15b9b 100644 --- a/lib/sqfs/data_reader.c +++ b/lib/sqfs/data_reader.c @@ -219,14 +219,13 @@ int sqfs_data_reader_get_block(sqfs_data_reader_t *data, return SQFS_ERROR_OUT_OF_BOUNDS; for (i = 0; i < index; ++i) { - off += SQFS_ON_DISK_BLOCK_SIZE(inode->block_sizes[i]); + off += SQFS_ON_DISK_BLOCK_SIZE(inode->extra[i]); filesz -= data->block_size; } unpacked_size = filesz < data->block_size ? filesz : data->block_size; - return get_block(data, off, inode->block_sizes[index], - unpacked_size, out); + return get_block(data, off, inode->extra[index], unpacked_size, out); } int sqfs_data_reader_get_fragment(sqfs_data_reader_t *data, @@ -285,7 +284,7 @@ sqfs_s32 sqfs_data_reader_read(sqfs_data_reader_t *data, i = 0; while (offset > data->block_size && i < inode->num_file_blocks) { - off += SQFS_ON_DISK_BLOCK_SIZE(inode->block_sizes[i++]); + off += SQFS_ON_DISK_BLOCK_SIZE(inode->extra[i++]); offset -= data->block_size; if (filesz >= data->block_size) { @@ -301,17 +300,15 @@ sqfs_s32 sqfs_data_reader_read(sqfs_data_reader_t *data, if (size < diff) diff = size; - if (SQFS_IS_SPARSE_BLOCK(inode->block_sizes[i])) { + if (SQFS_IS_SPARSE_BLOCK(inode->extra[i])) { memset(buffer, 0, diff); } else { - if (precache_data_block(data, off, - inode->block_sizes[i])) { + if (precache_data_block(data, off, inode->extra[i])) return -1; - } memcpy(buffer, (char *)data->data_block->data + offset, diff); - off += SQFS_ON_DISK_BLOCK_SIZE(inode->block_sizes[i]); + off += SQFS_ON_DISK_BLOCK_SIZE(inode->extra[i]); } if (filesz >= data->block_size) { diff --git a/lib/sqfs/data_writer/block.c b/lib/sqfs/data_writer/block.c index 9396e4a..5967e59 100644 --- a/lib/sqfs/data_writer/block.c +++ b/lib/sqfs/data_writer/block.c @@ -116,7 +116,7 @@ int process_completed_block(sqfs_data_writer_t *proc, sqfs_block_t *blk) proc->fragments[blk->index].pad0 = 0; proc->fragments[blk->index].size = htole32(out); } else { - blk->inode->block_sizes[blk->index] = out; + blk->inode->extra[blk->index] = out; } err = store_block_location(proc, offset, out, blk->checksum); diff --git a/lib/sqfs/data_writer/fileapi.c b/lib/sqfs/data_writer/fileapi.c index de77690..89bac0b 100644 --- a/lib/sqfs/data_writer/fileapi.c +++ b/lib/sqfs/data_writer/fileapi.c @@ -67,7 +67,7 @@ static int flush_block(sqfs_data_writer_t *proc, sqfs_block_t *block) sqfs_inode_make_extended(proc->inode); proc->inode->data.file_ext.sparse += block->size; proc->inode->num_file_blocks += 1; - proc->inode->block_sizes[block->index] = 0; + proc->inode->extra[block->index] = 0; free(block); return 0; } diff --git a/lib/sqfs/dir_writer.c b/lib/sqfs/dir_writer.c index 78256a1..53e5800 100644 --- a/lib/sqfs/dir_writer.c +++ b/lib/sqfs/dir_writer.c @@ -419,7 +419,8 @@ sqfs_inode_generic_t ent.index = idx->index; ent.size = idx->ent->name_len - 1; - ptr = inode->extra + inode->num_dir_idx_bytes; + ptr = (sqfs_u8 *)inode->extra + + inode->num_dir_idx_bytes; memcpy(ptr, &ent, sizeof(ent)); memcpy(ptr + sizeof(ent), idx->ent->name, idx->ent->name_len); diff --git a/lib/sqfs/inode.c b/lib/sqfs/inode.c index 3a4ec09..815cc0f 100644 --- a/lib/sqfs/inode.c +++ b/lib/sqfs/inode.c @@ -72,9 +72,6 @@ int sqfs_inode_copy(const sqfs_inode_generic_t *src, return SQFS_ERROR_ALLOC; memcpy(copy, src, size); - copy->block_sizes = (sqfs_u32 *)copy->extra; - copy->slink_target = (char *)copy->extra; - *out = copy; return 0; } diff --git a/lib/sqfs/read_inode.c b/lib/sqfs/read_inode.c index f7bfff0..8653928 100644 --- a/lib/sqfs/read_inode.c +++ b/lib/sqfs/read_inode.c @@ -101,18 +101,16 @@ static int read_inode_file(sqfs_meta_reader_t *ir, sqfs_inode_t *base, out->base = *base; out->data.file = file; - out->block_sizes = (sqfs_u32 *)out->extra; out->num_file_blocks = count; - err = sqfs_meta_reader_read(ir, out->block_sizes, - count * sizeof(sqfs_u32)); + err = sqfs_meta_reader_read(ir, out->extra, count * sizeof(sqfs_u32)); if (err) { free(out); return err; } for (i = 0; i < count; ++i) - SWAB32(out->block_sizes[i]); + SWAB32(out->extra[i]); *result = out; return 0; @@ -149,18 +147,16 @@ static int read_inode_file_ext(sqfs_meta_reader_t *ir, sqfs_inode_t *base, out->base = *base; out->data.file_ext = file; - out->block_sizes = (sqfs_u32 *)out->extra; out->num_file_blocks = count; - err = sqfs_meta_reader_read(ir, out->block_sizes, - count * sizeof(sqfs_u32)); + err = sqfs_meta_reader_read(ir, out->extra, count * sizeof(sqfs_u32)); if (err) { free(out); return err; } for (i = 0; i < count; ++i) - SWAB32(out->block_sizes[i]); + SWAB32(out->extra[i]); *result = out; return 0; @@ -190,11 +186,10 @@ static int read_inode_slink(sqfs_meta_reader_t *ir, sqfs_inode_t *base, if (out == NULL) return SQFS_ERROR_ALLOC; - out->slink_target = (char *)out->extra; out->base = *base; out->data.slink = slink; - err = sqfs_meta_reader_read(ir, out->slink_target, slink.target_size); + err = sqfs_meta_reader_read(ir, (void *)out->extra, slink.target_size); if (err) { free(out); return err; @@ -290,10 +285,10 @@ static int read_inode_dir_ext(sqfs_meta_reader_t *ir, sqfs_inode_t *base, index_max = new_sz; } - memcpy(out->extra + index_used, &ent, sizeof(ent)); + memcpy((char *)out->extra + index_used, &ent, sizeof(ent)); index_used += sizeof(ent); - err = sqfs_meta_reader_read(ir, out->extra + index_used, + err = sqfs_meta_reader_read(ir, (char *)out->extra + index_used, ent.size + 1); if (err) { free(out); diff --git a/lib/sqfs/write_inode.c b/lib/sqfs/write_inode.c index 5f0ef4c..b5ba905 100644 --- a/lib/sqfs/write_inode.c +++ b/lib/sqfs/write_inode.c @@ -22,7 +22,7 @@ static int write_block_sizes(sqfs_meta_writer_t *ir, size_t i; for (i = 0; i < n->num_file_blocks; ++i) - sizes[i] = htole32(n->block_sizes[i]); + sizes[i] = htole32(n->extra[i]); return sqfs_meta_writer_append(ir, sizes, sizeof(sqfs_u32) * n->num_file_blocks); @@ -112,7 +112,7 @@ int sqfs_meta_writer_write_inode(sqfs_meta_writer_t *ir, ret = sqfs_meta_writer_append(ir, &slink, sizeof(slink)); if (ret) return ret; - return sqfs_meta_writer_append(ir, n->slink_target, + return sqfs_meta_writer_append(ir, n->extra, n->data.slink.target_size); } case SQFS_INODE_BDEV: @@ -143,7 +143,8 @@ int sqfs_meta_writer_write_inode(sqfs_meta_writer_t *ir, ret = sqfs_meta_writer_append(ir, &dir, sizeof(dir)); if (ret) return ret; - return write_dir_index(ir, n->extra, n->num_dir_idx_bytes); + return write_dir_index(ir, (const sqfs_u8 *)n->extra, + n->num_dir_idx_bytes); } case SQFS_INODE_EXT_FILE: { sqfs_inode_file_ext_t file = { @@ -171,7 +172,7 @@ int sqfs_meta_writer_write_inode(sqfs_meta_writer_t *ir, ret = sqfs_meta_writer_append(ir, &slink, sizeof(slink)); if (ret) return ret; - ret = sqfs_meta_writer_append(ir, n->slink_target, + ret = sqfs_meta_writer_append(ir, n->extra, n->data.slink_ext.target_size); if (ret) return ret; diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index 213fb36..b5d3443 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -109,7 +109,6 @@ static int pack_files(sqfs_data_writer_t *data, fstree_t *fs, return -1; } - inode->block_sizes = (sqfs_u32 *)inode->extra; inode->base.type = SQFS_INODE_FILE; sqfs_inode_set_file_size(inode, filesize); sqfs_inode_set_frag_location(inode, 0xFFFFFFFF, 0xFFFFFFFF); diff --git a/tar/sqfs2tar.c b/tar/sqfs2tar.c index 4d31fbe..935b687 100644 --- a/tar/sqfs2tar.c +++ b/tar/sqfs2tar.c @@ -414,7 +414,7 @@ static int write_tree_dfs(const sqfs_tree_node_t *n) } } - target = S_ISLNK(sb.st_mode) ? n->inode->slink_target : NULL; + target = S_ISLNK(sb.st_mode) ? (char *)n->inode->extra : NULL; ret = write_tar_header(out_file, &sb, name, target, xattr, record_counter++); diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c index 12055c3..b180739 100644 --- a/tar/tar2sqfs.c +++ b/tar/tar2sqfs.c @@ -275,7 +275,6 @@ static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, return -1; } - inode->block_sizes = (sqfs_u32 *)inode->extra; inode->base.type = SQFS_INODE_FILE; sqfs_inode_set_file_size(inode, filesize); sqfs_inode_set_frag_location(inode, 0xFFFFFFFF, 0xFFFFFFFF); diff --git a/unpack/describe.c b/unpack/describe.c index 4c35070..d30f844 100644 --- a/unpack/describe.c +++ b/unpack/describe.c @@ -74,7 +74,8 @@ int describe_tree(const sqfs_tree_node_t *root, const char *unpack_root) case S_IFSOCK: return print_simple("sock", root, NULL); case S_IFLNK: - return print_simple("slink", root, root->inode->slink_target); + return print_simple("slink", root, + (const char *)root->inode->extra); case S_IFIFO: return print_simple("pipe", root, NULL); case S_IFREG: diff --git a/unpack/list_files.c b/unpack/list_files.c index 0d64010..c08c2dd 100644 --- a/unpack/list_files.c +++ b/unpack/list_files.c @@ -85,7 +85,7 @@ static void print_node_size(const sqfs_tree_node_t *n, char *buffer) { switch (n->inode->base.mode & S_IFMT) { case S_IFLNK: - print_size(strlen(n->inode->slink_target), buffer); + print_size(strlen((const char *)n->inode->extra), buffer); break; case S_IFREG: { sqfs_u64 size; @@ -151,7 +151,8 @@ void list_files(const sqfs_tree_node_t *node) n->name); if (S_ISLNK(n->inode->base.mode)) { - printf(" -> %s\n", n->inode->slink_target); + printf(" -> %s\n", + (const char *)n->inode->extra); } else { fputc('\n', stdout); } @@ -164,7 +165,7 @@ void list_files(const sqfs_tree_node_t *node) node->uid, node->gid, sizestr, node->name); if (S_ISLNK(node->inode->base.mode)) { - printf(" -> %s\n", node->inode->slink_target); + printf(" -> %s\n", (const char *)node->inode->extra); } else { fputc('\n', stdout); } diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c index 00d75ef..8f99439 100644 --- a/unpack/restore_fstree.c +++ b/unpack/restore_fstree.c @@ -57,9 +57,9 @@ static int create_node(const sqfs_tree_node_t *n, const char *name) } break; case S_IFLNK: - if (symlink(n->inode->slink_target, name)) { + if (symlink((const char *)n->inode->extra, name)) { fprintf(stderr, "ln -s %s %s: %s\n", - n->inode->slink_target, name, + (const char *)n->inode->extra, name, strerror(errno)); return -1; } -- cgit v1.2.3