[libvirt] [PATCH option 1] Use fallocate directly if possible

Jiri Denemark jdenemar at redhat.com
Tue Mar 2 15:26:49 UTC 2010


If fallocate() is present, use it directly instead of posix_allocate().
If it is not support by the kernel or filesystem, emulate it using
mmap() or write().

This change is to work around slow fallocate emulation done by glibc's
posix_allocate() when used on files opened with O_DSYNC.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 configure.ac    |    2 +-
 src/util/util.c |   24 +++++++++++++++++++++---
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 682b8b5..c000ac3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -104,7 +104,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 posix_fallocate mmap])
+AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid posix_fallocate mmap 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/util/util.c b/src/util/util.c
index 34c585d..6ecc226 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -128,7 +128,7 @@ ssize_t safewrite(int fd, const void *buf, size_t count)
         return nwritten;
 }
 
-#ifdef HAVE_POSIX_FALLOCATE
+#if defined(HAVE_POSIX_FALLOCATE) && !defined(HAVE_FALLOCATE)
 int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len)
 {
     return posix_fallocate(fd, offset, len);
@@ -136,7 +136,7 @@ int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len)
 #else
 
 #ifdef HAVE_MMAP
-int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len)
+static int safezero_mmap(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len)
 {
     int r;
     char *buf;
@@ -160,7 +160,7 @@ int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len)
 
 #else /* HAVE_MMAP */
 
-int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len)
+static int safezero_write(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len)
 {
     int r;
     char *buf;
@@ -196,6 +196,24 @@ int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len)
     return 0;
 }
 #endif /* HAVE_MMAP */
+
+int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len)
+{
+#ifdef HAVE_FALLOCATE
+    if (fallocate(fd, 0, offset, len) < 0) {
+        if (errno != ENOSYS && errno != EOPNOTSUPP)
+            return -1;
+    } else
+        return 0;
+#endif
+
+#ifdef HAVE_MMAP
+    return safezero_mmap(fd, 0, offset, len);
+#else
+    return safezero_write(fd, 0, offset, len);
+#endif
+}
+
 #endif /* HAVE_POSIX_FALLOCATE */
 
 #ifndef PROXY
-- 
1.7.0




More information about the libvir-list mailing list