dirty-bitmap: add bdrv_dirty_bitmap_next_dirty_area
The function alters bdrv_dirty_iter_next_area(), which is wrong and less efficient (see further commit "block/mirror: fix and improve do_sync_target_write" for description). Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
This commit is contained in:
parent
fa9c2da294
commit
a78a1a48cd
|
@ -787,6 +787,12 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset,
|
||||||
return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
|
return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
|
||||||
|
uint64_t *offset, uint64_t *bytes)
|
||||||
|
{
|
||||||
|
return hbitmap_next_dirty_area(bitmap->bitmap, offset, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
||||||
HBitmap **backup, Error **errp)
|
HBitmap **backup, Error **errp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,6 +101,8 @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
|
||||||
char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp);
|
char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp);
|
||||||
int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset,
|
int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset,
|
||||||
uint64_t bytes);
|
uint64_t bytes);
|
||||||
|
bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
|
||||||
|
uint64_t *offset, uint64_t *bytes);
|
||||||
BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
|
BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
|
||||||
BdrvDirtyBitmap *bitmap,
|
BdrvDirtyBitmap *bitmap,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
|
@ -311,6 +311,22 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi);
|
||||||
*/
|
*/
|
||||||
int64_t hbitmap_next_zero(const HBitmap *hb, uint64_t start, uint64_t count);
|
int64_t hbitmap_next_zero(const HBitmap *hb, uint64_t start, uint64_t count);
|
||||||
|
|
||||||
|
/* hbitmap_next_dirty_area:
|
||||||
|
* @hb: The HBitmap to operate on
|
||||||
|
* @start: in-out parameter.
|
||||||
|
* in: the offset to start from
|
||||||
|
* out: (if area found) start of found area
|
||||||
|
* @count: in-out parameter.
|
||||||
|
* in: length of requested region
|
||||||
|
* out: length of found area
|
||||||
|
*
|
||||||
|
* If dirty area found within [@start, @start + @count), returns true and sets
|
||||||
|
* @offset and @bytes appropriately. Otherwise returns false and leaves @offset
|
||||||
|
* and @bytes unchanged.
|
||||||
|
*/
|
||||||
|
bool hbitmap_next_dirty_area(const HBitmap *hb, uint64_t *start,
|
||||||
|
uint64_t *count);
|
||||||
|
|
||||||
/* hbitmap_create_meta:
|
/* hbitmap_create_meta:
|
||||||
* Create a "meta" hbitmap to track dirtiness of the bits in this HBitmap.
|
* Create a "meta" hbitmap to track dirtiness of the bits in this HBitmap.
|
||||||
* The caller owns the created bitmap and must call hbitmap_free_meta(hb) to
|
* The caller owns the created bitmap and must call hbitmap_free_meta(hb) to
|
||||||
|
|
|
@ -246,6 +246,45 @@ int64_t hbitmap_next_zero(const HBitmap *hb, uint64_t start, uint64_t count)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hbitmap_next_dirty_area(const HBitmap *hb, uint64_t *start,
|
||||||
|
uint64_t *count)
|
||||||
|
{
|
||||||
|
HBitmapIter hbi;
|
||||||
|
int64_t firt_dirty_off, area_end;
|
||||||
|
uint32_t granularity = 1UL << hb->granularity;
|
||||||
|
uint64_t end;
|
||||||
|
|
||||||
|
if (*start >= hb->orig_size || *count == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = *count > hb->orig_size - *start ? hb->orig_size : *start + *count;
|
||||||
|
|
||||||
|
hbitmap_iter_init(&hbi, hb, *start);
|
||||||
|
firt_dirty_off = hbitmap_iter_next(&hbi, false);
|
||||||
|
|
||||||
|
if (firt_dirty_off < 0 || firt_dirty_off >= end) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firt_dirty_off + granularity >= end) {
|
||||||
|
area_end = end;
|
||||||
|
} else {
|
||||||
|
area_end = hbitmap_next_zero(hb, firt_dirty_off + granularity,
|
||||||
|
end - firt_dirty_off - granularity);
|
||||||
|
if (area_end < 0) {
|
||||||
|
area_end = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firt_dirty_off > *start) {
|
||||||
|
*start = firt_dirty_off;
|
||||||
|
}
|
||||||
|
*count = area_end - *start;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool hbitmap_empty(const HBitmap *hb)
|
bool hbitmap_empty(const HBitmap *hb)
|
||||||
{
|
{
|
||||||
return hb->count == 0;
|
return hb->count == 0;
|
||||||
|
|
Loading…
Reference in New Issue