diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/mirror.c | 33 |
1 files changed, 6 insertions, 27 deletions
diff --git a/block/mirror.c b/block/mirror.c index efca8fc177..23aa10e5bf 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -20,7 +20,6 @@ #include "qapi/qmp/qerror.h" #include "qemu/ratelimit.h" #include "qemu/bitmap.h" -#include "qemu/error-report.h" #define SLICE_TIME 100000000ULL /* ns */ #define MAX_IN_FLIGHT 16 @@ -466,24 +465,20 @@ static void mirror_exit(BlockJob *job, void *opaque) to_replace = s->to_replace; } - /* This was checked in mirror_start_job(), but meanwhile one of the - * nodes could have been newly attached to a BlockBackend. */ - if (bdrv_has_blk(to_replace) && bdrv_has_blk(s->target)) { - error_report("block job: Can't create node with two BlockBackends"); - data->ret = -EINVAL; - goto out; - } - if (bdrv_get_flags(s->target) != bdrv_get_flags(to_replace)) { bdrv_reopen(s->target, bdrv_get_flags(to_replace), NULL); } + + /* The mirror job has no requests in flight any more, but we need to + * drain potential other users of the BDS before changing the graph. */ + bdrv_drained_begin(s->target); bdrv_replace_in_backing_chain(to_replace, s->target); + bdrv_drained_end(s->target); + /* We just changed the BDS the job BB refers to */ blk_remove_bs(job->blk); blk_insert_bs(job->blk, src); } - -out: if (s->to_replace) { bdrv_op_unblock_all(s->to_replace, s->replace_blocker); error_free(s->replace_blocker); @@ -807,7 +802,6 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, bool is_none_mode, BlockDriverState *base) { MirrorBlockJob *s; - BlockDriverState *replaced_bs; if (granularity == 0) { granularity = bdrv_get_default_bitmap_granularity(target); @@ -824,21 +818,6 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, buf_size = DEFAULT_MIRROR_BUF_SIZE; } - /* We can't support this case as long as the block layer can't handle - * multiple BlockBackends per BlockDriverState. */ - if (replaces) { - replaced_bs = bdrv_lookup_bs(replaces, replaces, errp); - if (replaced_bs == NULL) { - return; - } - } else { - replaced_bs = bs; - } - if (bdrv_has_blk(replaced_bs) && bdrv_has_blk(target)) { - error_setg(errp, "Can't create node with two BlockBackends"); - return; - } - s = block_job_create(driver, bs, speed, cb, opaque, errp); if (!s) { return; |