diff options
Diffstat (limited to 'block/backup.c')
| -rw-r--r-- | block/backup.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/block/backup.c b/block/backup.c index 715e1d3be8..b26c22c4b8 100644 --- a/block/backup.c +++ b/block/backup.c @@ -202,22 +202,31 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job, cow_request_begin(&cow_request, job, start, end); while (start < end) { + int64_t dirty_end; + if (!hbitmap_get(job->copy_bitmap, start)) { trace_backup_do_cow_skip(job, start); start += job->cluster_size; continue; /* already copied */ } + dirty_end = hbitmap_next_zero(job->copy_bitmap, start, (end - start)); + if (dirty_end < 0) { + dirty_end = end; + } + trace_backup_do_cow_process(job, start); if (job->use_copy_range) { - ret = backup_cow_with_offload(job, start, end, is_write_notifier); + ret = backup_cow_with_offload(job, start, dirty_end, + is_write_notifier); if (ret < 0) { job->use_copy_range = false; } } if (!job->use_copy_range) { - ret = backup_cow_with_bounce_buffer(job, start, end, is_write_notifier, + ret = backup_cow_with_bounce_buffer(job, start, dirty_end, + is_write_notifier, error_is_read, &bounce_buffer); } if (ret < 0) { @@ -648,7 +657,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, job->cluster_size = cluster_size; job->copy_bitmap = copy_bitmap; copy_bitmap = NULL; - job->use_copy_range = true; + job->use_copy_range = !compress; /* compression isn't supported for it */ job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk), blk_get_max_transfer(job->target)); job->copy_range_size = MAX(job->cluster_size, |