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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list