On 10/22/2013 05:57 PM, Gabriel de Perthuis wrote:
---
pxzcat.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/pxzcat.c b/pxzcat.c
index 9bcdc36..55ccfc0 100644
--- a/pxzcat.c
+++ b/pxzcat.c
@@ -44,10 +44,11 @@
#include <sys/types.h>
#include <error.h>
#include <errno.h>
#include <getopt.h>
#include <pthread.h>
+#include <linux/falloc.h>
#include <lzma.h>
#define DEBUG 0
@@ -145,10 +146,11 @@ usage (int exitcode)
static void
xzfile_uncompress (const char *filename, const char *outputfile,
unsigned nr_threads)
{
int fd, ofd;
+ off_t hole_start, data_start;
uint64_t size;
lzma_index *idx;
/* Open the file. */
fd = open (filename, O_RDONLY);
@@ -176,10 +178,29 @@ xzfile_uncompress (const char *filename, const
char *outputfile,
posix_fadvise (fd, 0, 0, POSIX_FADV_RANDOM|POSIX_FADV_DONTNEED);
/* Iterate over blocks. */
iter_blocks (idx, nr_threads, filename, fd, outputfile, ofd);
+ /* discard ranges that were allocated but not written */
+ data_start = 0;
+ while (data_start < size) {
+ hole_start = lseek (ofd, data_start, SEEK_HOLE);
+ if (hole_start == (off_t) -1)
+ error (EXIT_FAILURE, errno, "lseek: %s", outputfile);
+ if (hole_start == size)
+ break;
+ data_start = lseek (ofd, hole_start, SEEK_DATA);
+ if (data_start == (off_t) -1) {
+ if (errno == ENXIO)
+ data_start = size;
+ else
+ error (EXIT_FAILURE, errno, "lseek: %s", outputfile);
+ }
+ if (fallocate (ofd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE,
hole_start, data_start - hole_start) == -1)
FALLOC_FL_PUNCH_HOLE is new. So you might want to:
#ifdef FALLOC_FL_PUNCH_HOLE
fallocate(....)
#endif
You may want to avoid the original fallocate() too,
if PUNCH_HOLE wasn't available.
cheers,
Pádraig.