aboutsummaryrefslogtreecommitdiff
path: root/util/hbitmap.c
diff options
context:
space:
mode:
authorVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>2020-02-05 14:20:38 +0300
committerJohn Snow <jsnow@redhat.com>2020-03-18 14:03:46 -0400
commit299ea9ff01a8452dd14a042d700d8651370f5314 (patch)
treebf5d93cf9bbb8dac37627c0445d954fb8c520bce /util/hbitmap.c
parent9399c54b7557a20bc78aaecf2d51983cfafbbf41 (diff)
downloadqemu-299ea9ff01a8452dd14a042d700d8651370f5314.zip
qemu-299ea9ff01a8452dd14a042d700d8651370f5314.tar.gz
qemu-299ea9ff01a8452dd14a042d700d8651370f5314.tar.bz2
block/dirty-bitmap: improve _next_dirty_area API
Firstly, _next_dirty_area is for scenarios when we may contiguously search for next dirty area inside some limited region, so it is more comfortable to specify "end" which should not be recalculated on each iteration. Secondly, let's add a possibility to limit resulting area size, not limiting searching area. This will be used in NBD code in further commit. (Note that now bdrv_dirty_bitmap_next_dirty_area is unused) Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com> Message-id: 20200205112041.6003-8-vsementsov@virtuozzo.com Signed-off-by: John Snow <jsnow@redhat.com>
Diffstat (limited to 'util/hbitmap.c')
-rw-r--r--util/hbitmap.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/util/hbitmap.c b/util/hbitmap.c
index 883ca48..305b894 100644
--- a/util/hbitmap.c
+++ b/util/hbitmap.c
@@ -270,22 +270,33 @@ int64_t hbitmap_next_zero(const HBitmap *hb, int64_t start, int64_t count)
return res;
}
-bool hbitmap_next_dirty_area(const HBitmap *hb, int64_t *start, int64_t *count)
+bool hbitmap_next_dirty_area(const HBitmap *hb, int64_t start, int64_t end,
+ int64_t max_dirty_count,
+ int64_t *dirty_start, int64_t *dirty_count)
{
- int64_t area_start, area_end;
+ int64_t next_zero;
- area_start = hbitmap_next_dirty(hb, *start, *count);
- if (area_start < 0) {
+ assert(start >= 0 && end >= 0 && max_dirty_count > 0);
+
+ end = MIN(end, hb->orig_size);
+ if (start >= end) {
return false;
}
- area_end = hbitmap_next_zero(hb, area_start, *start + *count - area_start);
- if (area_end < 0) {
- area_end = MIN(hb->orig_size, *start + *count);
+ start = hbitmap_next_dirty(hb, start, end - start);
+ if (start < 0) {
+ return false;
}
- *start = area_start;
- *count = area_end - area_start;
+ end = start + MIN(end - start, max_dirty_count);
+
+ next_zero = hbitmap_next_zero(hb, start, end - start);
+ if (next_zero >= 0) {
+ end = next_zero;
+ }
+
+ *dirty_start = start;
+ *dirty_count = end - start;
return true;
}
@@ -841,16 +852,15 @@ bool hbitmap_can_merge(const HBitmap *a, const HBitmap *b)
*/
static void hbitmap_sparse_merge(HBitmap *dst, const HBitmap *src)
{
- int64_t offset = 0;
- int64_t count = src->orig_size;
+ int64_t offset;
+ int64_t count;
- while (hbitmap_next_dirty_area(src, &offset, &count)) {
+ for (offset = 0;
+ hbitmap_next_dirty_area(src, offset, src->orig_size, INT64_MAX,
+ &offset, &count);
+ offset += count)
+ {
hbitmap_set(dst, offset, count);
- offset += count;
- if (offset >= src->orig_size) {
- break;
- }
- count = src->orig_size - offset;
}
}