summaryrefslogtreecommitdiff
path: root/lib/sqfs/block_processor/frontend.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfs/block_processor/frontend.c')
-rw-r--r--lib/sqfs/block_processor/frontend.c254
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);
}