Index: libvirt-1.2.3/docs/schemas/storagevol.rng =================================================================== --- libvirt-1.2.3.orig/docs/schemas/storagevol.rng +++ libvirt-1.2.3/docs/schemas/storagevol.rng @@ -139,6 +139,11 @@ + + + + + Index: libvirt-1.2.3/src/conf/storage_conf.c =================================================================== --- libvirt-1.2.3.orig/src/conf/storage_conf.c +++ libvirt-1.2.3/src/conf/storage_conf.c @@ -1401,6 +1401,9 @@ virStorageVolDefParseXML(virStoragePoolD 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; Index: libvirt-1.2.3/src/conf/storage_conf.h =================================================================== --- libvirt-1.2.3.orig/src/conf/storage_conf.h +++ libvirt-1.2.3/src/conf/storage_conf.h @@ -90,6 +90,7 @@ struct _virStorageVolTarget { virStorageEncryptionPtr encryption; virBitmapPtr features; char *compat; + bool nocow; }; typedef struct _virStorageVolDef virStorageVolDef; Index: libvirt-1.2.3/src/storage/storage_backend.c =================================================================== --- libvirt-1.2.3.orig/src/storage/storage_backend.c +++ libvirt-1.2.3/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 @@ -449,6 +452,21 @@ virStorageBackendCreateRaw(virConnectPtr 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; @@ -712,6 +730,7 @@ virStorageBackendCreateQemuImgOpts(char bool preallocate, int format, const char *compat, + bool nocow, virBitmapPtr features) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -724,6 +743,8 @@ virStorageBackendCreateQemuImgOpts(char virBufferAddLit(&buf, "encryption=on,"); if (preallocate) virBufferAddLit(&buf, "preallocation=metadata,"); + if (nocow) + virBufferAddLit(&buf, "nocow=on,"); if (compat) virBufferAsprintf(&buf, "compat=%s,", compat); @@ -945,6 +966,7 @@ virStorageBackendCreateQemuImgCmd(virCon do_encryption, preallocate, vol->target.format, compat, + vol->target.nocow, vol->target.features) < 0) { virCommandFree(cmd); return NULL;