mirror of
https://github.com/mii443/qemu.git
synced 2025-08-22 23:25:48 +00:00
block: Resize bitmaps on bdrv_truncate
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-id: 1429314609-29776-16-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
@ -400,6 +400,54 @@ HBitmap *hbitmap_alloc(uint64_t size, int granularity)
|
||||
return hb;
|
||||
}
|
||||
|
||||
void hbitmap_truncate(HBitmap *hb, uint64_t size)
|
||||
{
|
||||
bool shrink;
|
||||
unsigned i;
|
||||
uint64_t num_elements = size;
|
||||
uint64_t old;
|
||||
|
||||
/* Size comes in as logical elements, adjust for granularity. */
|
||||
size = (size + (1ULL << hb->granularity) - 1) >> hb->granularity;
|
||||
assert(size <= ((uint64_t)1 << HBITMAP_LOG_MAX_SIZE));
|
||||
shrink = size < hb->size;
|
||||
|
||||
/* bit sizes are identical; nothing to do. */
|
||||
if (size == hb->size) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're losing bits, let's clear those bits before we invalidate all of
|
||||
* our invariants. This helps keep the bitcount consistent, and will prevent
|
||||
* us from carrying around garbage bits beyond the end of the map.
|
||||
*/
|
||||
if (shrink) {
|
||||
/* Don't clear partial granularity groups;
|
||||
* start at the first full one. */
|
||||
uint64_t start = QEMU_ALIGN_UP(num_elements, 1 << hb->granularity);
|
||||
uint64_t fix_count = (hb->size << hb->granularity) - start;
|
||||
|
||||
assert(fix_count);
|
||||
hbitmap_reset(hb, start, fix_count);
|
||||
}
|
||||
|
||||
hb->size = size;
|
||||
for (i = HBITMAP_LEVELS; i-- > 0; ) {
|
||||
size = MAX(BITS_TO_LONGS(size), 1);
|
||||
if (hb->sizes[i] == size) {
|
||||
break;
|
||||
}
|
||||
old = hb->sizes[i];
|
||||
hb->sizes[i] = size;
|
||||
hb->levels[i] = g_realloc(hb->levels[i], size * sizeof(unsigned long));
|
||||
if (!shrink) {
|
||||
memset(&hb->levels[i][old], 0x00,
|
||||
(size - old) * sizeof(*hb->levels[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given HBitmaps A and B, let A := A (BITOR) B.
|
||||
* Bitmap B will not be modified.
|
||||
|
Reference in New Issue
Block a user