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