diff options
Diffstat (limited to 'block/backup-top.c')
-rw-r--r-- | block/backup-top.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/block/backup-top.c b/block/backup-top.c index 9aed2eb4c0..fa78f3256d 100644 --- a/block/backup-top.c +++ b/block/backup-top.c @@ -190,6 +190,7 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source, BlockDriverState *top = bdrv_new_open_driver(&bdrv_backup_top_filter, filter_node_name, BDRV_O_RDWR, errp); + bool appended = false; if (!top) { return NULL; @@ -212,8 +213,9 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source, bdrv_append(top, source, &local_err); if (local_err) { error_prepend(&local_err, "Cannot append backup-top filter: "); - goto append_failed; + goto fail; } + appended = true; /* * bdrv_append() finished successfully, now we can require permissions @@ -224,14 +226,14 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source, if (local_err) { error_prepend(&local_err, "Cannot set permissions for backup-top filter: "); - goto failed_after_append; + goto fail; } state->bcs = block_copy_state_new(top->backing, state->target, cluster_size, write_flags, &local_err); if (local_err) { error_prepend(&local_err, "Cannot create block-copy-state: "); - goto failed_after_append; + goto fail; } *bcs = state->bcs; @@ -239,14 +241,15 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source, return top; -failed_after_append: - state->active = false; - bdrv_backup_top_drop(top); +fail: + if (appended) { + state->active = false; + bdrv_backup_top_drop(top); + } else { + bdrv_unref(top); + } -append_failed: bdrv_drained_end(source); - bdrv_unref_child(top, state->target); - bdrv_unref(top); error_propagate(errp, local_err); return NULL; |