This will not touch loaded bitmaps, as they are alredy removed from the image.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- block/qcow2-bitmap.c | 38 ++++++++++++++++++++++++++++++++++++++ block/qcow2.c | 9 ++++++--- block/qcow2.h | 2 ++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 1c3abea..2642afe 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -624,6 +624,44 @@ out: return ret; } + +int qcow2_delete_bitmaps(BlockDriverState *bs) +{ + int ret; + BDRVQcow2State *s = bs->opaque; + uint8_t *dir; + uint64_t dir_size; + Qcow2BitmapDirEntry *e; + + if (s->nb_bitmaps == 0) { + /* No bitmaps - nothing to do */ + return 0; + } + + dir_size = s->bitmap_directory_size; + dir = directory_read(bs, s->bitmap_directory_offset, + s->bitmap_directory_size, NULL); + if (dir == NULL) { + ret = -EINVAL; + goto out; + } + + ret = directory_update(bs, NULL, 0, 0); + if (ret < 0) { + goto out; + } + + /* to be consistent, free bitmap only after successfull directory update */ + for_each_bitmap_dir_entry(e, dir, dir_size) { + free_bitmap_clusters(bs, e); + } + +out: + g_free(dir); + + return ret; +} + /* store_bitmap_data() * Store bitmap to image, filling bitamp table accordingly. */ diff --git a/block/qcow2.c b/block/qcow2.c index 8238205..aa967ed 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2592,9 +2592,12 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset) /* cannot proceed if image has bitmaps */ if (s->nb_bitmaps) { - /* FIXME */ - error_report("Can't resize an image which has bitmaps"); - return -ENOTSUP; + /* FIXME: not loaded bitmaps will be lost */ + ret = qcow2_delete_bitmaps(bs); + if (ret < 0) { + error_report("Can't remove bitmaps from qcow2 on truncate"); + return ret; + } } /* shrinking is currently not supported */ diff --git a/block/qcow2.h b/block/qcow2.h index dfcf4c6..af18efc 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -606,6 +606,8 @@ int qcow2_read_snapshots(BlockDriverState *bs); /* qcow2-bitmap.c functions */ int qcow2_read_bitmaps(BlockDriverState *bs, Error **errp); +int qcow2_delete_bitmaps(BlockDriverState *bs); + /* qcow2-cache.c functions */ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables); int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c); -- 1.8.3.1