From cdccc69c62579b0c13b35fad0728079652b8f3c9 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Tue, 31 Jan 2023 11:21:30 +0100 Subject: Move library source into src sub-directory Signed-off-by: David Oberhollenzer --- lib/sqfs/block_writer.c | 238 ------------------------------------------------ 1 file changed, 238 deletions(-) delete mode 100644 lib/sqfs/block_writer.c (limited to 'lib/sqfs/block_writer.c') diff --git a/lib/sqfs/block_writer.c b/lib/sqfs/block_writer.c deleted file mode 100644 index a5135bc..0000000 --- a/lib/sqfs/block_writer.c +++ /dev/null @@ -1,238 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * block_writer.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#define SQFS_BUILDING_DLL -#include "config.h" - -#include "sqfs/block_writer.h" -#include "sqfs/error.h" -#include "sqfs/block.h" -#include "sqfs/io.h" - -#include "util/array.h" -#include "util/util.h" - -#include -#include - -#define MK_BLK_HASH(chksum, size) \ - (((sqfs_u64)(size) << 32) | (sqfs_u64)(chksum)) - -#define SIZE_FROM_HASH(hash) ((hash >> 32) & ((1 << 24) - 1)) - -#define INIT_BLOCK_COUNT (128) -#define SCRATCH_SIZE (8192) - -typedef struct { - sqfs_u64 offset; - sqfs_u64 hash; -} blk_info_t; - -typedef struct { - sqfs_block_writer_t base; - sqfs_file_t *file; - - array_t blocks; - size_t devblksz; - - size_t file_start; - - sqfs_u32 flags; - - sqfs_u8 scratch[]; -} block_writer_default_t; - -static int store_block_location(block_writer_default_t *wr, sqfs_u64 offset, - sqfs_u32 size, sqfs_u32 chksum) -{ - blk_info_t info = { offset, MK_BLK_HASH(chksum, size) }; - - return array_append(&(wr->blocks), &info); -} - -static int deduplicate_blocks(block_writer_default_t *wr, sqfs_u32 flags, sqfs_u64 *out) -{ - const blk_info_t *blocks = wr->blocks.data; - sqfs_u64 loc_a, loc_b, sz; - size_t i, j, count; - int ret; - - count = wr->blocks.used - wr->file_start; - if (count == 0) { - *out = 0; - return 0; - } - - if (flags & SQFS_BLK_DONT_DEDUPLICATE) { - *out = blocks[wr->file_start].offset; - return 0; - } - - sz = 0; - loc_a = blocks[wr->file_start].offset; - - for (i = 0; i < count; ++i) - sz += SIZE_FROM_HASH(blocks[wr->file_start + i].hash); - - for (i = 0; i < wr->file_start; ++i) { - for (j = 0; j < count; ++j) { - if (blocks[i + j].hash == 0) - break; - - if (blocks[i + j].hash != - blocks[wr->file_start + j].hash) - break; - } - - if (j != count) - continue; - - if (wr->flags & SQFS_BLOCK_WRITER_HASH_COMPARE_ONLY) - break; - - loc_b = blocks[i].offset; - - ret = check_file_range_equal(wr->file, wr->scratch, - SCRATCH_SIZE, loc_a, loc_b, sz); - if (ret == 0) - break; - if (ret < 0) - return ret; - } - - *out = blocks[i].offset; - if (i >= wr->file_start) - return 0; - - if (count >= (wr->file_start - i)) { - wr->blocks.used = i + count; - } else { - wr->blocks.used = wr->file_start; - } - - sz = blocks[wr->blocks.used - 1].offset + - SIZE_FROM_HASH(blocks[wr->blocks.used - 1].hash); - - return wr->file->truncate(wr->file, sz); -} - -static int align_file(block_writer_default_t *wr, sqfs_u32 flags) -{ - void *padding; - sqfs_u64 size; - size_t diff; - int ret; - - if (!(flags & SQFS_BLK_ALIGN)) - return 0; - - size = wr->file->get_size(wr->file); - diff = size % wr->devblksz; - if (diff == 0) - return 0; - - padding = calloc(1, diff); - if (padding == 0) - return SQFS_ERROR_ALLOC; - - ret = wr->file->write_at(wr->file, size, padding, diff); - free(padding); - if (ret) - return ret; - - return store_block_location(wr, size, 0, 0); -} - -static void block_writer_destroy(sqfs_object_t *wr) -{ - sqfs_drop(((block_writer_default_t *)wr)->file); - array_cleanup(&(((block_writer_default_t *)wr)->blocks)); - free(wr); -} - -static int write_data_block(sqfs_block_writer_t *base, void *user, - sqfs_u32 size, sqfs_u32 checksum, sqfs_u32 flags, - const sqfs_u8 *data, sqfs_u64 *location) -{ - block_writer_default_t *wr = (block_writer_default_t *)base; - int err; - (void)user; - - if (flags & (SQFS_BLK_FIRST_BLOCK | SQFS_BLK_FRAGMENT_BLOCK)) { - err = align_file(wr, flags); - if (err) - return err; - - if (flags & SQFS_BLK_FIRST_BLOCK) - wr->file_start = wr->blocks.used; - } - - *location = wr->file->get_size(wr->file); - - if (size != 0 && !(flags & SQFS_BLK_IS_SPARSE)) { - sqfs_u32 out = size; - if (!(flags & SQFS_BLK_IS_COMPRESSED)) - out |= 1 << 24; - - err = store_block_location(wr, *location, out, checksum); - if (err) - return err; - - err = wr->file->write_at(wr->file, *location, data, size); - if (err) - return err; - } - - if (flags & (SQFS_BLK_LAST_BLOCK | SQFS_BLK_FRAGMENT_BLOCK)) { - err = align_file(wr, flags); - if (err) - return err; - - if (flags & SQFS_BLK_LAST_BLOCK) - return deduplicate_blocks(wr, flags, location); - } - - return 0; -} - -static sqfs_u64 get_block_count(const sqfs_block_writer_t *wr) -{ - return ((const block_writer_default_t *)wr)->blocks.used; -} - -sqfs_block_writer_t *sqfs_block_writer_create(sqfs_file_t *file, - size_t devblksz, sqfs_u32 flags) -{ - block_writer_default_t *wr; - - if (flags & ~SQFS_BLOCK_WRITER_ALL_FLAGS) - return NULL; - - if (flags & SQFS_BLOCK_WRITER_HASH_COMPARE_ONLY) { - wr = calloc(1, sizeof(*wr)); - } else { - wr = alloc_flex(sizeof(*wr), 1, SCRATCH_SIZE); - } - - if (wr == NULL) - return NULL; - - sqfs_object_init(wr, block_writer_destroy, NULL); - - ((sqfs_block_writer_t *)wr)->write_data_block = write_data_block; - ((sqfs_block_writer_t *)wr)->get_block_count = get_block_count; - wr->flags = flags; - wr->file = sqfs_grab(file); - wr->devblksz = devblksz; - - if (array_init(&(wr->blocks), sizeof(blk_info_t), INIT_BLOCK_COUNT)) { - sqfs_drop(wr->file); - free(wr); - return NULL; - } - - return (sqfs_block_writer_t *)wr; -} -- cgit v1.2.3