aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/backup.c27
-rw-r--r--qapi/block-core.json5
2 files changed, 23 insertions, 9 deletions
diff --git a/block/backup.c b/block/backup.c
index 474f8eeae2..2be570c0bf 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -278,18 +278,29 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
{
BdrvDirtyBitmap *bm;
BlockDriverState *bs = blk_bs(job->common.blk);
+ bool sync = (((ret == 0) || (job->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS)) \
+ && (job->bitmap_mode != BITMAP_SYNC_MODE_NEVER));
- if (ret < 0 || job->bitmap_mode == BITMAP_SYNC_MODE_NEVER) {
+ if (sync) {
/*
- * Failure, or we don't want to synchronize the bitmap.
- * Merge the successor back into the parent, delete nothing.
+ * We succeeded, or we always intended to sync the bitmap.
+ * Delete this bitmap and install the child.
*/
- bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
- assert(bm);
- } else {
- /* Everything is fine, delete this bitmap and install the backup. */
bm = bdrv_dirty_bitmap_abdicate(bs, job->sync_bitmap, NULL);
- assert(bm);
+ } else {
+ /*
+ * We failed, or we never intended to sync the bitmap anyway.
+ * Merge the successor back into the parent, keeping all data.
+ */
+ bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
+ }
+
+ assert(bm);
+
+ if (ret < 0 && job->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS) {
+ /* If we failed and synced, merge in the bits we didn't copy: */
+ bdrv_dirty_bitmap_merge_internal(bm, job->copy_bitmap,
+ NULL, true);
}
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 06e34488a3..8344fbe203 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1149,10 +1149,13 @@
# @never: The bitmap is never synchronized with the operation, and is
# treated solely as a read-only manifest of blocks to copy.
#
+# @always: The bitmap is always synchronized with the operation,
+# regardless of whether or not the operation was successful.
+#
# Since: 4.2
##
{ 'enum': 'BitmapSyncMode',
- 'data': ['on-success', 'never'] }
+ 'data': ['on-success', 'never', 'always'] }
##
# @MirrorCopyMode: