mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 03:12:22 +00:00
storage: Support preallocate the new capacity for vol-resize
The document for "vol-resize" says the new capacity will be sparse unless "--allocate" is specified, however, the "--allocate" flag is never implemented. This implements the "--allocate" flag for fs backend's raw type volume, based on posix_fallocate and the syscall SYS_fallocate.
This commit is contained in:
parent
70fe129546
commit
aa2a4cff7c
@ -1246,13 +1246,24 @@ virStorageBackendFileSystemVolResize(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
unsigned long long capacity,
|
||||
unsigned int flags)
|
||||
{
|
||||
virCheckFlags(0, -1);
|
||||
virCheckFlags(VIR_STORAGE_VOL_RESIZE_ALLOCATE, -1);
|
||||
|
||||
bool pre_allocate = flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE;
|
||||
|
||||
if (vol->target.format == VIR_STORAGE_FILE_RAW) {
|
||||
return virStorageFileResize(vol->target.path, capacity,
|
||||
vol->capacity, pre_allocate);
|
||||
} else {
|
||||
if (pre_allocate) {
|
||||
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
||||
_("preallocate is only supported for raw "
|
||||
"type volume"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vol->target.format == VIR_STORAGE_FILE_RAW)
|
||||
return virStorageFileResize(vol->target.path, capacity);
|
||||
else
|
||||
return virStorageBackendFilesystemResizeQemuImg(vol->target.path,
|
||||
capacity);
|
||||
}
|
||||
}
|
||||
|
||||
virStorageBackend virStorageBackendDirectory = {
|
||||
|
@ -1761,7 +1761,8 @@ storageVolResize(virStorageVolPtr obj,
|
||||
unsigned long long abs_capacity;
|
||||
int ret = -1;
|
||||
|
||||
virCheckFlags(VIR_STORAGE_VOL_RESIZE_DELTA, -1);
|
||||
virCheckFlags(VIR_STORAGE_VOL_RESIZE_ALLOCATE |
|
||||
VIR_STORAGE_VOL_RESIZE_DELTA, -1);
|
||||
|
||||
storageDriverLock(driver);
|
||||
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
|
||||
|
@ -45,6 +45,9 @@
|
||||
#include "virendian.h"
|
||||
#include "virstring.h"
|
||||
#include "virutil.h"
|
||||
#if HAVE_SYS_SYSCALL_H
|
||||
# include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_STORAGE
|
||||
|
||||
@ -1038,19 +1041,48 @@ virStorageFileFreeMetadata(virStorageFileMetadata *meta)
|
||||
* Change the capacity of the raw storage file at 'path'.
|
||||
*/
|
||||
int
|
||||
virStorageFileResize(const char *path, unsigned long long capacity)
|
||||
virStorageFileResize(const char *path,
|
||||
unsigned long long capacity,
|
||||
unsigned long long orig_capacity,
|
||||
bool pre_allocate)
|
||||
{
|
||||
int fd = -1;
|
||||
int ret = -1;
|
||||
int rc;
|
||||
off_t offset = orig_capacity;
|
||||
off_t len = capacity - orig_capacity;
|
||||
|
||||
if ((fd = open(path, O_RDWR)) < 0) {
|
||||
virReportSystemError(errno, _("Unable to open '%s'"), path);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ftruncate(fd, capacity) < 0) {
|
||||
virReportSystemError(errno, _("Failed to truncate file '%s'"), 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 preallocate 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,
|
||||
_("Failed to truncate file '%s'"), path);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (VIR_CLOSE(fd) < 0) {
|
||||
|
@ -89,7 +89,10 @@ const char *virStorageFileChainLookup(virStorageFileMetadataPtr chain,
|
||||
|
||||
void virStorageFileFreeMetadata(virStorageFileMetadataPtr meta);
|
||||
|
||||
int virStorageFileResize(const char *path, unsigned long long capacity);
|
||||
int virStorageFileResize(const char *path,
|
||||
unsigned long long capacity,
|
||||
unsigned long long orig_capacity,
|
||||
bool pre_allocate);
|
||||
|
||||
enum {
|
||||
VIR_STORAGE_FILE_SHFS_NFS = (1 << 0),
|
||||
|
Loading…
x
Reference in New Issue
Block a user