From 8db9823b63d82196b204cb969752eff6adb15756 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Thu, 14 Jan 2021 04:40:36 +0100 Subject: Fix: Move fragment consolidation back to block processor serial part Keeping a list of fragments stored away in the current fragment block and consolidating them in the thread pool takes them out of circulation. If we have a lot of tiny fragments, this can lead to a situation where all the limit is reached, but we cannot do anything, because we are waiting for a block to complete, but they are all attached to the current fragment block and the queue is empty. Signed-off-by: David Oberhollenzer --- lib/sqfs/block_processor/common.c | 35 +++++------------------------------ lib/sqfs/block_processor/internal.h | 4 ---- lib/sqfs/block_processor/serial.c | 12 ------------ 3 files changed, 5 insertions(+), 46 deletions(-) diff --git a/lib/sqfs/block_processor/common.c b/lib/sqfs/block_processor/common.c index 9c80502..b2657e6 100644 --- a/lib/sqfs/block_processor/common.c +++ b/lib/sqfs/block_processor/common.c @@ -46,18 +46,6 @@ static int set_block_size(sqfs_inode_generic_t **inode, 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; } @@ -128,26 +116,11 @@ static bool is_zero_block(unsigned char *ptr, size_t size) static int process_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); - } - } - if (!(block->flags & SQFS_BLK_IGNORE_SPARSE) && is_zero_block(block->data, block->size)) { block->flags |= SQFS_BLK_IS_SPARSE; @@ -241,15 +214,17 @@ static int process_completed_fragment(sqfs_block_processor_t *proc, proc->frag_block->index = index; proc->frag_block->flags &= SQFS_BLK_DONT_COMPRESS; proc->frag_block->flags |= SQFS_BLK_FRAGMENT_BLOCK; - proc->frag_block->frag_list = NULL; } else { index = proc->frag_block->index; offset = 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->size += frag->size; + proc->frag_block->flags |= + (frag->flags & SQFS_BLK_DONT_COMPRESS); + release_old_block(proc, frag); } if (proc->frag_tbl != NULL) { diff --git a/lib/sqfs/block_processor/internal.h b/lib/sqfs/block_processor/internal.h index 0c4f2b3..ee76946 100644 --- a/lib/sqfs/block_processor/internal.h +++ b/lib/sqfs/block_processor/internal.h @@ -53,10 +53,6 @@ typedef struct sqfs_block_t { For fragment fragment blocks: fragment table index. */ sqfs_u32 index; - /* For fragment blocks: list of fragments to - consolidate in reverse order. */ - struct sqfs_block_t *frag_list; - /* User data pointer */ void *user; diff --git a/lib/sqfs/block_processor/serial.c b/lib/sqfs/block_processor/serial.c index f56f3cb..4d6b3ec 100644 --- a/lib/sqfs/block_processor/serial.c +++ b/lib/sqfs/block_processor/serial.c @@ -13,17 +13,6 @@ typedef struct { sqfs_u8 scratch[]; } serial_block_processor_t; -static void free_block_list(sqfs_block_t *list) -{ - sqfs_block_t *blk; - - while (list != NULL) { - blk = list; - list = blk->next; - free(blk); - } -} - static void block_processor_destroy(sqfs_object_t *obj) { sqfs_block_processor_t *proc = (sqfs_block_processor_t *)obj; @@ -63,7 +52,6 @@ static int append_to_work_queue(sqfs_block_processor_t *proc, sproc->status = proc->process_completed_block(proc, block); return sproc->status; fail: - free_block_list(block->frag_list); free(block); return sproc->status; } -- cgit v1.2.3