[Libguestfs] [nbdkit PATCH v2 1/6] file: Optimize writing zeroes without holes

Eric Blake eblake at redhat.com
Thu Jan 26 02:42:31 UTC 2017


On newer Linux, fallocate() can more efficiently write zeroes
without punching holes.  When this mode is supported, use it
instead of falling back to write (while still gracefully falling
back to the write method if it fails with EOPNOTSUPP).

Also fix a typo in an error message in the previous commit.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 plugins/file/file.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/plugins/file/file.c b/plugins/file/file.c
index bd7a9c1..2d32615 100644
--- a/plugins/file/file.c
+++ b/plugins/file/file.c
@@ -254,6 +254,7 @@ static int
 file_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)
 {
   struct handle *h = handle;
+  int r = -1;

   if (wdelayms > 0) {
     const struct timespec ts = {
@@ -265,18 +266,28 @@ file_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)

 #ifdef FALLOC_FL_PUNCH_HOLE
   if (may_trim) {
-    int r = fallocate (h->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
-		       offset, count);
+    r = fallocate (h->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+		   offset, count);
     if (r == -1 && errno != EOPNOTSUPP) {
-      nbdkit_error ("pwrite: %m");
+      nbdkit_error ("zero: %m");
     }
+    /* PUNCH_HOLE is older; if it is not supported, it is likely that
+       ZERO_RANGE will not work either, so fall back to write. */
     return r;
   }
 #endif

+#ifdef FALLOC_FL_ZERO_RANGE
+  r = fallocate (h->fd, FALLOC_FL_ZERO_RANGE, offset, count);
+  if (r == -1 && errno != EOPNOTSUPP) {
+    nbdkit_error ("zero: %m");
+  }
+#else
   /* Trigger a fall back to writing */
   errno = EOPNOTSUPP;
-  return -1;
+#endif
+
+  return r;
 }

 /* Flush the file to disk. */
-- 
2.9.3




More information about the Libguestfs mailing list