diff options
author | John Snow <jsnow@redhat.com> | 2019-05-13 11:06:38 -0400 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2019-06-04 15:20:41 +0200 |
commit | 4da26f138db06c9c6d7199d42bd3c2be552cb956 (patch) | |
tree | 510ec888d533c4524ac0d5612bf4c0b0c7b96113 | |
parent | ac6fb43eae1f5029b51e0a3d975fe2111cc8b976 (diff) | |
download | qemu-4da26f138db06c9c6d7199d42bd3c2be552cb956.zip qemu-4da26f138db06c9c6d7199d42bd3c2be552cb956.tar.gz qemu-4da26f138db06c9c6d7199d42bd3c2be552cb956.tar.bz2 |
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.c | 13 |
1 files changed, 6 insertions, 7 deletions
@@ -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; |