Skip to content

Commit

Permalink
file_iterator: use static buffer for zero pages.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gottox committed Jul 17, 2023
1 parent 3829587 commit b160c65
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 38 deletions.
12 changes: 0 additions & 12 deletions include/sqsh_archive_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ struct SqshArchive {
uint8_t initialized;
struct SqshConfig config;
sqsh_mutex_t lock;
uint8_t *zero_block;
};

/**
Expand Down Expand Up @@ -275,17 +274,6 @@ int sqsh__archive_metablock_extract_manager(
struct SqshArchive *archive,
struct SqshExtractManager **metablock_extract_manager);

/**
* @internal
* @memberof SqshArchive
*
* @brief sqsh__archive_id_table retrieves a zero block.
*
* @param archive the SqshArchive to retrieve the zero block from.
* @return the zero block.
*/
const uint8_t *sqsh__archive_zero_block(const struct SqshArchive *archive);

/**
* @internal
* @memberof SqshArchive
Expand Down
14 changes: 0 additions & 14 deletions lib/archive/archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,6 @@ sqsh__archive_init(
goto out;
}

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

enum SqshSuperblockCompressionId compression_id =
sqsh_superblock_compression_id(&archive->superblock);
uint32_t data_block_size = sqsh_superblock_block_size(&archive->superblock);
Expand Down Expand Up @@ -372,11 +365,6 @@ sqsh_archive_xattr_table(
return rv;
}

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

struct SqshMapManager *
sqsh_archive_map_manager(struct SqshArchive *archive) {
return &archive->map_manager;
Expand Down Expand Up @@ -412,8 +400,6 @@ sqsh__archive_cleanup(struct SqshArchive *archive) {
sqsh__superblock_cleanup(&archive->superblock);
sqsh__map_manager_cleanup(&archive->map_manager);

free(archive->zero_block);

sqsh_mutex_destroy(&archive->lock);

return rv;
Expand Down
10 changes: 5 additions & 5 deletions lib/file/file_iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@

#define BLOCK_INDEX_FINISHED UINT32_MAX

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

int
sqsh__file_iterator_init(
struct SqshFileIterator *iterator, const struct SqshInode *inode) {
Expand Down Expand Up @@ -183,8 +185,6 @@ map_block_uncompressed(
static int
map_zero_block(struct SqshFileIterator *iterator) {
const struct SqshInode *inode = iterator->inode;
struct SqshArchive *archive = inode->archive;
const uint8_t *zero_block = sqsh__archive_zero_block(archive);

const sqsh_index_t block_index = iterator->block_index;
const bool has_fragment = sqsh_inode_file_has_fragment(inode);
Expand All @@ -196,7 +196,8 @@ map_zero_block(struct SqshFileIterator *iterator) {
if (file_size == 0) {
size = 0;
} else if (sparse_size > 0) {
size = sparse_size;
size = SQSH_MIN(sizeof(ZERO_BLOCK), sparse_size);
iterator->sparse_size -= size;
} else if (has_fragment || block_index != block_count - 1) {
size = iterator->block_size;
} else {
Expand All @@ -207,8 +208,7 @@ map_zero_block(struct SqshFileIterator *iterator) {
}

iterator->size = size;
iterator->data = zero_block;
iterator->sparse_size = 0;
iterator->data = ZERO_BLOCK;

return size;
}
Expand Down
84 changes: 79 additions & 5 deletions test/file/file_iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
#include "../../include/sqsh_inode_private.h"
#include "../../lib/utils/utils.h"

static const size_t BLOCK_SIZE = 32768;
static const size_t ZERO_PAGE_SIZE = 16384;

static void
load_segment_from_compressed_data_block(void) {
int rv;
Expand Down Expand Up @@ -105,7 +108,7 @@ load_two_segments_from_uncompressed_data_block(void) {
/* inode */
[INODE_TABLE_OFFSET] = METABLOCK_HEADER(0, 128),
INODE_HEADER(2, 0, 0, 0, 0, 1),
INODE_BASIC_FILE(8192, 0xFFFFFFFF, 0, 4096 + 5),
INODE_BASIC_FILE(8192, 0xFFFFFFFF, 0, BLOCK_SIZE + 5),
DATA_BLOCK_REF(1000, 0),
DATA_BLOCK_REF(5, 0),
/* datablocks */
Expand Down Expand Up @@ -140,9 +143,19 @@ load_two_segments_from_uncompressed_data_block(void) {
assert(rv > 0);

size = sqsh_file_iterator_size(&iter);
assert(size == 4096 - 1000);
assert(size == ZERO_PAGE_SIZE);
data = sqsh_file_iterator_data(&iter);
for (size_t i = 0; i < size; i++) {
for (size_t i = 0; i < ZERO_PAGE_SIZE; i++) {
assert(data[i] == 0);
}

rv = sqsh_file_iterator_next(&iter, 1);
assert(rv > 0);

size = sqsh_file_iterator_size(&iter);
assert(size == ZERO_PAGE_SIZE - 1000);
data = sqsh_file_iterator_data(&iter);
for (size_t i = 0; i < ZERO_PAGE_SIZE - 1000; i++) {
assert(data[i] == 0);
}

Expand Down Expand Up @@ -237,7 +250,67 @@ load_zero_padding(void) {
/* inode */
[INODE_TABLE_OFFSET] = METABLOCK_HEADER(0, 128),
INODE_HEADER(2, 0, 0, 0, 0, 1),
INODE_BASIC_FILE(512, 0xFFFFFFFF, 0, 4096 + 5),
INODE_BASIC_FILE(512, 0xFFFFFFFF, 0, BLOCK_SIZE + 5),
DATA_BLOCK_REF(0, 1),
DATA_BLOCK_REF(0, 1),
/* clang-format on */
};
mk_stub(&archive, payload, sizeof(payload));

uint64_t inode_ref = sqsh_address_ref_create(0, 0);
rv = sqsh__inode_init(&inode, &archive, inode_ref);
assert(rv == 0);

assert(sqsh_inode_type(&inode) == SQSH_INODE_TYPE_FILE);
assert(sqsh_inode_file_has_fragment(&inode) == false);

struct SqshFileIterator iter = {0};
rv = sqsh__file_iterator_init(&iter, &inode);
assert(rv == 0);

rv = sqsh_file_iterator_next(&iter, 1);
assert(rv > 0);

size_t size = sqsh_file_iterator_size(&iter);
assert(size == BLOCK_SIZE);

rv = sqsh_file_iterator_next(&iter, 1);
assert(rv > 0);

size = sqsh_file_iterator_size(&iter);
assert(size == 5);
const uint8_t *data = sqsh_file_iterator_data(&iter);
assert(data[0] == 0);
assert(data[1] == 0);
assert(data[2] == 0);
assert(data[3] == 0);
assert(data[4] == 0);

rv = sqsh_file_iterator_next(&iter, 1);
assert(rv == 0);

size = sqsh_file_iterator_size(&iter);
assert(size == 0);
data = sqsh_file_iterator_data(&iter);
assert(data == NULL);

sqsh__file_iterator_cleanup(&iter);
sqsh__inode_cleanup(&inode);
sqsh__archive_cleanup(&archive);
}

static void
load_zero_big_padding(void) {
int rv;
struct SqshArchive archive = {0};
struct SqshInode inode = {0};
uint8_t payload[8192] = {
/* clang-format off */
SQSH_HEADER,
/* inode */
[INODE_TABLE_OFFSET] = METABLOCK_HEADER(0, 128),
INODE_HEADER(2, 0, 0, 0, 0, 1),
INODE_BASIC_FILE(512, 0xFFFFFFFF, 0, BLOCK_SIZE + 5),
DATA_BLOCK_REF(0, 1),
DATA_BLOCK_REF(0, 1),
/* clang-format on */
Expand All @@ -259,7 +332,7 @@ load_zero_padding(void) {
assert(rv > 0);

size_t size = sqsh_file_iterator_size(&iter);
assert(size == 4096);
assert(size == BLOCK_SIZE);

rv = sqsh_file_iterator_next(&iter, 1);
assert(rv > 0);
Expand Down Expand Up @@ -291,4 +364,5 @@ TEST(load_two_segments_from_uncompressed_data_block);
TEST(load_segment_from_uncompressed_data_block);
TEST(load_segment_from_compressed_data_block);
TEST(load_zero_padding);
TEST(load_zero_big_padding);
DEFINE_END
4 changes: 2 additions & 2 deletions test/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ mk_stub(struct SqshArchive *sqsh, uint8_t *payload, size_t payload_size) {
/* modification_time */
UINT32_BYTES(0),
/* block_size */
UINT32_BYTES(4096),
UINT32_BYTES(32768),
/* fragment_entry_count */
UINT32_BYTES(0),
/* compression_id */
UINT16_BYTES(SQSH_COMPRESSION_GZIP),
/* block_log */
UINT16_BYTES(12),
UINT16_BYTES(15),
/* flags */
UINT16_BYTES(0),
/* id_count */
Expand Down

0 comments on commit b160c65

Please sign in to comment.