diff mbox

[1/2] block/mirror: Fix target backing BDS

Message ID 20160526134003.936-2-mreitz@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Max Reitz May 26, 2016, 1:40 p.m. UTC
Currently, we are trying to move the backing BDS from the source to the
target in bdrv_replace_in_backing_chain(). However, the conditions used
to decide when to move the backing BDS from source to target are not
really correct.

Basically, we do not have to set the target's backing BDS when doing a
commit operation (an active commit, to be specific) but we do have to
set it for every mirror operation (unless the target's backing BDS is
already the one it should have).

The decision when to adjust the target's backing BDS and what it should
be set to is something that the mirror code can do best, so let's do it
there.

Also, we do not need to drop the source's backing BDS. In most cases,
the source will be deleted after the mirroring operation anyway, and if
it is not, we probably want it to keep its own backing chain so it stays
valid.

Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block.c        |  8 --------
 block/mirror.c | 13 +++++++++++++
 2 files changed, 13 insertions(+), 8 deletions(-)
diff mbox

Patch

diff --git a/block.c b/block.c
index 736432f..7ae2766 100644
--- a/block.c
+++ b/block.c
@@ -2275,14 +2275,6 @@  void bdrv_replace_in_backing_chain(BlockDriverState *old, BlockDriverState *new)
 
     change_parent_backing_link(old, new);
 
-    /* Change backing files if a previously independent node is added to the
-     * chain. For active commit, we replace top by its own (indirect) backing
-     * file and don't do anything here so we don't build a loop. */
-    if (new->backing == NULL && !bdrv_chain_contains(backing_bs(old), new)) {
-        bdrv_set_backing_hd(new, backing_bs(old));
-        bdrv_set_backing_hd(old, NULL);
-    }
-
     bdrv_unref(old);
 }
 
diff --git a/block/mirror.c b/block/mirror.c
index 80fd3c7..bc65e54 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -482,6 +482,19 @@  static void mirror_exit(BlockJob *job, void *opaque)
         /* We just changed the BDS the job BB refers to */
         blk_remove_bs(job->blk);
         blk_insert_bs(job->blk, src);
+
+        /* Now we need to adjust the target's backing BDS. This is not necessary
+         * when having performed a commit operation.
+         * Note that we cannot do this adjustment before the call to
+         * bdrv_replace_in_backing_chain(), because we may end up using
+         * to_replace as the target's BDS, which makes it impossible to replace
+         * to_replace by the target afterwards */
+        if (!bdrv_chain_contains(backing_bs(to_replace), target_bs)) {
+            BlockDriverState *backing = s->is_none_mode ? to_replace : s->base;
+            if (backing_bs(target_bs) != backing) {
+                bdrv_set_backing_hd(target_bs, backing);
+            }
+        }
     }
     if (s->to_replace) {
         bdrv_op_unblock_all(s->to_replace, s->replace_blocker);