Re: [Qemu-devel] [PATCH v3 12/16] block/dirty-bitmap: Add bdrv_dirty_iter_next_area

2018-03-15 Thread John Snow


On 02/28/2018 01:05 PM, Max Reitz wrote:
> This new function allows to look for a consecutively dirty area in a
> dirty bitmap.
> 
> Signed-off-by: Max Reitz 
> ---
>  include/block/dirty-bitmap.h |  2 ++
>  block/dirty-bitmap.c | 55 
> 
>  2 files changed, 57 insertions(+)
> 
> diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
> index e3f4bbf51d..8c8f63e722 100644
> --- a/include/block/dirty-bitmap.h
> +++ b/include/block/dirty-bitmap.h
> @@ -79,6 +79,8 @@ void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
>  void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
>  int64_t offset, int64_t bytes);
>  int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
> +bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t 
> max_offset,
> +   uint64_t *offset, int *bytes);
>  void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t offset);
>  int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
>  int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
> diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
> index d8e999226e..5d6b8dba89 100644
> --- a/block/dirty-bitmap.c
> +++ b/block/dirty-bitmap.c
> @@ -496,6 +496,61 @@ int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
>  return hbitmap_iter_next(>hbi, true);
>  }
>  
> +/**
> + * Return the next consecutively dirty area in the dirty bitmap
> + * belonging to the given iterator @iter.
> + *
> + * @max_offset: Maximum value that may be returned for
> + *  *offset + *bytes
> + * @offset: Will contain the start offset of the next dirty area
> + * @bytes:  Will contain the length of the next dirty area
> + *
> + * Returns: True if a dirty area could be found before max_offset
> + *  (which means that *offset and *bytes then contain valid
> + *  values), false otherwise.
> + *
> + * Note that @iter is never advanced if false is returned.  If an area
> + * is found (which means that true is returned), it will be advanced
> + * past that area.
> + */
> +bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t 
> max_offset,
> +   uint64_t *offset, int *bytes)
> +{
> +uint32_t granularity = bdrv_dirty_bitmap_granularity(iter->bitmap);
> +uint64_t gran_max_offset;
> +int64_t ret;
> +int size;
> +
> +if (max_offset == iter->bitmap->size) {
> +/* If max_offset points to the image end, round it up by the
> + * bitmap granularity */
> +gran_max_offset = ROUND_UP(max_offset, granularity);
> +} else {
> +gran_max_offset = max_offset;
> +}
> +
> +ret = hbitmap_iter_next(>hbi, false);
> +if (ret < 0 || ret + granularity > gran_max_offset) {
> +return false;
> +}
> +
> +*offset = ret;
> +size = 0;
> +
> +assert(granularity <= INT_MAX);
> +
> +do {
> +/* Advance iterator */
> +ret = hbitmap_iter_next(>hbi, true);
> +size += granularity;
> +} while (ret + granularity <= gran_max_offset &&
> + hbitmap_iter_next(>hbi, false) == ret + granularity &&
> + size <= INT_MAX - granularity);
> +
> +*bytes = MIN(size, max_offset - *offset);
> +return true;
> +}
> +
>  /* Called within bdrv_dirty_bitmap_lock..unlock */
>  void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
>int64_t offset, int64_t bytes)
> 

10, 11, 12:

Reviewed-by: John Snow 



[Qemu-devel] [PATCH v3 12/16] block/dirty-bitmap: Add bdrv_dirty_iter_next_area

2018-02-28 Thread Max Reitz
This new function allows to look for a consecutively dirty area in a
dirty bitmap.

Signed-off-by: Max Reitz 
---
 include/block/dirty-bitmap.h |  2 ++
 block/dirty-bitmap.c | 55 
 2 files changed, 57 insertions(+)

diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index e3f4bbf51d..8c8f63e722 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -79,6 +79,8 @@ void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
 int64_t offset, int64_t bytes);
 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
+bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t max_offset,
+   uint64_t *offset, int *bytes);
 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t offset);
 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index d8e999226e..5d6b8dba89 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -496,6 +496,61 @@ int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
 return hbitmap_iter_next(>hbi, true);
 }
 
+/**
+ * Return the next consecutively dirty area in the dirty bitmap
+ * belonging to the given iterator @iter.
+ *
+ * @max_offset: Maximum value that may be returned for
+ *  *offset + *bytes
+ * @offset: Will contain the start offset of the next dirty area
+ * @bytes:  Will contain the length of the next dirty area
+ *
+ * Returns: True if a dirty area could be found before max_offset
+ *  (which means that *offset and *bytes then contain valid
+ *  values), false otherwise.
+ *
+ * Note that @iter is never advanced if false is returned.  If an area
+ * is found (which means that true is returned), it will be advanced
+ * past that area.
+ */
+bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t max_offset,
+   uint64_t *offset, int *bytes)
+{
+uint32_t granularity = bdrv_dirty_bitmap_granularity(iter->bitmap);
+uint64_t gran_max_offset;
+int64_t ret;
+int size;
+
+if (max_offset == iter->bitmap->size) {
+/* If max_offset points to the image end, round it up by the
+ * bitmap granularity */
+gran_max_offset = ROUND_UP(max_offset, granularity);
+} else {
+gran_max_offset = max_offset;
+}
+
+ret = hbitmap_iter_next(>hbi, false);
+if (ret < 0 || ret + granularity > gran_max_offset) {
+return false;
+}
+
+*offset = ret;
+size = 0;
+
+assert(granularity <= INT_MAX);
+
+do {
+/* Advance iterator */
+ret = hbitmap_iter_next(>hbi, true);
+size += granularity;
+} while (ret + granularity <= gran_max_offset &&
+ hbitmap_iter_next(>hbi, false) == ret + granularity &&
+ size <= INT_MAX - granularity);
+
+*bytes = MIN(size, max_offset - *offset);
+return true;
+}
+
 /* Called within bdrv_dirty_bitmap_lock..unlock */
 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
   int64_t offset, int64_t bytes)
-- 
2.14.3