Add BDS flags that prevent taking WRITE and/or RESIZE permissions on
pure data (no metadata) children.  These are going to be used by qcow2
during formatting, when we need write access to format the metadata
file, but no write access to an external data file.  This will allow
creating a qcow2 image for a raw image while the latter is currently in
use by the VM.

Signed-off-by: Hanna Czenczek <[email protected]>
---
 include/block/block-common.h | 11 +++++++++++
 block.c                      | 15 +++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/block/block-common.h b/include/block/block-common.h
index c8c626daea..504f6aa113 100644
--- a/include/block/block-common.h
+++ b/include/block/block-common.h
@@ -245,6 +245,17 @@ typedef enum {
 
 #define BDRV_O_CBW_DISCARD_SOURCE 0x80000 /* for copy-before-write filter */
 
+/*
+ * Promise not to write any data to pure (non-metadata-bearing) data storage
+ * children, so we don't need the WRITE permission for them.
+ * For image creation, formatting requires write access to the image, but not
+ * necessarily to its pure storage children.  This allows creating an image on
+ * top of an existing raw storage image that is already attached to the VM.
+ */
+#define BDRV_O_NO_DATA_WRITE  0x100000
+/* Same as O_NO_DATA_WRITE, but for resizing */
+#define BDRV_O_NO_DATA_RESIZE 0x200000
+
 #define BDRV_O_CACHE_MASK  (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
 
 
diff --git a/block.c b/block.c
index 48a17f393c..cdfed7a4d8 100644
--- a/block.c
+++ b/block.c
@@ -2887,6 +2887,21 @@ static void 
bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
         if (perm & BLK_PERM_WRITE) {
             perm |= BLK_PERM_RESIZE;
         }
+
+        if (!(role & BDRV_CHILD_METADATA)) {
+            /*
+             * For a pure data storage child (no metadata), these flags
+             * respectively promise that
+             * - nothing will be written, and/or
+             * - it will not be resized.
+             */
+            if (flags & BDRV_O_NO_DATA_WRITE) {
+                perm &= ~BLK_PERM_WRITE;
+            }
+            if (flags & BDRV_O_NO_DATA_RESIZE) {
+                perm &= ~BLK_PERM_RESIZE;
+            }
+        }
     }
 
     if (bs->open_flags & BDRV_O_INACTIVE) {
-- 
2.52.0


Reply via email to