Commit 8cc6dc62 authored by Vladimir Sementsov-Ogievskiy's avatar Vladimir Sementsov-Ogievskiy Committed by Jeff Cody
Browse files

backup: init copy_bitmap from sync_bitmap for incremental



We should not copy non-dirty clusters in write notifiers. So,
initialize copy_bitmap from sync_bitmap.

Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: default avatarJohn Snow <jsnow@redhat.com>
Reviewed-by: default avatarJeff Cody <jcody@redhat.com>
Reviewed-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Message-id: 20171012135313.227864-4-vsementsov@virtuozzo.com
Signed-off-by: default avatarJeff Cody <jcody@redhat.com>
parent a193b0f0
Loading
Loading
Loading
Loading
+43 −1
Original line number Diff line number Diff line
@@ -422,6 +422,43 @@ out:
    return ret;
}

/* init copy_bitmap from sync_bitmap */
static void backup_incremental_init_copy_bitmap(BackupBlockJob *job)
{
    BdrvDirtyBitmapIter *dbi;
    int64_t offset;
    int64_t end = DIV_ROUND_UP(bdrv_dirty_bitmap_size(job->sync_bitmap),
                               job->cluster_size);

    dbi = bdrv_dirty_iter_new(job->sync_bitmap);
    while ((offset = bdrv_dirty_iter_next(dbi)) != -1) {
        int64_t cluster = offset / job->cluster_size;
        int64_t next_cluster;

        offset += bdrv_dirty_bitmap_granularity(job->sync_bitmap);
        if (offset >= bdrv_dirty_bitmap_size(job->sync_bitmap)) {
            hbitmap_set(job->copy_bitmap, cluster, end - cluster);
            break;
        }

        offset = bdrv_dirty_bitmap_next_zero(job->sync_bitmap, offset);
        if (offset == -1) {
            hbitmap_set(job->copy_bitmap, cluster, end - cluster);
            break;
        }

        next_cluster = DIV_ROUND_UP(offset, job->cluster_size);
        hbitmap_set(job->copy_bitmap, cluster, next_cluster - cluster);
        if (next_cluster >= end) {
            break;
        }

        bdrv_set_dirty_iter(dbi, next_cluster * job->cluster_size);
    }

    bdrv_dirty_iter_free(dbi);
}

static void coroutine_fn backup_run(void *opaque)
{
    BackupBlockJob *job = opaque;
@@ -435,7 +472,12 @@ static void coroutine_fn backup_run(void *opaque)

    nb_clusters = DIV_ROUND_UP(job->common.len, job->cluster_size);
    job->copy_bitmap = hbitmap_alloc(nb_clusters, 0);
    if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
        backup_incremental_init_copy_bitmap(job);
    } else {
        hbitmap_set(job->copy_bitmap, 0, nb_clusters);
    }


    job->before_write.notify = backup_before_write_notify;
    bdrv_add_before_write_notifier(bs, &job->before_write);