Using posix_fallocate() to allocate disk space and fill it with zeros is faster
than writing the zeros block-by-block.
Also, for backing file systems that support extents and the fallocate() syscall,
this operation will give us a big speed boost.
This also brings us the advantage of very less fragmentation for the chunk being
allocated.
For systems that don't support posix_fallocate(), fall back to safewrite().
Signed-off-by: Amit Shah <amit.shah(a)redhat.com>
---
configure.in | 2 +-
src/libvirt_private.syms | 1 +
src/util.c | 20 ++++++++++++++++++++
src/util.h | 1 +
4 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/configure.in b/configure.in
index 413d27c..edce040 100644
--- a/configure.in
+++ b/configure.in
@@ -72,7 +72,7 @@ dnl Use --disable-largefile if you don't want this.
AC_SYS_LARGEFILE
dnl Availability of various common functions (non-fatal if missing).
-AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid])
+AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid
posix_fallocate])
dnl Availability of various not common threadsafe functions
AC_CHECK_FUNCS([strerror_r strtok_r getmntent_r getgrnam_r getpwuid_r])
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f0d8afa..a5f9f92 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -308,6 +308,7 @@ virStrToLong_ui;
virFileLinkPointsTo;
saferead;
safewrite;
+safezero;
virMacAddrCompare;
virEnumFromString;
virEnumToString;
diff --git a/src/util.c b/src/util.c
index 66ad9a4..de754bf 100644
--- a/src/util.c
+++ b/src/util.c
@@ -117,6 +117,26 @@ ssize_t safewrite(int fd, const void *buf, size_t count)
return nwritten;
}
+#if HAVE_POSIX_FALLOCATE
+int safezero(int fd, int flags, off_t offset, off_t len)
+{
+ return posix_fallocate(fd, offset, len);
+}
+#else
+int safezero(int fd, int flags, off_t offset, off_t len)
+{
+ char *buf;
+ int r;
+
+ buf = calloc(len, sizeof(char));
+ if (buf == NULL)
+ return -ENOMEM;
+
+ r = safewrite(fd, buf, len);
+ return r;
+}
+#endif
+
#ifndef PROXY
int virFileStripSuffix(char *str,
diff --git a/src/util.h b/src/util.h
index 87cbf67..3fd5d25 100644
--- a/src/util.h
+++ b/src/util.h
@@ -31,6 +31,7 @@
int saferead(int fd, void *buf, size_t count);
ssize_t safewrite(int fd, const void *buf, size_t count);
+int safezero(int fd, int flags, off_t offset, off_t len);
enum {
VIR_EXEC_NONE = 0,
--
1.6.0.6