Gabriel de Perthuis
2013-Oct-22 16:57 UTC
[Libguestfs] [PATCH 2/2] Discard unwritten ranges
--- 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) + error (EXIT_FAILURE, errno, "fallocate: %s", outputfile); + } + close (fd); } static int check_header_magic (int fd) -- 1.8.4.1.563.g8e6fc32
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.