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(a)redhat.com>
---
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