Ensure that the guest does not write anything to disk after cnt is read for the final time.
Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- Untested. block/mirror.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index 0e8f556..e57c246 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -562,8 +562,18 @@ static void coroutine_fn mirror_run(void *opaque) * mirror_populate runs. */ trace_mirror_before_drain(s, cnt); - bdrv_drain(bs); + bdrv_drained_begin(s->common.bs); cnt = bdrv_get_dirty_count(s->dirty_bitmap); + + if (cnt == 0) { + /* The two disks are in sync. Exit and report successful + * completion. + */ + assert(QLIST_EMPTY(&bs->tracked_requests)); + s->common.cancelled = false; + break; + } + bdrv_drained_end(s->common.bs); } ret = 0; @@ -576,13 +586,6 @@ static void coroutine_fn mirror_run(void *opaque) } else if (!should_complete) { delay_ns = (s->in_flight == 0 && cnt == 0 ? SLICE_TIME : 0); block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns); - } else if (cnt == 0) { - /* The two disks are in sync. Exit and report successful - * completion. - */ - assert(QLIST_EMPTY(&bs->tracked_requests)); - s->common.cancelled = false; - break; } last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); } @@ -608,9 +611,6 @@ immediate_exit: data = g_malloc(sizeof(*data)); data->ret = ret; - /* Before we switch to target in mirror_exit, make sure data doesn't - * change. */ - bdrv_drained_begin(s->common.bs); block_job_defer_to_main_loop(&s->common, mirror_exit, data); } -- 2.5.0