[libvirt] [PATCH 1/3] storage: Support preallocate the new capacity for vol-resize
Michal Privoznik
mprivozn at redhat.com
Tue Jun 4 15:19:37 UTC 2013
On 31.05.2013 07:16, Osier Yang wrote:
> 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.
> ---
> src/storage/storage_backend_fs.c | 19 +++++++++++++++----
> src/storage/storage_driver.c | 3 ++-
> src/util/virstoragefile.c | 38 +++++++++++++++++++++++++++++++++++---
> src/util/virstoragefile.h | 5 ++++-
> 4 files changed, 56 insertions(+), 9 deletions(-)
>
> diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
> index 1379f17..78f5d53 100644
> --- a/src/storage/storage_backend_fs.c
> +++ b/src/storage/storage_backend_fs.c
> @@ -1245,13 +1245,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 = {
> diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
> index a2b0c21..e7516eb 100644
> --- a/src/storage/storage_driver.c
> +++ b/src/storage/storage_driver.c
> @@ -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);
> diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
> index f0e9114..e42eb77 100644
> --- a/src/util/virstoragefile.c
> +++ b/src/util/virstoragefile.c
> @@ -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 'path'"), path);
fails synax-check. s/path/%s/
> + 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) {
> diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
> index ffe7a54..c195c9a 100644
> --- a/src/util/virstoragefile.h
> +++ b/src/util/virstoragefile.h
> @@ -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),
>
ACK
Michal
More information about the libvir-list
mailing list