diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2021-03-22 11:30:15 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2021-03-22 15:26:47 +0100 |
commit | 5aa0f30173ecf3b6538b9136cb4783fc19266288 (patch) | |
tree | e163429bb7ecf5c3cd343532e0fd60b5f1819d39 /lib/sqfs/block_processor/frontend.c | |
parent | c7056c1853b5defd5b933e651bf58dc94b4d3f8b (diff) |
Cleanup the block processor file structure
A cleaner separation between common code, frontend code and backend
code is made.
The "is this byte blob zero" function is moved out to libutil (with
test case and everything) with a more optimized implementation.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfs/block_processor/frontend.c')
-rw-r--r-- | lib/sqfs/block_processor/frontend.c | 254 |
1 files changed, 41 insertions, 213 deletions
diff --git a/lib/sqfs/block_processor/frontend.c b/lib/sqfs/block_processor/frontend.c index 8bd6cf2..ccf54c0 100644 --- a/lib/sqfs/block_processor/frontend.c +++ b/lib/sqfs/block_processor/frontend.c @@ -7,123 +7,46 @@ #define SQFS_BUILDING_DLL #include "internal.h" -static sqfs_block_t *get_new_block(sqfs_block_processor_t *proc) +static int get_new_block(sqfs_block_processor_t *proc, sqfs_block_t **out) { sqfs_block_t *blk; + while (proc->backlog >= proc->max_backlog) { + int ret = dequeue_block(proc); + if (ret != 0) + return ret; + } + if (proc->free_list != NULL) { blk = proc->free_list; proc->free_list = blk->next; } else { blk = malloc(sizeof(*blk) + proc->max_block_size); + if (blk == NULL) + return SQFS_ERROR_ALLOC; } - if (blk != NULL) - memset(blk, 0, sizeof(*blk)); - - return blk; + memset(blk, 0, sizeof(*blk)); + *out = blk; + return 0; } -static int dequeue_block(sqfs_block_processor_t *proc) +static int add_sentinel_block(sqfs_block_processor_t *proc) { - sqfs_block_t *blk, *fragblk, *it, *prev; - bool have_dequeued = false; - int status; -retry: - while (proc->io_queue != NULL) { - if (proc->io_queue->io_seq_num != proc->io_deq_seq_num) - break; - - blk = proc->io_queue; - proc->io_queue = blk->next; - proc->io_deq_seq_num += 1; - proc->backlog -= 1; - have_dequeued = true; - - status = process_completed_block(proc, blk); - if (status != 0) - return status; - } - - if (have_dequeued) - return 0; - - blk = proc->pool->dequeue(proc->pool); - - if (blk == NULL) { - status = proc->pool->get_status(proc->pool); - if (status == 0) - status = SQFS_ERROR_INTERNAL; - - return status; - } - - proc->backlog -= 1; - have_dequeued = true; - - if (blk->flags & SQFS_BLK_IS_FRAGMENT) { - fragblk = NULL; - status = process_completed_fragment(proc, blk, &fragblk); - - if (status != 0) { - free(fragblk); - return status; - } - - if (fragblk != NULL) { - fragblk->io_seq_num = proc->io_seq_num++; - - if (proc->pool->submit(proc->pool, fragblk) != 0) { - free(fragblk); - - if (status == 0) { - status = proc->pool-> - get_status(proc->pool); - - if (status == 0) - status = SQFS_ERROR_ALLOC; - } - - return status; - } - - proc->backlog += 1; - have_dequeued = false; - } - } else { - if (!(blk->flags & SQFS_BLK_FRAGMENT_BLOCK)) - blk->io_seq_num = proc->io_seq_num++; - - prev = NULL; - it = proc->io_queue; - - while (it != NULL) { - if (it->io_seq_num >= blk->io_seq_num) - break; - - prev = it; - it = it->next; - } - - if (prev == NULL) { - blk->next = proc->io_queue; - proc->io_queue = blk; - } else { - blk->next = prev->next; - prev->next = blk; - } + sqfs_block_t *blk; + int ret; - proc->backlog += 1; - have_dequeued = false; - } + ret = get_new_block(proc, &blk); + if (ret != 0) + return ret; - if (!have_dequeued) - goto retry; + blk->inode = proc->inode; + blk->flags = proc->blk_flags | SQFS_BLK_LAST_BLOCK; - return 0; + return enqueue_block(proc, blk); } -static int enqueue_block(sqfs_block_processor_t *proc, sqfs_block_t *blk) +int enqueue_block(sqfs_block_processor_t *proc, sqfs_block_t *blk) { int status; @@ -141,44 +64,6 @@ static int enqueue_block(sqfs_block_processor_t *proc, sqfs_block_t *blk) return 0; } -static int add_sentinel_block(sqfs_block_processor_t *proc) -{ - sqfs_block_t *blk; - int ret; - - if (proc->backlog == proc->max_backlog) { - ret = dequeue_block(proc); - if (ret != 0) - return ret; - } - - blk = get_new_block(proc); - if (blk == NULL) - return SQFS_ERROR_ALLOC; - - blk->inode = proc->inode; - blk->flags = proc->blk_flags | SQFS_BLK_LAST_BLOCK; - - return enqueue_block(proc, blk); -} - -static int flush_block(sqfs_block_processor_t *proc) -{ - sqfs_block_t *block; - int ret; - - if (proc->backlog == proc->max_backlog) { - ret = dequeue_block(proc); - if (ret != 0) - return ret; - } - - block = proc->blk_current; - proc->blk_current = NULL; - - return enqueue_block(proc, block); -} - int sqfs_block_processor_begin_file(sqfs_block_processor_t *proc, sqfs_inode_generic_t **inode, void *user, sqfs_u32 flags) @@ -224,9 +109,9 @@ int sqfs_block_processor_append(sqfs_block_processor_t *proc, const void *data, while (size > 0) { if (proc->blk_current == NULL) { - new = get_new_block(proc); - if (new == NULL) - return SQFS_ERROR_ALLOC; + err = get_new_block(proc, &new); + if (err != 0) + return err; proc->blk_current = new; proc->blk_current->flags = proc->blk_flags; @@ -239,7 +124,9 @@ int sqfs_block_processor_append(sqfs_block_processor_t *proc, const void *data, diff = proc->max_block_size - proc->blk_current->size; if (diff == 0) { - err = flush_block(proc); + err = enqueue_block(proc, proc->blk_current); + proc->blk_current = NULL; + if (err) return err; continue; @@ -258,9 +145,12 @@ int sqfs_block_processor_append(sqfs_block_processor_t *proc, const void *data, proc->stats.input_bytes_read += diff; } - if (proc->blk_current != NULL && - proc->blk_current->size == proc->max_block_size) { - return flush_block(proc); + if (proc->blk_current->size == proc->max_block_size) { + err = enqueue_block(proc, proc->blk_current); + proc->blk_current = NULL; + + if (err) + return err; } return 0; @@ -293,7 +183,9 @@ int sqfs_block_processor_end_file(sqfs_block_processor_t *proc) proc->blk_current->flags |= SQFS_BLK_IS_FRAGMENT; } - err = flush_block(proc); + err = enqueue_block(proc, proc->blk_current); + proc->blk_current = NULL; + if (err) return err; } @@ -321,78 +213,14 @@ int sqfs_block_processor_submit_block(sqfs_block_processor_t *proc, void *user, if (flags & ~SQFS_BLK_FLAGS_ALL) return SQFS_ERROR_UNSUPPORTED; - if (proc->backlog == proc->max_backlog) { - ret = dequeue_block(proc); - if (ret != 0) - return ret; - } - - blk = get_new_block(proc); - if (blk == NULL) - return SQFS_ERROR_ALLOC; + ret = get_new_block(proc, &blk); + if (ret != 0) + return ret; blk->flags = flags | BLK_FLAG_MANUAL_SUBMISSION; blk->user = user; blk->size = size; memcpy(blk->data, data, size); - ret = proc->pool->submit(proc->pool, blk); - if (ret != 0) - free(blk); - - proc->backlog += 1; - return ret; -} - -int sqfs_block_processor_sync(sqfs_block_processor_t *proc) -{ - int ret; - - while (proc->backlog > 0) { - ret = dequeue_block(proc); - if (ret != 0) - return ret; - } - - return 0; -} - -int sqfs_block_processor_finish(sqfs_block_processor_t *proc) -{ - sqfs_block_t *blk; - int status; - - status = sqfs_block_processor_sync(proc); - if (status != 0) - return status; - - if (proc->frag_block != NULL) { - blk = proc->frag_block; - blk->next = NULL; - proc->frag_block = NULL; - - blk->io_seq_num = proc->io_seq_num++; - - status = proc->pool->submit(proc->pool, blk); - if (status != 0) { - status = proc->pool->get_status(proc->pool); - - if (status == 0) - status = SQFS_ERROR_ALLOC; - - free(blk); - return status; - } - - proc->backlog += 1; - status = sqfs_block_processor_sync(proc); - } - - return status; -} - -const sqfs_block_processor_stats_t -*sqfs_block_processor_get_stats(const sqfs_block_processor_t *proc) -{ - return &proc->stats; + return enqueue_block(proc, blk); } |