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(a)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