summaryrefslogtreecommitdiff
path: root/lib/sqfshelper/data_writer.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfshelper/data_writer.c')
-rw-r--r--lib/sqfshelper/data_writer.c134
1 files changed, 2 insertions, 132 deletions
diff --git a/lib/sqfshelper/data_writer.c b/lib/sqfshelper/data_writer.c
index 5bce527..9f9631b 100644
--- a/lib/sqfshelper/data_writer.c
+++ b/lib/sqfshelper/data_writer.c
@@ -18,128 +18,14 @@
#include <errno.h>
#include <zlib.h>
-#define MK_BLK_SIG(chksum, size) \
- (((uint64_t)(size) << 32) | (uint64_t)(chksum))
-
-#define BLK_SIZE(sig) ((sig) >> 32)
-
-#define INIT_BLOCK_COUNT (128)
-
-typedef struct {
- uint32_t index;
- uint32_t offset;
- uint64_t signature;
-} frag_info_t;
-
struct data_writer_t {
- sqfs_block_t *frag_block;
- size_t num_fragments;
-
sqfs_block_processor_t *proc;
sqfs_compressor_t *cmp;
sqfs_super_t *super;
- size_t frag_list_num;
- size_t frag_list_max;
- frag_info_t *frag_list;
-
data_writer_stats_t stats;
};
-static int flush_fragment_block(data_writer_t *data)
-{
- int ret;
-
- ret = sqfs_block_processor_enqueue(data->proc, data->frag_block);
- data->frag_block = NULL;
- return ret;
-}
-
-static int store_fragment(data_writer_t *data, sqfs_block_t *frag,
- uint64_t signature)
-{
- size_t new_sz;
- void *new;
-
- if (data->frag_list_num == data->frag_list_max) {
- new_sz = data->frag_list_max * 2;
- new = realloc(data->frag_list,
- sizeof(data->frag_list[0]) * new_sz);
-
- if (new == NULL) {
- perror("growing fragment checksum table");
- return -1;
- }
-
- data->frag_list = new;
- data->frag_list_max = new_sz;
- }
-
- data->frag_list[data->frag_list_num].index = data->frag_block->index;
- data->frag_list[data->frag_list_num].offset = data->frag_block->size;
- data->frag_list[data->frag_list_num].signature = signature;
- data->frag_list_num += 1;
-
- sqfs_inode_set_frag_location(frag->inode, data->frag_block->index,
- data->frag_block->size);
-
- memcpy(data->frag_block->data + data->frag_block->size,
- frag->data, frag->size);
-
- data->frag_block->flags |= (frag->flags & SQFS_BLK_DONT_COMPRESS);
- data->frag_block->size += frag->size;
- return 0;
-}
-
-static int handle_fragment(data_writer_t *data, sqfs_block_t *frag)
-{
- uint64_t signature;
- size_t i, size;
-
- signature = MK_BLK_SIG(frag->checksum, frag->size);
-
- for (i = 0; i < data->frag_list_num; ++i) {
- if (data->frag_list[i].signature == signature) {
- sqfs_inode_set_frag_location(frag->inode,
- data->frag_list[i].index,
- data->frag_list[i].offset);
- free(frag);
- return 0;
- }
- }
-
- if (data->frag_block != NULL) {
- size = data->frag_block->size + frag->size;
-
- if (size > data->super->block_size) {
- if (flush_fragment_block(data))
- goto fail;
- }
- }
-
- if (data->frag_block == NULL) {
- size = sizeof(sqfs_block_t) + data->super->block_size;
-
- data->frag_block = calloc(1, size);
- if (data->frag_block == NULL) {
- perror("creating fragment block");
- goto fail;
- }
-
- data->frag_block->index = data->num_fragments++;
- data->frag_block->flags = SQFS_BLK_FRAGMENT_BLOCK;
- }
-
- if (store_fragment(data, frag, signature))
- goto fail;
-
- free(frag);
- return 0;
-fail:
- free(frag);
- return -1;
-}
-
static bool is_zero_block(unsigned char *ptr, size_t size)
{
return ptr[0] == 0 && memcmp(ptr, ptr + 1, size - 1) == 0;
@@ -225,9 +111,9 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file,
}
}
- blk->checksum = crc32(0, blk->data, blk->size);
+ blk->flags |= SQFS_BLK_IS_FRAGMENT;
- if (handle_fragment(data, blk))
+ if (sqfs_block_processor_enqueue(data->proc, blk))
return -1;
} else {
if (sqfs_block_processor_enqueue(data->proc, blk))
@@ -269,21 +155,11 @@ data_writer_t *data_writer_create(sqfs_super_t *super, sqfs_compressor_t *cmp,
return NULL;
}
- data->frag_list_max = INIT_BLOCK_COUNT;
- data->frag_list = alloc_array(sizeof(data->frag_list[0]),
- data->frag_list_max);
- if (data->frag_list == NULL) {
- perror("creating data writer");
- free(data);
- return NULL;
- }
-
data->proc = sqfs_block_processor_create(super->block_size, cmp,
num_jobs, max_backlog,
devblksize, file);
if (data->proc == NULL) {
perror("creating data block processor");
- free(data->frag_list);
free(data);
return NULL;
}
@@ -296,7 +172,6 @@ data_writer_t *data_writer_create(sqfs_super_t *super, sqfs_compressor_t *cmp,
void data_writer_destroy(data_writer_t *data)
{
sqfs_block_processor_destroy(data->proc);
- free(data->frag_list);
free(data);
}
@@ -312,11 +187,6 @@ int data_writer_write_fragment_table(data_writer_t *data)
int data_writer_sync(data_writer_t *data)
{
- if (data->frag_block != NULL) {
- if (flush_fragment_block(data))
- return -1;
- }
-
return sqfs_block_processor_finish(data->proc);
}