|
@@ -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) {
|