From 8e52ed282e16cc0cc984d077377cd79d0f10308d Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 16 Feb 2020 00:00:40 +0100 Subject: block processor: move sparse block detection into worker thread Signed-off-by: David Oberhollenzer --- lib/sqfs/block_processor/common.c | 44 +++++++++++++++++++++++++++----------- lib/sqfs/block_processor/fileapi.c | 11 ++-------- lib/sqfs/block_processor/serial.c | 38 ++++++++++++++++---------------- lib/sqfs/block_writer.c | 35 +++++++++++++++++------------- 4 files changed, 71 insertions(+), 57 deletions(-) (limited to 'lib') diff --git a/lib/sqfs/block_processor/common.c b/lib/sqfs/block_processor/common.c index 002dad4..3859916 100644 --- a/lib/sqfs/block_processor/common.c +++ b/lib/sqfs/block_processor/common.c @@ -13,6 +13,11 @@ int process_completed_block(sqfs_block_processor_t *proc, sqfs_block_t *blk) sqfs_u32 size; int err; + err = sqfs_block_writer_write(proc->wr, blk->size, blk->checksum, + blk->flags, blk->data, &location); + if (err) + return err; + if (blk->flags & SQFS_BLK_IS_SPARSE) { sqfs_inode_make_extended(blk->inode); blk->inode->data.file_ext.sparse += blk->size; @@ -20,19 +25,11 @@ int process_completed_block(sqfs_block_processor_t *proc, sqfs_block_t *blk) blk->inode->num_file_blocks += 1; proc->stats.sparse_block_count += 1; - return 0; - } - - size = blk->size; - if (!(blk->flags & SQFS_BLK_IS_COMPRESSED)) - size |= 1 << 24; - - err = sqfs_block_writer_write(proc->wr, blk->size, blk->checksum, - blk->flags, blk->data, &location); - if (err) - return err; + } else if (blk->size != 0) { + size = blk->size; + if (!(blk->flags & SQFS_BLK_IS_COMPRESSED)) + size |= 1 << 24; - if (blk->size != 0) { if (blk->flags & SQFS_BLK_FRAGMENT_BLOCK) { err = sqfs_frag_table_set(proc->frag_tbl, blk->index, location, size); @@ -52,12 +49,23 @@ int process_completed_block(sqfs_block_processor_t *proc, sqfs_block_t *blk) return 0; } +static bool is_zero_block(unsigned char *ptr, size_t size) +{ + return ptr[0] == 0 && memcmp(ptr, ptr + 1, size - 1) == 0; +} + int block_processor_do_block(sqfs_block_t *block, sqfs_compressor_t *cmp, sqfs_u8 *scratch, size_t scratch_size) { ssize_t ret; - if (block->size == 0 || (block->flags & SQFS_BLK_IS_SPARSE)) { + if (block->size == 0) { + block->checksum = 0; + return 0; + } + + if (is_zero_block(block->data, block->size)) { + block->flags |= SQFS_BLK_IS_SPARSE; block->checksum = 0; return 0; } @@ -90,6 +98,16 @@ int process_completed_fragment(sqfs_block_processor_t *proc, sqfs_block_t *frag, size_t size; int err; + if (frag->flags & SQFS_BLK_IS_SPARSE) { + sqfs_inode_make_extended(frag->inode); + frag->inode->data.file_ext.sparse += frag->size; + frag->inode->extra[frag->inode->num_file_blocks] = 0; + frag->inode->num_file_blocks += 1; + + proc->stats.sparse_block_count += 1; + return 0; + } + proc->stats.total_frag_count += 1; err = sqfs_frag_table_find_tail_end(proc->frag_tbl, diff --git a/lib/sqfs/block_processor/fileapi.c b/lib/sqfs/block_processor/fileapi.c index 7ca189e..abaf3d2 100644 --- a/lib/sqfs/block_processor/fileapi.c +++ b/lib/sqfs/block_processor/fileapi.c @@ -7,11 +7,6 @@ #define SQFS_BUILDING_DLL #include "internal.h" -static bool is_zero_block(unsigned char *ptr, size_t size) -{ - return ptr[0] == 0 && memcmp(ptr, ptr + 1, size - 1) == 0; -} - static int enqueue_block(sqfs_block_processor_t *proc, sqfs_block_t *block) { int status; @@ -58,10 +53,8 @@ static int flush_block(sqfs_block_processor_t *proc, sqfs_block_t *block) block->flags = proc->blk_flags; block->inode = proc->inode; - if (is_zero_block(block->data, block->size)) { - block->flags |= SQFS_BLK_IS_SPARSE; - } else if (block->size < proc->max_block_size && - !(block->flags & SQFS_BLK_DONT_FRAGMENT)) { + if (block->size < proc->max_block_size && + !(block->flags & SQFS_BLK_DONT_FRAGMENT)) { block->flags |= SQFS_BLK_IS_FRAGMENT; } else { proc->blk_flags &= ~SQFS_BLK_FIRST_BLOCK; diff --git a/lib/sqfs/block_processor/serial.c b/lib/sqfs/block_processor/serial.c index c9ee164..1d2c2db 100644 --- a/lib/sqfs/block_processor/serial.c +++ b/lib/sqfs/block_processor/serial.c @@ -43,35 +43,33 @@ int append_to_work_queue(sqfs_block_processor_t *proc, sqfs_block_t *block) { sqfs_block_t *fragblk = NULL; - if (proc->status != 0 || block == NULL) { - free(block); - return proc->status; - } + if (proc->status != 0) + goto done; - if (block->flags & SQFS_BLK_IS_FRAGMENT) { - block->checksum = crc32(0, block->data, block->size); + proc->status = block_processor_do_block(block, proc->cmp, + proc->scratch, + proc->max_block_size); + if (proc->status != 0) + goto done; + if (block->flags & SQFS_BLK_IS_FRAGMENT) { proc->status = process_completed_fragment(proc, block, &fragblk); - free(block); - - if (proc->status != 0) { - free(fragblk); - return proc->status; - } - if (fragblk == NULL) - return 0; + goto done; + free(block); block = fragblk; - } - - proc->status = block_processor_do_block(block, proc->cmp, proc->scratch, - proc->max_block_size); - if (proc->status == 0) - proc->status = process_completed_block(proc, block); + proc->status = block_processor_do_block(block, proc->cmp, + proc->scratch, + proc->max_block_size); + if (proc->status != 0) + goto done; + } + proc->status = process_completed_block(proc, block); +done: free(block); return proc->status; } diff --git a/lib/sqfs/block_writer.c b/lib/sqfs/block_writer.c index 63f8c61..73dcb14 100644 --- a/lib/sqfs/block_writer.c +++ b/lib/sqfs/block_writer.c @@ -191,14 +191,14 @@ int sqfs_block_writer_write(sqfs_block_writer_t *wr, sqfs_u32 size, } } - if (size != 0) { + offset = wr->file->get_size(wr->file); + *location = offset; + + if (size != 0 && !(flags & SQFS_BLK_IS_SPARSE)) { out = size; if (!(flags & SQFS_BLK_IS_COMPRESSED)) out |= 1 << 24; - offset = wr->file->get_size(wr->file); - *location = offset; - err = store_block_location(wr, offset, out, checksum); if (err) return err; @@ -226,19 +226,24 @@ int sqfs_block_writer_write(sqfs_block_writer_t *wr, sqfs_u32 size, } count = wr->num_blocks - wr->file_start; - start = deduplicate_blocks(wr, count); - offset = wr->blocks[start].offset; - - *location = offset; - if (start >= wr->file_start) - return 0; - offset = start + count; - if (offset >= wr->file_start) { - count = wr->num_blocks - offset; - wr->num_blocks = offset; + if (count == 0) { + *location = 0; } else { - wr->num_blocks = wr->file_start; + start = deduplicate_blocks(wr, count); + offset = wr->blocks[start].offset; + + *location = offset; + if (start >= wr->file_start) + return 0; + + offset = start + count; + if (offset >= wr->file_start) { + count = wr->num_blocks - offset; + wr->num_blocks = offset; + } else { + wr->num_blocks = wr->file_start; + } } err = wr->file->truncate(wr->file, wr->start); -- cgit v1.2.3