[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-block] [PULL 34/39] block: Allow replacement of a BDS by its overl

From: Kevin Wolf
Subject: [Qemu-block] [PULL 34/39] block: Allow replacement of a BDS by its overlay
Date: Thu, 16 Jun 2016 16:08:23 +0200

From: Max Reitz <address@hidden>

change_parent_backing_link() asserts that the BDS to be replaced is not
used as a backing file. However, we may want to replace a BDS by its
overlay in which case that very link should not be redirected.

For instance, when doing a sync=none drive-mirror operation, we may have
the following BDS/BB forest before block job completion:


  base <- source <- BlockBackend

During job completion, we want to establish the source BDS as the
target's backing node:

  base <- source <- BlockBackend

This makes the target a valid replacement for the source:

          target <- BlockBackend
  base <- source

Without this modification to change_parent_backing_link() we have to
inject the target into the graph before the source is its backing node,
thus temporarily creating a wrong graph:

  target <- BlockBackend

  base <- source

Signed-off-by: Max Reitz <address@hidden>
Message-id: address@hidden
Reviewed-by: Kevin Wolf <address@hidden>
Reviewed-by: Fam Zheng <address@hidden>
Signed-off-by: Max Reitz <address@hidden>
 block.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 8104225..d090324 100644
--- a/block.c
+++ b/block.c
@@ -2226,9 +2226,23 @@ void bdrv_close_all(void)
 static void change_parent_backing_link(BlockDriverState *from,
                                        BlockDriverState *to)
-    BdrvChild *c, *next;
+    BdrvChild *c, *next, *to_c;
     QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
+        if (c->role == &child_backing) {
+            /* @from is generally not allowed to be a backing file, except for
+             * when @to is the overlay. In that case, @from may not be replaced
+             * by @to as @to's backing node. */
+            QLIST_FOREACH(to_c, &to->children, next) {
+                if (to_c == c) {
+                    break;
+                }
+            }
+            if (to_c) {
+                continue;
+            }
+        }
         assert(c->role != &child_backing);
         bdrv_replace_child(c, to);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]