summaryrefslogtreecommitdiff
path: root/lib
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
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')
-rw-r--r--lib/sqfs/io.c66
-rw-r--r--lib/sqfshelper/data_writer.c21
-rw-r--r--lib/sqfshelper/io_stdin.c67
-rw-r--r--lib/tar/cleanup.c4
-rw-r--r--lib/tar/internal.h6
-rw-r--r--lib/tar/read_header.c2
-rw-r--r--lib/tar/read_sparse_map.c4
-rw-r--r--lib/tar/read_sparse_map_old.c4
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;