summaryrefslogtreecommitdiff
path: root/lib/sqfs/block_processor/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfs/block_processor/common.c')
-rw-r--r--lib/sqfs/block_processor/common.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/lib/sqfs/block_processor/common.c b/lib/sqfs/block_processor/common.c
index b8f2760..c3363f9 100644
--- a/lib/sqfs/block_processor/common.c
+++ b/lib/sqfs/block_processor/common.c
@@ -63,6 +63,18 @@ static sqfs_block_t *get_new_block(sqfs_block_processor_t *proc)
static void release_old_block(sqfs_block_processor_t *proc, sqfs_block_t *blk)
{
+ sqfs_block_t *it;
+
+ if (blk->flags & SQFS_BLK_FRAGMENT_BLOCK && blk->frag_list != NULL) {
+ it = blk->frag_list;
+
+ while (it->next != NULL)
+ it = it->next;
+
+ it->next = proc->free_list;
+ proc->free_list = blk->frag_list;
+ }
+
blk->next = proc->free_list;
proc->free_list = blk;
}
@@ -120,11 +132,29 @@ static bool is_zero_block(unsigned char *ptr, size_t size)
int block_processor_do_block(sqfs_block_t *block, sqfs_compressor_t *cmp,
sqfs_u8 *scratch, size_t scratch_size)
{
+ sqfs_block_t *it;
+ size_t offset;
sqfs_s32 ret;
if (block->size == 0)
return 0;
+ if (block->flags & SQFS_BLK_FRAGMENT_BLOCK) {
+ offset = block->size;
+
+ for (it = block->frag_list; it != NULL; it = it->next) {
+ assert(offset >= it->size);
+ offset -= it->size;
+
+ memcpy(block->data + offset, it->data, it->size);
+
+ block->flags |= (it->flags & SQFS_BLK_DONT_COMPRESS);
+
+ sqfs_inode_set_frag_location(*(it->inode),
+ block->index, offset);
+ }
+ }
+
if (is_zero_block(block->data, block->size)) {
block->flags |= SQFS_BLK_IS_SPARSE;
return 0;
@@ -211,17 +241,11 @@ int process_completed_fragment(sqfs_block_processor_t *proc, sqfs_block_t *frag,
if (err)
goto fail;
- sqfs_inode_set_frag_location(*(frag->inode), proc->frag_block->index,
- proc->frag_block->size);
+ frag->next = proc->frag_block->frag_list;
+ proc->frag_block->frag_list = frag;
- memcpy(proc->frag_block->data + proc->frag_block->size,
- frag->data, frag->size);
-
- proc->frag_block->flags |= (frag->flags & SQFS_BLK_DONT_COMPRESS);
proc->frag_block->size += frag->size;
proc->stats.actual_frag_count += 1;
-
- release_old_block(proc, frag);
return 0;
fail:
release_old_block(proc, frag);