From ebf4cfdb6b33d07e53ceb0c883ca9a2a90f37eef Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: <27a73856ecc481c66c7afac8171f753887f32e31.1342518105.git.minovotn@redhat.com> References: <27a73856ecc481c66c7afac8171f753887f32e31.1342518105.git.minovotn@redhat.com> From: Jeffrey Cody Date: Wed, 30 May 2012 20:56:50 +0200 Subject: [PATCH 05/41] block: don't create mirror block job if the target bdrv_open() fails RH-Author: Jeffrey Cody Message-id: <42d29a954aec142354dbf88ddfcf6f8e4dc2fe62.1338408171.git.jcody@redhat.com> Patchwork-id: 39862 O-Subject: [RHEL6.4 qemu-kvm PATCH] block: don't create mirror block job if the target bdrv_open() fails Bugzilla: 814102 RH-Acked-by: Paolo Bonzini RH-Acked-by: Kevin Wolf RH-Acked-by: Luiz Capitulino The function mirror_start() creates a block job, and then opens the BDS. It returns on error from bdrv_open(), which leaves the block job orphaned, and the BDS 'in use'. This patch makes sure that we don't create the block job at all if the bdrv_open() fails - so the bdrv_open() is attempted first, and then the block job is created if bdrv_open() was successful. BZ: 814102 Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=4464544 Upstream: block-mirror is not upstream yet, but I replied to the relevant patch from Paolo upstream with the same code that is in the patch below. Since downstream is already divergent w.r.t mirroring, I am going ahead and submitting this fix for RHEL 6.4. Signed-off-by: Jeff Cody --- block/mirror.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) Signed-off-by: Michal Novotny --- block/mirror.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index ee546db..49649b4 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -263,28 +263,34 @@ int mirror_start(BlockDriverState *bs, void *opaque, bool full) { MirrorBlockJob *s; - int ret; + BlockDriverState *target_bs; + int ret = 0; - s = block_job_create(&mirror_job_type, bs, speed, cb, opaque); - if (!s) { - return -EBUSY; /* bs must already be in use */ - } - s->target = bdrv_new(""); - ret = bdrv_open(s->target, target, + target_bs = bdrv_new(""); + ret = bdrv_open(target_bs, target, flags | BDRV_O_NO_BACKING | BDRV_O_NO_FLUSH | BDRV_O_CACHE_WB, drv); if (ret < 0) { - bdrv_delete(s->target); - return ret; + bdrv_delete(target_bs); + goto exit; } + s = block_job_create(&mirror_job_type, bs, speed, cb, opaque); + if (!s) { + bdrv_delete(target_bs); + ret = -EBUSY; /* bs must already be in use */ + goto exit; + } + + s->target = target_bs; s->full = full; bdrv_set_dirty_tracking(bs, true); s->common.co = qemu_coroutine_create(mirror_run); trace_mirror_start(bs, s, s->common.co, opaque); - return 0; +exit: + return ret; } void mirror_abort(BlockDriverState *bs) -- 1.7.10.4