Currently virStorageFileResize() function uses build conditionals to choose either the posix_fallocate() or syscall(SYS_fallocate) with no fallback in order to preallocate the space in the newly resized file.
Since the safezero code has a similar set of conditionals modify the resize and safezero code in order to allow the resize logic to make use of safezero to unify the look/feel of the code paths. Add a new boolean (resize) to safezero() to make the optional decision whether to try syscall(SYS_fallocate) if the posix_fallocate fails because HAVE_POSIX_FALLOCATE is not defined (eg, return -1 and errno == 0). Create a local safezero_sys_fallocate in order to handle the resize code paths that support that. If not present, the set errno = ENOSYS in order to allow the caller to handle the failure scenarios. Signed-off-by: John Ferlan <jfer...@redhat.com> --- src/locking/lock_driver_sanlock.c | 4 ++-- src/storage/storage_backend.c | 2 +- src/util/virfile.c | 22 +++++++++++++++++++++- src/util/virfile.h | 2 +- src/util/virstoragefile.c | 29 +++++++++-------------------- 5 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c index 60f305c..9fc97db 100644 --- a/src/locking/lock_driver_sanlock.c +++ b/src/locking/lock_driver_sanlock.c @@ -281,7 +281,7 @@ static int virLockManagerSanlockSetupLockspace(void) /* * Pre allocate enough data for 1 block of leases at preferred alignment */ - if (safezero(fd, 0, rv) < 0) { + if (safezero(fd, 0, rv, false) < 0) { virReportSystemError(errno, _("Unable to allocate lockspace %s"), path); @@ -690,7 +690,7 @@ static int virLockManagerSanlockCreateLease(struct sanlk_resource *res) /* * Pre allocate enough data for 1 block of leases at preferred alignment */ - if (safezero(fd, 0, rv) < 0) { + if (safezero(fd, 0, rv, false) < 0) { virReportSystemError(errno, _("Unable to allocate lease %s"), res->disks[0].path); diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index b990a82..472cec6 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -399,7 +399,7 @@ createRawFile(int fd, virStorageVolDefPtr vol, } if (remain && need_alloc) { - if (safezero(fd, vol->target.allocation - remain, remain) < 0) { + if (safezero(fd, vol->target.allocation - remain, remain, false) < 0) { ret = -errno; virReportSystemError(errno, _("cannot fill file '%s'"), vol->target.path); diff --git a/src/util/virfile.c b/src/util/virfile.c index 5e8c306..4483cce 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -42,6 +42,9 @@ #if HAVE_MMAP # include <sys/mman.h> #endif +#if HAVE_SYS_SYSCALL_H +# include <sys/syscall.h> +#endif #ifdef __linux__ # if HAVE_LINUX_MAGIC_H @@ -1047,6 +1050,20 @@ safezero_posix_fallocate(int fd, off_t offset, off_t len) } static int +safezero_sys_fallocate(int fd, + off_t offset, + off_t len) +{ + int rc = -1; +#if HAVE_SYS_SYSCALL_H && defined(SYS_fallocate) + rc = syscall(SYS_fallocate, fd, 0, offset, len); +#else + errno = ENOSYS; +#endif + return rc; +} + +static int safezero_mmap(int fd, off_t offset, off_t len) { #ifdef HAVE_MMAP @@ -1119,7 +1136,7 @@ safezero_slow(int fd, off_t offset, off_t len) return 0; } -int safezero(int fd, off_t offset, off_t len) +int safezero(int fd, off_t offset, off_t len, bool resize) { int ret; @@ -1134,6 +1151,9 @@ int safezero(int fd, off_t offset, off_t len) if (ret == 0 || errno != 0) return ret; + if (resize) + return safezero_sys_fallocate(fd, offset, len); + if (safezero_mmap(fd, offset, len) == 0) return 0; return safezero_slow(fd, offset, len); diff --git a/src/util/virfile.h b/src/util/virfile.h index 403d0ba..b8e30c3 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -41,7 +41,7 @@ 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 safezero(int fd, off_t offset, off_t len) +int safezero(int fd, off_t offset, off_t len, bool resize) ATTRIBUTE_RETURN_CHECK; /* Don't call these directly - use the macros below */ diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index c424251..9efe748 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -43,9 +43,6 @@ #include "viruri.h" #include "dirname.h" #include "virbuffer.h" -#if HAVE_SYS_SYSCALL_H -# include <sys/syscall.h> -#endif #define VIR_FROM_THIS VIR_FROM_STORAGE @@ -1120,25 +1117,17 @@ virStorageFileResize(const char *path, } if (pre_allocate) { -#if HAVE_POSIX_FALLOCATE - if ((rc = posix_fallocate(fd, offset, len)) != 0) { - virReportSystemError(rc, - _("Failed to pre-allocate space for " - "file '%s'"), path); - goto cleanup; - } -#elif HAVE_SYS_SYSCALL_H && defined(SYS_fallocate) - if (syscall(SYS_fallocate, fd, 0, offset, len) != 0) { - virReportSystemError(errno, - _("Failed to pre-allocate space for " - "file '%s'"), path); + if (safezero(fd, offset, len, true) != 0) { + if (errno == ENOSYS) + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("preallocate is not supported on this " + "platform")); + else + virReportSystemError(errno, + _("Failed to pre-allocate space for " + "file '%s'"), path); goto cleanup; } -#else - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("preallocate is not supported on this platform")); - goto cleanup; -#endif } else { if (ftruncate(fd, capacity) < 0) { virReportSystemError(errno, -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list