diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-06-30 16:41:21 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-06-30 16:41:21 +0200 |
commit | f439b20706ade4b5630c3d6c57e6a36ce0dc287a (patch) | |
tree | 210abf39ac29d7cf7513f667f63495ef1fd43700 /tar/tar2sqfs.c | |
parent | 3e920038ecd8cc123b0c8dd957f94a8e1a616c0c (diff) |
Add support for repacking condensed sparse files
This commit broadly does the following things:
- Rename and move the sparse mapping structure to libutil
- Add a function to the data writer for writing condensed versions
of sparse files, given the mapping.
- This shares code with the already existing function for regular
files. The shared code is moved to a common helper function.
- Add support to tar2sqfs for repacking sparse files.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'tar/tar2sqfs.c')
-rw-r--r-- | tar/tar2sqfs.c | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c index 48e7fda..bce6a4d 100644 --- a/tar/tar2sqfs.c +++ b/tar/tar2sqfs.c @@ -165,6 +165,26 @@ fail_arg: exit(EXIT_FAILURE); } +static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, + data_writer_t *data) +{ + int ret; + + if (hdr->sparse != NULL) { + ret = write_data_from_fd_condensed(data, fi, STDIN_FILENO, + hdr->sparse); + if (ret) + return -1; + + return skip_padding(STDIN_FILENO, hdr->sparse_size); + } + + if (write_data_from_fd(data, fi, STDIN_FILENO)) + return -1; + + return skip_padding(STDIN_FILENO, fi->size); +} + static int create_node_and_repack_data(tar_header_decoded_t *hdr, fstree_t *fs, data_writer_t *data) { @@ -177,15 +197,8 @@ static int create_node_and_repack_data(tar_header_decoded_t *hdr, fstree_t *fs, if (!quiet) printf("Packing %s\n", hdr->name); - if (S_ISREG(hdr->sb.st_mode)) { - if (write_data_from_fd(data, node->data.file, - STDIN_FILENO)) { - return -1; - } - - if (skip_padding(STDIN_FILENO, node->data.file->size)) - return -1; - } + if (S_ISREG(hdr->sb.st_mode)) + return write_file(hdr, node->data.file, data); return 0; fail_errno: @@ -196,6 +209,9 @@ fail_errno: static int process_tar_ball(fstree_t *fs, data_writer_t *data) { tar_header_decoded_t hdr; + uint64_t offset, count; + sparse_map_t *m; + bool skip; int ret; for (;;) { @@ -205,9 +221,37 @@ static int process_tar_ball(fstree_t *fs, data_writer_t *data) if (ret < 0) return -1; + skip = false; + if (hdr.unknown_record) { fprintf(stderr, "skipping '%s' (unknown entry type)\n", hdr.name); + skip = true; + } + + if (!skip && hdr.sparse != NULL) { + offset = hdr.sparse->offset; + count = 0; + + for (m = hdr.sparse; m != NULL; m = m->next) { + if (m->offset < offset) { + skip = true; + break; + } + offset = m->offset + m->count; + count += m->count; + } + + if (count != hdr.sparse_size) + skip = true; + + if (skip) { + fprintf(stderr, "skipping '%s' (broken sparse " + "file layout)\n", hdr.name); + } + } + + if (skip) { if (skip_entry(STDIN_FILENO, hdr.sb.st_size)) goto fail; continue; |