diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-06-28 12:41:26 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-06-28 15:07:34 +0200 |
commit | 4e017928c7b5b590d2c7e04e42cb497eb3a4f8cf (patch) | |
tree | 28f649af1074ab74576a9a715991c610b210f1c0 /lib/sqfs/data_reader.c | |
parent | d89d7e3d7f5b21fe53ea0cbf65134bdc3df30950 (diff) |
Add support for packing sparse files
This commit adds support for packing sparse files into squashfs images
as follows:
- In the data writer: simply detect zero blocks and write a zero to the
block size field and don't emit any data. Record the number of bytes
saved this way. For fragments, set the fragment offset to invalid.
- In the inode writer: write out the number of bytes saved for sparse
files. If there should be a fragment but there is none, append a block
count of 0.
- In the data reader: if the block size is 0, read nothing from disk and
emit an empty block. Do the same if the fragment is missing.
- In the inode reader: restore the number of bytes saved for sparse files.
The sparse files can be packed and unpacked, but the unpacking will not
create sparse files for now.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfs/data_reader.c')
-rw-r--r-- | lib/sqfs/data_reader.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/lib/sqfs/data_reader.c b/lib/sqfs/data_reader.c index 22413f2..421d914 100644 --- a/lib/sqfs/data_reader.c +++ b/lib/sqfs/data_reader.c @@ -5,6 +5,7 @@ #include <stdlib.h> #include <unistd.h> +#include <string.h> #include <stdio.h> struct data_reader_t { @@ -81,12 +82,18 @@ int data_reader_dump_file(data_reader_t *data, file_info_t *fi, int outfd) if (bs > data->block_size) goto fail_bs; - ret = read_retry(data->sqfsfd, data->buffer, bs); - if (ret < 0) - goto fail_rd; + if (bs == 0) { + bs = data->block_size; + memset(data->buffer, 0, bs); + compressed = false; + } else { + ret = read_retry(data->sqfsfd, data->buffer, bs); + if (ret < 0) + goto fail_rd; - if ((size_t)ret < bs) - goto fail_trunc; + if ((size_t)ret < bs) + goto fail_trunc; + } if (compressed) { ret = data->cmp->do_block(data->cmp, @@ -114,13 +121,18 @@ int data_reader_dump_file(data_reader_t *data, file_info_t *fi, int outfd) fragsz = fi->size % data->block_size; if (fragsz > 0) { - if (data->frag == NULL) - goto fail_frag; - - if (frag_reader_read(data->frag, fi->fragment, - fi->fragment_offset, data->buffer, - fragsz)) { - return -1; + if (fi->fragment == 0xFFFFFFFF || + fi->fragment_offset == 0xFFFFFFFF) { + memset(data->buffer, 0, fragsz); + } else { + if (data->frag == NULL) + goto fail_frag; + + if (frag_reader_read(data->frag, fi->fragment, + fi->fragment_offset, data->buffer, + fragsz)) { + return -1; + } } ret = write_retry(outfd, data->buffer, fragsz); |