diff options
Diffstat (limited to 'block/backup.c')
-rw-r--r-- | block/backup.c | 27 |
1 files changed, 19 insertions, 8 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); } } |