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@xxxxxxxxxx> --- 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