summaryrefslogtreecommitdiff
path: root/lib/sqfshelper
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-09-25 17:47:19 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-09-25 17:47:19 +0200
commit3511b1fa7c6f71c579e161951e945904e552e1d9 (patch)
tree55fa94e5daef7bcc8e4b650f27d05af49fd1b02d /lib/sqfshelper
parent4d79f55f4a626a3cfd8bd18673aa29b48b16e137 (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/sqfshelper')
-rw-r--r--lib/sqfshelper/data_writer.c21
-rw-r--r--lib/sqfshelper/io_stdin.c67
2 files changed, 69 insertions, 19 deletions
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;
}