summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/data_writer.h4
-rw-r--r--include/fstree.h2
-rw-r--r--include/highlevel.h2
-rw-r--r--lib/sqfshelper/data_writer.c58
-rw-r--r--lib/sqfshelper/serialize_fstree.c3
-rw-r--r--lib/sqfshelper/tree_node_to_inode.c97
-rw-r--r--mkfs/mkfs.c22
-rw-r--r--tar/tar2sqfs.c23
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)