diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index 1cd82b4565a99f69be0cb876df13558191e7e340..789701c18c5dd1848151f6580f249fa577cfce88 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -385,6 +385,7 @@ <label>virt_image_t</label> </permissions> <compat>1.1</compat> + <nocow/> <features> <lazy_refcounts/> </features> @@ -424,6 +425,12 @@ 1.1 is used. If omitted, qemu-img default is used. Since 1.1.0 +
nocow
+
Turn off COW of the newly created volume. So far, this is only valid + for a file image in btrfs file system. It will improve performance when + the file image is used in VM. To create non-raw file images, it + requires QEMU version since 2.1. Since 1.2.7 +
features
Format-specific features. Only used for qcow2 now. Valid sub-elements are: diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 3798476f0354c48bcca4be5bc224c6b937018d29..1b2d4cccad79e3120ce5c18d3c028f620a5f6958 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -137,6 +137,11 @@ + + + + + diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index c79aebd0a4234a83811592e5288ca00f188b1da3..69333f574aaed0c72ec3d2d31b238350e979de6d 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -1299,6 +1299,9 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, virStringFreeList(version); } + if (virXPathNode("./target/nocow", ctxt)) + ret->target.nocow = true; + if (options->featureFromString && virXPathNode("./target/features", ctxt)) { if ((n = virXPathNodeSet("./target/features/*", ctxt, &nodes)) < 0) goto error; diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index fdcaadad7767900178f79bbe75636c233213c64c..dc835d36bad0832a47690f51a6bc2b449cc36524 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -37,6 +37,9 @@ #ifdef __linux__ # include # include +# ifndef FS_NOCOW_FL +# define FS_NOCOW_FL 0x00800000 /* Do not cow file */ +# endif #endif #if WITH_SELINUX @@ -453,6 +456,21 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, goto cleanup; } + if (vol->target.nocow) { +#ifdef __linux__ + int attr; + + /* Set NOCOW flag. This is an optimisation for btrfs. + * The FS_IOC_SETFLAGS ioctl return value will be ignored since any + * failure of this operation should not block the left work. + */ + if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) { + attr |= FS_NOCOW_FL; + ioctl(fd, FS_IOC_SETFLAGS, &attr); + } +#endif + } + if ((ret = createRawFile(fd, vol, inputvol)) < 0) /* createRawFile already reported the exact error. */ ret = -1; @@ -718,6 +736,7 @@ virStorageBackendCreateQemuImgOpts(char **opts, bool preallocate, int format, const char *compat, + bool nocow, virBitmapPtr features) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -730,6 +749,8 @@ virStorageBackendCreateQemuImgOpts(char **opts, virBufferAddLit(&buf, "encryption=on,"); if (preallocate) virBufferAddLit(&buf, "preallocation=metadata,"); + if (nocow) + virBufferAddLit(&buf, "nocow=on,"); if (compat) virBufferAsprintf(&buf, "compat=%s,", compat); @@ -950,6 +971,7 @@ virStorageBackendCreateQemuImgCmd(virConnectPtr conn, do_encryption, preallocate, vol->target.format, compat, + vol->target.nocow, vol->target.features) < 0) { virCommandFree(cmd); return NULL; diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 0ba746ab7dbbf83db13be025c1b85bdd6f012a2d..c840aa06e249a576b1efe2911c3e75749de735e1 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -247,6 +247,7 @@ struct _virStorageSource { * pool-specific enum for storage volumes */ virBitmapPtr features; char *compat; + bool nocow; virStoragePermsPtr perms; virStorageTimestampsPtr timestamps;