There is no need to use posix_fallocate or SYS_fallocate to shrink
the volume, ftruncate can do the work. qemu-img/kvm-img supports to
shrink the volume itself.
And instead of bool arguments, this introduces virStorageFileResizeFlags
enum.
---
src/storage/storage_backend_fs.c | 18 ++++++++++++++----
src/util/virstoragefile.c | 5 +++--
src/util/virstoragefile.h | 7 ++++++-
3 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index b1efa50..e55148c 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -1246,15 +1246,25 @@ virStorageBackendFileSystemVolResize(virConnectPtr conn
ATTRIBUTE_UNUSED,
unsigned long long capacity,
unsigned int flags)
{
- virCheckFlags(VIR_STORAGE_VOL_RESIZE_ALLOCATE, -1);
+ unsigned int resize_flags = 0;
+ bool preallocate = false;
- bool pre_allocate = flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE;
+ virCheckFlags(VIR_STORAGE_VOL_RESIZE_ALLOCATE |
+ VIR_STORAGE_VOL_RESIZE_SHRINK, -1);
+
+ if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) {
+ resize_flags |= VIR_STORAGE_FILE_RESIZE_PREALLOCATE;
+ preallocate = true;
+ }
+
+ if (flags & VIR_STORAGE_VOL_RESIZE_SHRINK)
+ resize_flags |= VIR_STORAGE_FILE_RESIZE_SHRINK;
if (vol->target.format == VIR_STORAGE_FILE_RAW) {
return virStorageFileResize(vol->target.path, capacity,
- vol->capacity, pre_allocate);
+ vol->capacity, resize_flags);
} else {
- if (pre_allocate) {
+ if (preallocate) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("preallocate is only supported for raw "
"type volume"));
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index bf668c8..9e085d4 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1044,7 +1044,7 @@ int
virStorageFileResize(const char *path,
unsigned long long capacity,
unsigned long long orig_capacity,
- bool pre_allocate)
+ unsigned int flags)
{
int fd = -1;
int ret = -1;
@@ -1057,7 +1057,8 @@ virStorageFileResize(const char *path,
goto cleanup;
}
- if (pre_allocate) {
+ if (flags & VIR_STORAGE_FILE_RESIZE_PREALLOCATE &&
+ !(flags & VIR_STORAGE_FILE_RESIZE_SHRINK)) {
#if HAVE_POSIX_FALLOCATE
if ((rc = posix_fallocate(fd, offset, len)) != 0) {
virReportSystemError(rc,
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index c195c9a..1cf90ce 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -89,10 +89,15 @@ const char *virStorageFileChainLookup(virStorageFileMetadataPtr
chain,
void virStorageFileFreeMetadata(virStorageFileMetadataPtr meta);
+enum {
+ VIR_STORAGE_FILE_RESIZE_PREALLOCATE = 1 << 0,
+ VIR_STORAGE_FILE_RESIZE_SHRINK = 1 << 1,
+} virStorageFileResizeFlags;
+
int virStorageFileResize(const char *path,
unsigned long long capacity,
unsigned long long orig_capacity,
- bool pre_allocate);
+ unsigned int flags);
enum {
VIR_STORAGE_FILE_SHFS_NFS = (1 << 0),
--
1.8.1.4