aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2019-05-13 11:06:38 -0400
committerKevin Wolf <kwolf@redhat.com>2019-06-04 15:20:41 +0200
commit4da26f138db06c9c6d7199d42bd3c2be552cb956 (patch)
tree510ec888d533c4524ac0d5612bf4c0b0c7b96113
parentac6fb43eae1f5029b51e0a3d975fe2111cc8b976 (diff)
blockdev: fix missed target unref for drive-backup
If the bitmap can't be used for whatever reason, we skip putting down the reference. Fix that. In practice, this means that if you attempt to gracefully exit QEMU after a backup command being rejected, bdrv_close_all will fail and tell you some unpleasant things via assert(). Reported-by: aihua liang <aliang@redhat.com> Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1703916 Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r--blockdev.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/blockdev.c b/blockdev.c
index 17c2d801d7..d88dc115f2 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3546,8 +3546,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
if (set_backing_hd) {
bdrv_set_backing_hd(target_bs, source, &local_err);
if (local_err) {
- bdrv_unref(target_bs);
- goto out;
+ goto unref;
}
}
@@ -3555,11 +3554,10 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
if (!bmap) {
error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap);
- bdrv_unref(target_bs);
- goto out;
+ goto unref;
}
if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) {
- goto out;
+ goto unref;
}
}
if (!backup->auto_finalize) {
@@ -3573,12 +3571,13 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
backup->sync, bmap, backup->compress,
backup->on_source_error, backup->on_target_error,
job_flags, NULL, NULL, txn, &local_err);
- bdrv_unref(target_bs);
if (local_err != NULL) {
error_propagate(errp, local_err);
- goto out;
+ goto unref;
}
+unref:
+ bdrv_unref(target_bs);
out:
aio_context_release(aio_context);
return job;