diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-09-25 17:47:19 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-09-25 17:47:19 +0200 |
commit | 3511b1fa7c6f71c579e161951e945904e552e1d9 (patch) | |
tree | 55fa94e5daef7bcc8e4b650f27d05af49fd1b02d /lib | |
parent | 4d79f55f4a626a3cfd8bd18673aa29b48b16e137 (diff) |
Remove condensed sparse file handling from libsquashfs
This only exists for tar2sqfs. Move the sparse file map to libtar
and add the ability to do this into the stind sqfs_file_t abstraction,
so it acts like a normal file but internally stitches the data
together from the sparse implementation.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sqfs/io.c | 66 | ||||
-rw-r--r-- | lib/sqfshelper/data_writer.c | 21 | ||||
-rw-r--r-- | lib/sqfshelper/io_stdin.c | 67 | ||||
-rw-r--r-- | lib/tar/cleanup.c | 4 | ||||
-rw-r--r-- | lib/tar/internal.h | 6 | ||||
-rw-r--r-- | lib/tar/read_header.c | 2 | ||||
-rw-r--r-- | lib/tar/read_sparse_map.c | 4 | ||||
-rw-r--r-- | lib/tar/read_sparse_map_old.c | 4 |
8 files changed, 79 insertions, 95 deletions
diff --git a/lib/sqfs/io.c b/lib/sqfs/io.c index f4ffda2..0021a30 100644 --- a/lib/sqfs/io.c +++ b/lib/sqfs/io.c @@ -37,69 +37,3 @@ int sqfs_file_create_block(sqfs_file_t *file, uint64_t offset, *out = blk; return 0; } - -int sqfs_file_create_block_dense(sqfs_file_t *file, uint64_t offset, - size_t size, sqfs_inode_generic_t *inode, - uint32_t flags, const sqfs_sparse_map_t *map, - sqfs_block_t **out) -{ - sqfs_block_t *blk = alloc_flex(sizeof(*blk), 1, size); - size_t dst_start, diff, count; - const sqfs_sparse_map_t *it; - uint64_t poffset, src_start; - int err; - - if (blk == NULL) - return SQFS_ERROR_ALLOC; - - poffset = 0; - - for (it = map; it != NULL; it = it->next) { - if (it->offset + it->count <= offset) { - poffset += it->count; - continue; - } - - if (it->offset >= offset + size) { - poffset += it->count; - continue; - } - - count = size; - - if (offset + count >= it->offset + it->count) - count = it->offset + it->count - offset; - - if (it->offset < offset) { - diff = offset - it->offset; - - src_start = poffset + diff; - dst_start = 0; - count -= diff; - } else if (it->offset > offset) { - diff = it->offset - offset; - - src_start = poffset; - dst_start = diff; - } else { - src_start = poffset; - dst_start = 0; - } - - err = file->read_at(file, src_start, - blk->data + dst_start, count); - if (err) { - free(blk); - return err; - } - - poffset += it->count; - } - - blk->inode = inode; - blk->size = size; - blk->flags = flags; - - *out = blk; - return 0; -} diff --git a/lib/sqfshelper/data_writer.c b/lib/sqfshelper/data_writer.c index 96cd9ee..a365e6d 100644 --- a/lib/sqfshelper/data_writer.c +++ b/lib/sqfshelper/data_writer.c @@ -98,9 +98,8 @@ static int add_sentinel_block(data_writer_t *data, sqfs_inode_generic_t *inode, return sqfs_data_writer_enqueue(data->proc, blk); } -int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, - sqfs_inode_generic_t *inode, - const sqfs_sparse_map_t *map, int flags) +int write_data_from_file(data_writer_t *data, sqfs_inode_generic_t *inode, + sqfs_file_t *file, int flags) { uint32_t blk_flags = SQFS_BLK_FIRST_BLOCK; uint64_t filesz, offset; @@ -123,14 +122,8 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, diff = filesz - offset; } - if (map == NULL) { - ret = sqfs_file_create_block(file, offset, diff, inode, - blk_flags, &blk); - } else { - ret = sqfs_file_create_block_dense(file, offset, diff, - inode, blk_flags, - map, &blk); - } + ret = sqfs_file_create_block(file, offset, diff, inode, + blk_flags, &blk); if (ret) return -1; @@ -189,12 +182,6 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, return 0; } -int write_data_from_file(data_writer_t *data, sqfs_inode_generic_t *inode, - sqfs_file_t *file, int flags) -{ - return write_data_from_file_condensed(data, file, inode, NULL, flags); -} - data_writer_t *data_writer_create(sqfs_super_t *super, sqfs_compressor_t *cmp, sqfs_file_t *file, size_t devblksize, unsigned int num_jobs, size_t max_backlog) diff --git a/lib/sqfshelper/io_stdin.c b/lib/sqfshelper/io_stdin.c index 6cb45d4..8568f5e 100644 --- a/lib/sqfshelper/io_stdin.c +++ b/lib/sqfshelper/io_stdin.c @@ -11,12 +11,14 @@ #include <stdlib.h> #include <unistd.h> +#include <string.h> #include <errno.h> typedef struct { sqfs_file_t base; + const sparse_map_t *map; uint64_t offset; uint64_t size; } sqfs_file_stdin_t; @@ -78,6 +80,60 @@ static int stdin_read_at(sqfs_file_t *base, uint64_t offset, return 0; } +static int stdin_read_condensed(sqfs_file_t *base, uint64_t offset, + void *buffer, size_t size) +{ + sqfs_file_stdin_t *file = (sqfs_file_stdin_t *)base; + uint64_t poffset = 0, src_start; + size_t dst_start, diff, count; + const sparse_map_t *it; + int err; + + memset(buffer, 0, size); + + for (it = file->map; it != NULL; it = it->next) { + if (it->offset + it->count <= offset) { + poffset += it->count; + continue; + } + + if (it->offset >= offset + size) { + poffset += it->count; + continue; + } + + count = size; + + if (offset + count >= it->offset + it->count) + count = it->offset + it->count - offset; + + if (it->offset < offset) { + diff = offset - it->offset; + + src_start = poffset + diff; + dst_start = 0; + count -= diff; + } else if (it->offset > offset) { + diff = it->offset - offset; + + src_start = poffset; + dst_start = diff; + } else { + src_start = poffset; + dst_start = 0; + } + + err = stdin_read_at(base, src_start, + (char *)buffer + dst_start, count); + if (err) + return err; + + poffset += it->count; + } + + return 0; +} + static int stdin_write_at(sqfs_file_t *base, uint64_t offset, const void *buffer, size_t size) { @@ -96,7 +152,7 @@ static int stdin_truncate(sqfs_file_t *base, uint64_t size) return SQFS_ERROR_IO; } -sqfs_file_t *sqfs_get_stdin_file(uint64_t size) +sqfs_file_t *sqfs_get_stdin_file(const sparse_map_t *map, uint64_t size) { sqfs_file_stdin_t *file = calloc(1, sizeof(*file)); sqfs_file_t *base = (sqfs_file_t *)file; @@ -105,10 +161,17 @@ sqfs_file_t *sqfs_get_stdin_file(uint64_t size) return NULL; file->size = size; + file->map = map; + base->destroy = stdin_destroy; - base->read_at = stdin_read_at; base->write_at = stdin_write_at; base->get_size = stdin_get_size; base->truncate = stdin_truncate; + + if (map == NULL) { + base->read_at = stdin_read_at; + } else { + base->read_at = stdin_read_condensed; + } return base; } diff --git a/lib/tar/cleanup.c b/lib/tar/cleanup.c index 3c1d0e9..2f814bf 100644 --- a/lib/tar/cleanup.c +++ b/lib/tar/cleanup.c @@ -8,9 +8,9 @@ #include "internal.h" -void free_sparse_list(sqfs_sparse_map_t *sparse) +void free_sparse_list(sparse_map_t *sparse) { - sqfs_sparse_map_t *old; + sparse_map_t *old; while (sparse != NULL) { old = sparse; diff --git a/lib/tar/internal.h b/lib/tar/internal.h index bc9a3a8..d95ef52 100644 --- a/lib/tar/internal.h +++ b/lib/tar/internal.h @@ -55,11 +55,11 @@ void update_checksum(tar_header_t *hdr); bool is_checksum_valid(const tar_header_t *hdr); -sqfs_sparse_map_t *read_sparse_map(const char *line); +sparse_map_t *read_sparse_map(const char *line); -sqfs_sparse_map_t *read_gnu_old_sparse(int fd, tar_header_t *hdr); +sparse_map_t *read_gnu_old_sparse(int fd, tar_header_t *hdr); -void free_sparse_list(sqfs_sparse_map_t *sparse); +void free_sparse_list(sparse_map_t *sparse); void free_xattr_list(tar_xattr_t *list); diff --git a/lib/tar/read_header.c b/lib/tar/read_header.c index a874972..63de699 100644 --- a/lib/tar/read_header.c +++ b/lib/tar/read_header.c @@ -77,7 +77,7 @@ static tar_xattr_t *mkxattr(const char *key, size_t keylen, static int read_pax_header(int fd, uint64_t entsize, unsigned int *set_by_pax, tar_header_decoded_t *out) { - sqfs_sparse_map_t *sparse_last = NULL, *sparse; + sparse_map_t *sparse_last = NULL, *sparse; uint64_t field, offset = 0, num_bytes = 0; char *buffer, *line, *key, *ptr, *value; tar_xattr_t *xattr; diff --git a/lib/tar/read_sparse_map.c b/lib/tar/read_sparse_map.c index 981a808..0779b96 100644 --- a/lib/tar/read_sparse_map.c +++ b/lib/tar/read_sparse_map.c @@ -8,9 +8,9 @@ #include "internal.h" -sqfs_sparse_map_t *read_sparse_map(const char *line) +sparse_map_t *read_sparse_map(const char *line) { - sqfs_sparse_map_t *last = NULL, *list = NULL, *ent = NULL; + sparse_map_t *last = NULL, *list = NULL, *ent = NULL; do { ent = calloc(1, sizeof(*ent)); diff --git a/lib/tar/read_sparse_map_old.c b/lib/tar/read_sparse_map_old.c index 7fb4cb3..5891bdb 100644 --- a/lib/tar/read_sparse_map_old.c +++ b/lib/tar/read_sparse_map_old.c @@ -8,9 +8,9 @@ #include "internal.h" -sqfs_sparse_map_t *read_gnu_old_sparse(int fd, tar_header_t *hdr) +sparse_map_t *read_gnu_old_sparse(int fd, tar_header_t *hdr) { - sqfs_sparse_map_t *list = NULL, *end = NULL, *node; + sparse_map_t *list = NULL, *end = NULL, *node; gnu_sparse_t sph; uint64_t off, sz; int i; |