diff options
Diffstat (limited to 'block/mirror.c')
-rw-r--r-- | block/mirror.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/block/mirror.c b/block/mirror.c index 6e8caf4..b344182 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -761,10 +761,14 @@ static int mirror_exit_common(Job *job) bdrv_graph_rdlock_main_loop(); bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing, &error_abort); + bdrv_graph_rdunlock_main_loop(); if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) { BlockDriverState *backing; - BlockDriverState *unfiltered_target = bdrv_skip_filters(target_bs); + BlockDriverState *unfiltered_target; + + bdrv_graph_wrlock_drained(); + unfiltered_target = bdrv_skip_filters(target_bs); backing = s->sync_mode == MIRROR_SYNC_MODE_NONE ? src : s->base; if (bdrv_cow_bs(unfiltered_target) != backing) { @@ -775,16 +779,18 @@ static int mirror_exit_common(Job *job) ret = -EPERM; } } + bdrv_graph_wrunlock(); } else if (!abort && s->backing_mode == MIRROR_OPEN_BACKING_CHAIN) { + bdrv_graph_rdlock_main_loop(); assert(!bdrv_backing_chain_next(target_bs)); ret = bdrv_open_backing_file(bdrv_skip_filters(target_bs), NULL, "backing", &local_err); + bdrv_graph_rdunlock_main_loop(); if (ret < 0) { error_report_err(local_err); local_err = NULL; } } - bdrv_graph_rdunlock_main_loop(); if (s->should_complete && !abort) { BlockDriverState *to_replace = s->to_replace ?: src; @@ -2014,15 +2020,13 @@ static BlockJob *mirror_start_job( */ bdrv_disable_dirty_bitmap(s->dirty_bitmap); - bdrv_drain_all_begin(); - bdrv_graph_wrlock(); + bdrv_graph_wrlock_drained(); ret = block_job_add_bdrv(&s->common, "source", bs, 0, BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE | BLK_PERM_CONSISTENT_READ, errp); if (ret < 0) { bdrv_graph_wrunlock(); - bdrv_drain_all_end(); goto fail; } @@ -2068,19 +2072,16 @@ static BlockJob *mirror_start_job( iter_shared_perms, errp); if (ret < 0) { bdrv_graph_wrunlock(); - bdrv_drain_all_end(); goto fail; } } if (bdrv_freeze_backing_chain(mirror_top_bs, target, errp) < 0) { bdrv_graph_wrunlock(); - bdrv_drain_all_end(); goto fail; } } bdrv_graph_wrunlock(); - bdrv_drain_all_end(); QTAILQ_INIT(&s->ops_in_flight); |