aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfs/block_processor/backend.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfs/block_processor/backend.c')
-rw-r--r--lib/sqfs/block_processor/backend.c335
1 files changed, 0 insertions, 335 deletions
diff --git a/lib/sqfs/block_processor/backend.c b/lib/sqfs/block_processor/backend.c
deleted file mode 100644
index b443c9d..0000000
--- a/lib/sqfs/block_processor/backend.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/* SPDX-License-Identifier: LGPL-3.0-or-later */
-/*
- * backend.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#define SQFS_BUILDING_DLL
-#include "internal.h"
-
-static int set_block_size(sqfs_inode_generic_t **inode,
- sqfs_u32 index, sqfs_u32 size)
-{
- size_t min_size = (index + 1) * sizeof(sqfs_u32);
- size_t avail = (*inode)->payload_bytes_available;
- sqfs_inode_generic_t *new;
- size_t newsz;
-
- if (avail < min_size) {
- newsz = avail ? avail : (sizeof(sqfs_u32) * 4);
- while (newsz < min_size)
- newsz *= 2;
-
- if (SZ_ADD_OV(newsz, sizeof(**inode), &newsz))
- return SQFS_ERROR_OVERFLOW;
-
- if (sizeof(size_t) > sizeof(sqfs_u32)) {
- if ((newsz - sizeof(**inode)) > 0x0FFFFFFFFUL)
- return SQFS_ERROR_OVERFLOW;
- }
-
- new = realloc((*inode), newsz);
- if (new == NULL)
- return SQFS_ERROR_ALLOC;
-
- (*inode) = new;
- (*inode)->payload_bytes_available = newsz - sizeof(**inode);
- }
-
- (*inode)->extra[index] = size;
-
- if (min_size >= (*inode)->payload_bytes_used)
- (*inode)->payload_bytes_used = min_size;
-
- return 0;
-}
-
-static void release_old_block(sqfs_block_processor_t *proc, sqfs_block_t *blk)
-{
- blk->next = proc->free_list;
- proc->free_list = blk;
-
- proc->backlog -= 1;
-}
-
-static int process_completed_block(sqfs_block_processor_t *proc, sqfs_block_t *blk)
-{
- sqfs_u64 location;
- sqfs_u32 size;
- int err;
-
- if (blk->flags & SQFS_BLK_FRAGMENT_BLOCK) {
- sqfs_block_t *it = proc->fblk_in_flight, *prev = NULL;
-
- while (it != NULL && it->index != blk->index) {
- prev = it;
- it = it->next;
- }
-
- if (it != NULL) {
- if (prev == NULL) {
- proc->fblk_in_flight = it->next;
- } else {
- prev->next = it->next;
- }
- free(it);
- }
- }
-
- err = proc->wr->write_data_block(proc->wr, blk->user, blk->size,
- blk->checksum,
- blk->flags & ~BLK_FLAG_INTERNAL,
- blk->data, &location);
- if (err)
- goto out;
-
- proc->stats.output_bytes_generated += blk->size;
-
- if (blk->flags & SQFS_BLK_IS_SPARSE) {
- if (blk->inode != NULL) {
- sqfs_inode_make_extended(*(blk->inode));
- (*(blk->inode))->data.file_ext.sparse += blk->size;
-
- err = set_block_size(blk->inode, blk->index, 0);
- if (err)
- goto out;
- }
- proc->stats.sparse_block_count += 1;
- } else if (blk->size != 0) {
- size = blk->size;
- if (!(blk->flags & SQFS_BLK_IS_COMPRESSED))
- size |= 1 << 24;
-
- if (blk->flags & SQFS_BLK_FRAGMENT_BLOCK) {
- if (proc->frag_tbl != NULL) {
- err = sqfs_frag_table_set(proc->frag_tbl,
- blk->index, location,
- size);
- if (err)
- goto out;
- }
- proc->stats.frag_block_count += 1;
- } else {
- if (blk->inode != NULL) {
- err = set_block_size(blk->inode, blk->index,
- size);
- if (err)
- goto out;
- }
- proc->stats.data_block_count += 1;
- }
- }
-
- if (blk->flags & SQFS_BLK_LAST_BLOCK && blk->inode != NULL)
- sqfs_inode_set_file_block_start(*(blk->inode), location);
-out:
- release_old_block(proc, blk);
- return err;
-}
-
-static int process_completed_fragment(sqfs_block_processor_t *proc,
- sqfs_block_t *frag)
-{
- chunk_info_t *chunk = NULL, search;
- struct hash_entry *entry;
- sqfs_u32 index, offset;
- int err;
-
- if (frag->flags & SQFS_BLK_IS_SPARSE) {
- if (frag->inode != NULL) {
- sqfs_inode_make_extended(*(frag->inode));
- set_block_size(frag->inode, frag->index, 0);
- (*(frag->inode))->data.file_ext.sparse += frag->size;
- }
- proc->stats.sparse_block_count += 1;
- release_old_block(proc, frag);
- return 0;
- }
-
- proc->stats.total_frag_count += 1;
-
- if (!(frag->flags & SQFS_BLK_DONT_DEDUPLICATE)) {
- search.hash = frag->checksum;
- search.size = frag->size;
-
- proc->current_frag = frag;
- proc->fblk_lookup_error = 0;
- entry = hash_table_search_pre_hashed(proc->frag_ht,
- search.hash, &search);
- proc->current_frag = NULL;
-
- if (proc->fblk_lookup_error != 0) {
- err = proc->fblk_lookup_error;
- goto fail;
- }
-
- if (entry != NULL) {
- if (frag->inode != NULL) {
- chunk = entry->data;
- sqfs_inode_set_frag_location(*(frag->inode),
- chunk->index,
- chunk->offset);
- }
- release_old_block(proc, frag);
- return 0;
- }
- }
-
- if (proc->frag_block != NULL) {
- size_t size = proc->frag_block->size + frag->size;
-
- if (size > proc->max_block_size) {
- proc->frag_block->io_seq_num = proc->io_seq_num++;
-
- err = enqueue_block(proc, proc->frag_block);
- proc->frag_block = NULL;
-
- if (err)
- goto fail;
- }
- }
-
- if (proc->frag_block == NULL) {
- if (proc->frag_tbl == NULL) {
- index = 0;
- } else {
- err = sqfs_frag_table_append(proc->frag_tbl,
- 0, 0, &index);
- if (err)
- goto fail;
- }
-
- offset = 0;
- proc->frag_block = frag;
- proc->frag_block->index = index;
- proc->frag_block->flags &=
- (SQFS_BLK_DONT_COMPRESS | SQFS_BLK_ALIGN);
- proc->frag_block->flags |= SQFS_BLK_FRAGMENT_BLOCK;
- } else {
- index = proc->frag_block->index;
- offset = proc->frag_block->size;
-
- 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 | SQFS_BLK_ALIGN));
- }
-
- if (proc->frag_tbl != NULL) {
- err = SQFS_ERROR_ALLOC;
- chunk = calloc(1, sizeof(*chunk));
- if (chunk == NULL)
- goto fail;
-
- chunk->index = index;
- chunk->offset = offset;
- chunk->size = frag->size;
- chunk->hash = frag->checksum;
-
- proc->current_frag = frag;
- proc->fblk_lookup_error = 0;
- entry = hash_table_insert_pre_hashed(proc->frag_ht, chunk->hash,
- chunk, chunk);
- proc->current_frag = NULL;
-
- if (proc->fblk_lookup_error != 0) {
- err = proc->fblk_lookup_error;
- goto fail;
- }
-
- if (entry == NULL)
- goto fail;
- }
-
- if (frag->inode != NULL)
- sqfs_inode_set_frag_location(*(frag->inode), index, offset);
-
- if (frag != proc->frag_block)
- release_old_block(proc, frag);
-
- proc->stats.actual_frag_count += 1;
- return 0;
-fail:
- free(chunk);
- if (frag != proc->frag_block)
- release_old_block(proc, frag);
- return err;
-}
-
-static void store_io_block(sqfs_block_processor_t *proc, sqfs_block_t *blk)
-{
- sqfs_block_t *prev = NULL, *it = proc->io_queue;
-
- while (it != NULL && (it->io_seq_num < blk->io_seq_num)) {
- prev = it;
- it = it->next;
- }
-
- if (prev == NULL) {
- proc->io_queue = blk;
- } else {
- prev->next = blk;
- }
-
- blk->next = it;
-}
-
-int dequeue_block(sqfs_block_processor_t *proc)
-{
- size_t backlog_old = proc->backlog;
- sqfs_block_t *blk;
- int status;
-
- do {
- 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;
-
- status = process_completed_block(proc, blk);
- if (status != 0)
- return status;
- }
-
- if (proc->backlog < backlog_old)
- break;
-
- if ((proc->backlog == 1) &&
- (proc->frag_block != NULL || proc->blk_current != NULL)) {
- break;
- }
-
- if ((proc->backlog == 2) &&
- proc->frag_block != NULL && proc->blk_current != NULL) {
- break;
- }
-
- blk = proc->pool->dequeue(proc->pool);
-
- if (blk == NULL) {
- status = proc->pool->get_status(proc->pool);
- return status ? status : SQFS_ERROR_INTERNAL;
- }
-
- if (blk->flags & SQFS_BLK_IS_FRAGMENT) {
- status = process_completed_fragment(proc, blk);
- if (status != 0)
- return status;
- } else {
- if (!(blk->flags & SQFS_BLK_FRAGMENT_BLOCK) ||
- (blk->flags & BLK_FLAG_MANUAL_SUBMISSION)) {
- blk->io_seq_num = proc->io_seq_num++;
- }
-
- store_io_block(proc, blk);
- }
- } while (proc->backlog >= backlog_old);
-
- return 0;
-}