Rather than reimplement everything manually use virBitmapBuffsize to
find the current number of units, realloc the buffer and clear the tail
using virBitmapClearTail().
This fixes a corner case where the buffer would be over-allocated by one
unit when shrinking to the boundary of the unit size.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/util/virbitmap.c | 34 +++++++---------------------------
1 file changed, 7 insertions(+), 27 deletions(-)
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
index 35cf729a22..138c1ac5af 100644
--- a/src/util/virbitmap.c
+++ b/src/util/virbitmap.c
@@ -1187,33 +1187,13 @@ void
virBitmapShrink(virBitmap *map,
size_t b)
{
- size_t toremove;
- size_t nl = 0;
- size_t nb = 0;
-
- if (!map)
- return;
-
- if (map->nbits >= b)
- map->nbits = b;
-
- nl = map->nbits / VIR_BITMAP_BITS_PER_UNIT;
- nb = map->nbits % VIR_BITMAP_BITS_PER_UNIT;
-
- /* If we're at the end of the allocation the attempt to clear
'map->nbit'
- * and further would be beyond the end of the bitmap */
- if (nl >= map->map_alloc)
+ if (!map ||
+ map->nbits <= b)
return;
- map->map[nl] &= ((1UL << nb) - 1);
-
- toremove = map->map_alloc - (nl + 1);
-
- if (toremove == 0)
- return;
-
- VIR_SHRINK_N(map->map, map->map_alloc, toremove);
-
- /* length needs to be fixed as well */
- map->map_len = map->map_alloc;
+ map->nbits = b;
+ map->map_len = virBitmapBuffsize(b);
+ map->map = g_renew(unsigned long, map->map, map->map_len);
+ map->map_alloc = map->map_len;
+ virBitmapClearTail(map);
}
--
2.47.0