Commit c334e897 authored by Vladimir Sementsov-Ogievskiy's avatar Vladimir Sementsov-Ogievskiy Committed by Max Reitz
Browse files

block/backup: unify different modes code path



Do full, top and incremental mode copying all in one place. This
unifies the code path and helps further improvements.

Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Message-id: 20190429090842.57910-5-vsementsov@virtuozzo.com
Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
parent 9eb5a248
Loading
Loading
Loading
Loading
+10 −33
Original line number Diff line number Diff line
@@ -384,15 +384,23 @@ static bool bdrv_is_unallocated_range(BlockDriverState *bs,
    return offset >= end;
}

static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
static int coroutine_fn backup_loop(BackupBlockJob *job)
{
    int ret;
    bool error_is_read;
    int64_t offset;
    HBitmapIter hbi;
    BlockDriverState *bs = blk_bs(job->common.blk);

    hbitmap_iter_init(&hbi, job->copy_bitmap, 0);
    while ((offset = hbitmap_iter_next(&hbi)) != -1) {
        if (job->sync_mode == MIRROR_SYNC_MODE_TOP &&
            bdrv_is_unallocated_range(bs, offset, job->cluster_size))
        {
            hbitmap_reset(job->copy_bitmap, offset, job->cluster_size);
            continue;
        }

        do {
            if (yield_and_check(job)) {
                return 0;
@@ -437,7 +445,6 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
    BlockDriverState *bs = blk_bs(s->common.blk);
    int64_t offset;
    int ret = 0;

    QLIST_INIT(&s->inflight_reqs);
@@ -462,38 +469,8 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
             * notify callback service CoW requests. */
            job_yield(job);
        }
    } else if (s->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
        ret = backup_run_incremental(s);
    } else {
        /* Both FULL and TOP SYNC_MODE's require copying.. */
        for (offset = 0; offset < s->len;
             offset += s->cluster_size) {
            bool error_is_read;

            if (yield_and_check(s)) {
                break;
            }

            if (s->sync_mode == MIRROR_SYNC_MODE_TOP &&
                bdrv_is_unallocated_range(bs, offset, s->cluster_size))
            {
                continue;
            }

            ret = backup_do_cow(s, offset, s->cluster_size,
                                &error_is_read, false);
            if (ret < 0) {
                /* Depending on error action, fail now or retry cluster */
                BlockErrorAction action =
                    backup_error_action(s, error_is_read, -ret);
                if (action == BLOCK_ERROR_ACTION_REPORT) {
                    break;
    } else {
                    offset -= s->cluster_size;
                    continue;
                }
            }
        }
        ret = backup_loop(s);
    }

    notifier_with_return_remove(&s->before_write);