Skip to content

Commit

Permalink
mapper: add a file mapper that freads file chunks
Browse files Browse the repository at this point in the history
It needs to be tested if this is faster or slower than the mmap.
  • Loading branch information
Gottox committed Jun 8, 2024
1 parent a41dec9 commit d3d2dda
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/sqsh_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ enum SqshError {
SQSH_ERROR_INODE_PARENT_MISMATCH,
SQSH_ERROR_INODE_PARENT_UNSET,
SQSH_ERROR_NOT_A_SYMLINK,
SQSH_ERROR_READ_FAILED,
};

/**
Expand Down
9 changes: 9 additions & 0 deletions include/sqsh_mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ extern const struct SqshMemoryMapperImpl *const sqsh_mapper_impl_mmap;
*/
extern const struct SqshMemoryMapperImpl *const sqsh_mapper_impl_static;

/***************************************
* mapper/static_file.c
*/

/**
* @brief a mapper that uses a static buffer.
*/
extern const struct SqshMemoryMapperImpl *const sqsh_mapper_impl_file;

#ifdef __cplusplus
}
#endif
Expand Down
123 changes: 123 additions & 0 deletions libsqsh/src/mapper/file_mapper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/******************************************************************************
* *
* Copyright (c) 2023, Enno Boland <[email protected]> *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions are *
* met: *
* *
* * Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* * Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS *
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, *
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR *
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR *
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
******************************************************************************/

/**
* @author Enno Boland ([email protected])
* @file mmap_mapper.c
*/

#define _DEFAULT_SOURCE

#include <sqsh_common_private.h>
#include <sqsh_error.h>
#include <sqsh_mapper.h>

#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>

static int
sqsh_mapper_file_init(

Check warning on line 45 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L45

Added line #L45 was not covered by tests
struct SqshMapper *mapper, const void *input, size_t *size) {
(void)size;
int rv = 0;

Check warning on line 48 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L48

Added line #L48 was not covered by tests
FILE *file;
int fd;
struct stat st = {0};

Check warning on line 51 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L51

Added line #L51 was not covered by tests

file = fopen(input, "r");

Check warning on line 53 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L53

Added line #L53 was not covered by tests
if (file == NULL) {
rv = -errno;
goto out;

Check warning on line 56 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L55-L56

Added lines #L55 - L56 were not covered by tests
}

fd = fileno(file);

Check warning on line 59 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L59

Added line #L59 was not covered by tests

if (fstat(fd, &st) < 0) {
fclose(file);
rv = -errno;
goto out;

Check warning on line 64 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L62-L64

Added lines #L62 - L64 were not covered by tests
}

// TODO: check for overflow.
*size = (size_t)st.st_size;
sqsh_mapper_set_user_data(mapper, file);

Check warning on line 69 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L68-L69

Added lines #L68 - L69 were not covered by tests

out:
return rv;

Check warning on line 72 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L71-L72

Added lines #L71 - L72 were not covered by tests
}
static int
sqsh_mapping_file_map(

Check warning on line 75 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L75

Added line #L75 was not covered by tests
const struct SqshMapper *mapper, sqsh_index_t offset, size_t size,
uint8_t **data) {
int rv = 0;
FILE *file = sqsh_mapper_user_data(mapper);

Check warning on line 79 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L78-L79

Added lines #L78 - L79 were not covered by tests

if (size != 0) {
*data = calloc(size, sizeof(uint8_t));

Check warning on line 82 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L82

Added line #L82 was not covered by tests
if (*data == NULL) {
rv = -SQSH_ERROR_MALLOC_FAILED;
goto out;

Check warning on line 85 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L84-L85

Added lines #L84 - L85 were not covered by tests
}
fseek(file, (long)offset, SEEK_SET);

Check warning on line 87 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L87

Added line #L87 was not covered by tests
if (fread(*data, sizeof(uint8_t), size, file) != size) {
rv = -SQSH_ERROR_READ_FAILED;
goto out;

Check warning on line 90 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L89-L90

Added lines #L89 - L90 were not covered by tests
}
}

out:

Check warning on line 94 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L94

Added line #L94 was not covered by tests
if (rv < 0) {
free(*data);

Check warning on line 96 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L96

Added line #L96 was not covered by tests
}
return rv;

Check warning on line 98 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L98

Added line #L98 was not covered by tests
}

static int
sqsh_mapper_file_cleanup(struct SqshMapper *mapper) {
FILE *file = sqsh_mapper_user_data(mapper);
fclose(file);
return 0;

Check warning on line 105 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L102-L105

Added lines #L102 - L105 were not covered by tests
}

static int
sqsh_mapping_file_unmap(

Check warning on line 109 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L109

Added line #L109 was not covered by tests
const struct SqshMapper *mapper, uint8_t *data, size_t size) {
(void)mapper;
(void)size;
free(data);
return 0;

Check warning on line 114 in libsqsh/src/mapper/file_mapper.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/mapper/file_mapper.c#L113-L114

Added lines #L113 - L114 were not covered by tests
}

static const struct SqshMemoryMapperImpl impl = {
/* 1 MiB */
.block_size_hint = 1024 * 1024, .init = sqsh_mapper_file_init,
.map = sqsh_mapping_file_map, .unmap = sqsh_mapping_file_unmap,
.cleanup = sqsh_mapper_file_cleanup,
};
const struct SqshMemoryMapperImpl *const sqsh_mapper_impl_file = &impl;
1 change: 1 addition & 0 deletions libsqsh/src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ libsqsh_sources = files(
'file/inode_null.c',
'file/inode_symlink.c',
'mapper/curl_mapper.c',
'mapper/file_mapper.c',
'mapper/map_iterator.c',
'mapper/map_manager.c',
'mapper/map_reader.c',
Expand Down
2 changes: 2 additions & 0 deletions libsqsh/src/utils/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ sqsh_error_str(int error_code) {
return "Not a symlink";
case SQSH_ERROR_INODE_PARENT_UNSET:
return "Inode parent unset";
case SQSH_ERROR_READ_FAILED:
return "Read failed";

Check warning on line 162 in libsqsh/src/utils/error.c

View check run for this annotation

Codecov / codecov/patch

libsqsh/src/utils/error.c#L161-L162

Added lines #L161 - L162 were not covered by tests
}
snprintf(err_str, sizeof(err_str), UNKNOWN_ERROR_FORMAT, error_code);
return err_str;
Expand Down
1 change: 0 additions & 1 deletion tools/src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ struct SqshArchive *
open_archive(const char *image_path, uint64_t offset, int *err) {
struct SqshConfig config = {
.source_mapper = NULL,
.mapper_block_size = 1024 * 256,
.archive_offset = offset,
};
if (sqsh_mapper_impl_curl != NULL) {
Expand Down

0 comments on commit d3d2dda

Please sign in to comment.