Currently the safezero() function uses build conditionals to choose either the posix_fallocate() or mmap() with a fallback to safewrite() in order to preallocate a file. This patch will modify the logic in order to allow fallbacks in the event that posix_fallocate() or the ftruncate()and mmap() doesn't work properly. The fallback will be to use the slow safewrite of zero filled buffers to the file. This patch also introduces virFileFdPosixFallocate() so that it can be used by the resize code rather than having two separate functions Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virfile.c | 37 +++++++++++++++++++++++++++---------- src/util/virfile.h | 2 ++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 08111d4..5556d31 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1278,6 +1278,7 @@ virFileDirectFdFlag; virFileExists; virFileFclose; virFileFdopen; +virFileFdPosixFallocate; virFileFindHugeTLBFS; virFileFindMountPoint; virFileFindResource; diff --git a/src/util/virfile.c b/src/util/virfile.c index f9efc65..7f03cbf 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1034,26 +1034,26 @@ safewrite(int fd, const void *buf, size_t count) return nwritten; } -#ifdef HAVE_POSIX_FALLOCATE int -safezero(int fd, off_t offset, off_t len) +virFileFdPosixFallocate(int fd, off_t offset, off_t len) { +#ifdef HAVE_POSIX_FALLOCATE int ret = posix_fallocate(fd, offset, len); if (ret == 0) return 0; + VIR_WARN("Failed to pre-allocate '%lu' bytes with return value '%d'", + len, ret); errno = ret; +#endif /* HAVE_POSIX_FALLOCATE */ return -1; } -#else - -int -safezero(int fd, off_t offset, off_t len) +static int +safezero_mmap(int fd, off_t offset, off_t len) { +#ifdef HAVE_MMAP int r; char *buf; - unsigned long long remain, bytes; -# ifdef HAVE_MMAP static long pagemask = 0; off_t map_skip; @@ -1080,7 +1080,16 @@ safezero(int fd, off_t offset, off_t len) /* fall back to writing zeroes using safewrite if mmap fails (for * example because of virtual memory limits) */ -# endif /* HAVE_MMAP */ +#endif /* HAVE_MMAP */ + return -1; +} + +static int +safezero_slow(int fd, off_t offset, off_t len) +{ + int r; + char *buf; + unsigned long long remain, bytes; if (lseek(fd, offset, SEEK_SET) < 0) return -1; @@ -1111,8 +1120,16 @@ safezero(int fd, off_t offset, off_t len) VIR_FREE(buf); return 0; } -#endif /* HAVE_POSIX_FALLOCATE */ +int +safezero(int fd, off_t offset, off_t len) +{ + if (virFileFdPosixFallocate(fd, offset, len) == 0) + return 0; + if (safezero_mmap(fd, offset, len) == 0) + return 0; + return safezero_slow(fd, offset, len); +} #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R /* search /proc/mounts for mount point of *type; return pointer to diff --git a/src/util/virfile.h b/src/util/virfile.h index 403d0ba..29a1776 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -41,6 +41,8 @@ typedef enum { ssize_t saferead(int fd, void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; ssize_t safewrite(int fd, const void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; +int virFileFdPosixFallocate(int fd, off_t offset, off_t len) + ATTRIBUTE_RETURN_CHECK; int safezero(int fd, off_t offset, off_t len) ATTRIBUTE_RETURN_CHECK; -- 1.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list