Implement bdrv_make_empty() by making all clusters in the image fall through to the backing file (via the now modified discard).
Signed-off-by: Max Reitz <mre...@redhat.com> --- block/qcow2.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/block/qcow2.c b/block/qcow2.c index 1e7b7d5..4d70665 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2006,6 +2006,27 @@ fail: return ret; } +static int qcow2_make_empty(BlockDriverState *bs) +{ + uint64_t start_sector; + int ret = 0; + + /* The step taken here may not exceed INT_MAX when multiplied by + * BDRV_SECTOR_SIZE. 64k is arbitrary, but works well. */ + for (start_sector = 0; start_sector < bs->total_sectors; + start_sector += 65536) + { + ret = qcow2_discard_clusters(bs, start_sector * BDRV_SECTOR_SIZE, + MIN(65536, bs->total_sectors - start_sector), + QCOW2_DISCARD_REQUEST, true); + if (ret < 0) { + break; + } + } + + return ret; +} + static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; @@ -2388,6 +2409,7 @@ static BlockDriver bdrv_qcow2 = { .bdrv_co_discard = qcow2_co_discard, .bdrv_truncate = qcow2_truncate, .bdrv_write_compressed = qcow2_write_compressed, + .bdrv_make_empty = qcow2_make_empty, .bdrv_snapshot_create = qcow2_snapshot_create, .bdrv_snapshot_goto = qcow2_snapshot_goto, -- 1.9.2