Signed-off-by: Devin Nakamura <devin...@gmail.com> --- block/qcow2-refcount.c | 34 ++++++++++++++++++++++++++++++++++ block/qcow2.h | 2 ++ 2 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 75f1f88..2f78a71 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1202,3 +1202,37 @@ fail: return ret; } + +int qcow2_drop_leaked_clusters(BlockDriverState *bs) { + BDRVQcowState *s = bs->opaque; + int64_t size; + int nb_clusters, refcount, i; + uint16_t *refcount_table; + BdrvCheckResult res; + int ret; + + ret = inc_refcount_table(bs, &res, &refcount_table); + if (ret) { + goto fail; + } + size = bdrv_getlength(bs->file); + nb_clusters = size_to_clusters(s, size); + + for(i = 0; i < nb_clusters; i++) { + refcount = get_refcount(bs, i); + refcount = refcount_table[i] - refcount; + if (refcount < 0) { //we only want to change leaked clusters + ret = update_cluster_refcount(bs, i , refcount); + if (ret) { + goto fail; + } + } + } + + ret = 0; + +fail: + qemu_free(refcount_table); + + return ret; +} diff --git a/block/qcow2.h b/block/qcow2.h index 6a0a21b..e9efb74 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -193,6 +193,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs, int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res); +int qcow2_drop_leaked_clusters(BlockDriverState *bs) ; + /* qcow2-cluster.c functions */ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size); void qcow2_l2_cache_reset(BlockDriverState *bs); -- 1.7.6.rc1