[Libguestfs] [PATCH 2/2] Discard unwritten ranges

Gabriel de Perthuis g2p.code at gmail.com
Tue Oct 22 16:57:15 UTC 2013


---
 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




More information about the Libguestfs mailing list