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;