diff options
Diffstat (limited to 'lib/sqfs/block_processor/common.c')
-rw-r--r-- | lib/sqfs/block_processor/common.c | 40 |
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); |