16.01.2019 16:05, Max Reitz wrote: > On 14.01.19 15:48, Vladimir Sementsov-Ogievskiy wrote: >> 14.01.2019 17:13, Max Reitz wrote: >>> On 14.01.19 15:01, Vladimir Sementsov-Ogievskiy wrote: >>>> 14.01.2019 16:10, Max Reitz wrote: >>>>> On 29.12.18 13:20, Vladimir Sementsov-Ogievskiy wrote: >>>>>> Simplify backup_incremental_init_copy_bitmap using the function >>>>>> bdrv_dirty_bitmap_next_dirty_area. >>>>>> >>>>>> Note: move to job->len instead of bitmap size: it should not matter but >>>>>> less code. >>>>>> >>>>>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> >>>>>> --- >>>>>> block/backup.c | 40 ++++++++++++---------------------------- >>>>>> 1 file changed, 12 insertions(+), 28 deletions(-) >>>>> >>>>> Overall: What is this function even supposed to do? To me, it looks >>>>> like it marks all areas in job->copy_bitmap dirty that are dirty in >>>>> job->sync_bitmap. >>>>> >>>>> If so, wouldn't just replacing this by hbitmap_merge() simplify things >>>>> further? >>>>> >>>>>> diff --git a/block/backup.c b/block/backup.c >>>>>> index 435414e964..fbe7ce19e1 100644 >>>>>> --- a/block/backup.c >>>>>> +++ b/block/backup.c >>>>>> @@ -406,43 +406,27 @@ static int coroutine_fn >>>>>> backup_run_incremental(BackupBlockJob *job) >>>>> >>>>> [...] >>>>> >>>>>> + while (bdrv_dirty_bitmap_next_dirty_area(job->sync_bitmap, >>>>>> + &offset, &bytes)) >>>>>> + { >>>>>> + uint64_t cluster = offset / job->cluster_size; >>>>>> + uint64_t last_cluster = (offset + bytes) / job->cluster_size; >>>>>> >>>>>> - next_cluster = DIV_ROUND_UP(offset, job->cluster_size); >>>>>> - hbitmap_set(job->copy_bitmap, cluster, next_cluster - cluster); >>>>>> - if (next_cluster >= end) { >>>>>> + hbitmap_set(job->copy_bitmap, cluster, last_cluster - cluster + >>>>>> 1); >>>>> >>>>> Why the +1? Shouldn't the division for last_cluster round up instead? >>>>> >>>>>> + >>>>>> + offset = (last_cluster + 1) * job->cluster_size; >>>>> >>>>> Same here. >>>> >>>> last cluster is not "end", but it's last dirty cluster. so number of dirty >>>> clusters is last_cluster - cluster + 1, and next offset is calculated >>>> through +1 too. >>>> >>>> If I round up division result, I'll get last for most cases, but "end" >>>> (next after the last), for the case when offset % job->cluster_size == 0, >>>> so, how to use it? >>> >>> Doesn't bdrv_dirty_bitmap_next_dirty_area() return a range [offset, >>> offset + bytes), i.e. where "offset + bytes" is the first clean offset? >> >> oops, you are right. then I need >> uint64_t last_cluster = (offset + bytes - 1) / job->cluster_size; > > That, or you just use a rounding up division and rename it from > last_cluster to end_cluster or first_clean_cluster or something (and > subsequently drop the +1s).
This will not work, as ((offset + bytes) / job->cluster_size) is not first clean cluster or end cluster. It's a cluster, where is first clean bit located, but it may have dirty bits too (or, may not). So, to rewrite based on end_cluster, it should be calculated as (offset + bytes - 1) / job->cluster_size + 1 and, I'm going to do so, one "+1" instead of two, and, may be, a bit more understandable. -- Best regards, Vladimir