Currently virStorageFileResize() function uses build conditionals to choose either the posix_fallocate() or mmap() with no fallback in order to preallocate the space in the newly resized file. This patch will modify the logic in order to allow fallbacks in the event that posix_fallocate() or the sys_fallocate syscall() doesn't work properly. The fallback will be to use the slow safewrite of zero filled buffers to the file. Use the virFileFdPosixFallocate() rather than a local function. Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/util/virstoragefile.c | 52 +++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 5b6b2f5..4d37de1 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -1086,6 +1086,39 @@ virStorageFileChainGetBroken(virStorageSourcePtr chain, return 0; } +static int +resizeSysFallocate(const char *path, + int fd, + off_t offset, + off_t len) +{ + int rc = -1; +#if HAVE_SYS_SYSCALL_H && defined(SYS_fallocate) + if ((rc = syscall(SYS_fallocate, fd, 0, offset, len)) != 0) { + virReportSystemError(errno, + _("Failed to pre-allocate space for " + "file '%s'"), path); + } +#endif + return rc; +} + +static int +doResize(const char *path, + int fd, + off_t offset, + off_t len) +{ + if (virFileFdPosixFallocate(fd, offset, len) == 0 || + resizeSysFallocate(path, fd, offset, len) == 0 || + safezero(fd, offset, len) == 0) + return 0; + + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("preallocate is not supported on this platform")); + return -1; +} + /** * virStorageFileResize: @@ -1113,25 +1146,8 @@ 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 (doResize(path, fd, offset, len) < 0) 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list