Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

file_iterator: dynamically allocate zero block #166

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions libsqsh/include/sqsh_archive_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ struct SqshArchive {
uint8_t initialized;
struct SqshConfig config;
sqsh__mutex_t lock;
uint8_t *zero_block;
};

/**
Expand Down Expand Up @@ -270,6 +271,30 @@ SQSH_NO_EXPORT int sqsh__archive_data_extract_manager(
SQSH_NO_EXPORT struct SqshExtractManager *
sqsh__archive_metablock_extract_manager(struct SqshArchive *archive);

/**
* @internal
* @memberof SqshArchive
* @brief Returns a 16k block of zeros.
*
* @param archive the SqshArchive to retrieve the zero block from
*
* @return the SqshExtractManager.
*/
SQSH_NO_EXPORT const uint8_t *
sqsh__archive_zero_block(const struct SqshArchive *archive);

/**
* @internal
* @memberof SqshArchive
* @brief Returns a 16k block of zeros.
*
* @param archive the SqshArchive to retrieve the zero block from
*
* @return the SqshExtractManager.
*/
SQSH_NO_EXPORT size_t
sqsh__archive_zero_block_size(const struct SqshArchive *archive);

/**
* @internal
* @memberof SqshArchive
Expand Down
20 changes: 20 additions & 0 deletions libsqsh/src/archive/archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <string.h>

static const uint64_t NO_SEGMENT = 0xFFFFFFFFFFFFFFFF;
static const size_t ZERO_BLOCK_SIZE = 16384;

enum InitializedBitmap {
INITIALIZED_ID_TABLE = 1 << 0,
Expand Down Expand Up @@ -112,6 +113,12 @@ sqsh__archive_init(
memset(&archive->config, 0, sizeof(struct SqshConfig));
}

archive->zero_block = calloc(ZERO_BLOCK_SIZE, sizeof(uint8_t));
if (archive->zero_block == NULL) {
rv = -SQSH_ERROR_MALLOC_FAILED;
goto out;
}

/* RECURSIVE is needed because: inode_map may access the export_table
* during initialization. */
rv = sqsh__mutex_init_recursive(&archive->lock);
Expand Down Expand Up @@ -346,6 +353,17 @@ sqsh_archive_map_manager(struct SqshArchive *archive) {
return &archive->map_manager;
}

const uint8_t *
sqsh__archive_zero_block(const struct SqshArchive *archive) {
return archive->zero_block;
}

size_t
sqsh__archive_zero_block_size(const struct SqshArchive *archive) {
(void)archive;
return ZERO_BLOCK_SIZE;
}

int
sqsh__archive_cleanup(struct SqshArchive *archive) {
int rv = 0;
Expand Down Expand Up @@ -374,6 +392,8 @@ sqsh__archive_cleanup(struct SqshArchive *archive) {

sqsh__mutex_destroy(&archive->lock);

free(archive->zero_block);

return rv;
}

Expand Down
12 changes: 7 additions & 5 deletions libsqsh/src/file/file_iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@

#define BLOCK_INDEX_FINISHED UINT32_MAX

static const uint8_t ZERO_BLOCK[16384] = {0};

static bool
is_last_block(const struct SqshFileIterator *iterator) {
const struct SqshFile *file = iterator->file;
Expand Down Expand Up @@ -188,15 +186,19 @@ map_block_uncompressed(

static int
map_zero_block(struct SqshFileIterator *iterator) {
const struct SqshFile *file = iterator->file;
const struct SqshArchive *archive = file->archive;
const size_t zero_block_size = sqsh__archive_zero_block_size(archive);

size_t current_sparse_size = iterator->sparse_size;

if (current_sparse_size > sizeof(ZERO_BLOCK)) {
current_sparse_size = sizeof(ZERO_BLOCK);
if (current_sparse_size > zero_block_size) {
current_sparse_size = zero_block_size;
}
iterator->sparse_size -= current_sparse_size;

iterator->size = current_sparse_size;
iterator->data = ZERO_BLOCK;
iterator->data = sqsh__archive_zero_block(archive);

return current_sparse_size;
}
Expand Down