aboutsummaryrefslogtreecommitdiff
path: root/block/mirror.c
diff options
context:
space:
mode:
authorAlberto Garcia <berto@igalia.com>2016-10-28 10:08:09 +0300
committerKevin Wolf <kwolf@redhat.com>2016-10-31 16:52:38 +0100
commitf3ede4b05d1407d48314f0edada5e402865e641e (patch)
tree91ef72785aa34c68df371e5b85b30083118b2fe8 /block/mirror.c
parent3e4c5122cbb881cd271314ef0782c4b6c57ab03d (diff)
block: Block all intermediate nodes in commit_active_start()
When block-commit is launched without the top parameter, it uses internally a mirror block job. In that case all intermediate nodes between the active and base nodes must be blocked as well. Signed-off-by: Alberto Garcia <berto@igalia.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/mirror.c')
-rw-r--r--block/mirror.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/block/mirror.c b/block/mirror.c
index 04765ad2ff..7e99f3a880 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -997,6 +997,14 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
}
block_job_add_bdrv(&s->common, target);
+ /* In commit_active_start() all intermediate nodes disappear, so
+ * any jobs in them must be blocked */
+ if (bdrv_chain_contains(bs, target)) {
+ BlockDriverState *iter;
+ for (iter = backing_bs(bs); iter != target; iter = backing_bs(iter)) {
+ block_job_add_bdrv(&s->common, iter);
+ }
+ }
s->common.co = qemu_coroutine_create(mirror_run, s);
trace_mirror_start(bs, s, s->common.co, opaque);