On Fri, Aug 22, 2014 at 06:31:42PM +0200, Max Reitz wrote: > Because the old refcount structure will be leaked after having rebuilt > it, we need to recalculate the refcounts and run a leak-fixing operation > afterwards (if leaks should be fixed at all). > > Signed-off-by: Max Reitz <[email protected]> > --- > block/qcow2-refcount.c | 35 +++++++++++++++++++++++++++++++++++ > 1 file changed, 35 insertions(+) > > diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c > index 59cab65..818facc 100644 > --- a/block/qcow2-refcount.c > +++ b/block/qcow2-refcount.c > @@ -1874,12 +1874,47 @@ int qcow2_check_refcounts(BlockDriverState *bs, > BdrvCheckResult *res, > nb_clusters); > > if (rebuild && (fix & BDRV_FIX_ERRORS)) { > + BdrvCheckResult old_res = *res; > + > fprintf(stderr, "Rebuilding refcount structure\n"); > ret = rebuild_refcount_structure(bs, res, &refcount_table, > &nb_clusters); > if (ret < 0) { > goto fail; > } > + > + res->corruptions = 0; > + res->leaks = 0; > + > + /* Because the old reftable has been exchanged for a new one the > + * references have to be recalculated */ > + rebuild = false; > + memset(refcount_table, 0, nb_clusters * sizeof(uint16_t)); > + ret = calculate_refcounts(bs, res, 0, &rebuild, &refcount_table, > + &nb_clusters); > + if (ret < 0) { > + goto fail; > + } > + > + if (fix & BDRV_FIX_LEAKS) { > + /* The old refcount structures are now leaked, fix it; the result > + * can be ignored */ > + pre_compare_res = *res; > + compare_refcounts(bs, res, BDRV_FIX_LEAKS, &rebuild, > + &highest_cluster, refcount_table, nb_clusters); > + if (rebuild) { > + fprintf(stderr, "ERROR rebuilt refcount structure is still " > + "broken\n"); > + } > + *res = pre_compare_res; > + } > + > + if (res->corruptions < old_res.corruptions) { > + res->corruptions_fixed += old_res.corruptions - res->corruptions; > + } > + if (res->leaks < old_res.leaks) { > + res->leaks_fixed += old_res.leaks - res->leaks; > + } > } else if (fix) { > if (rebuild) { > fprintf(stderr, "ERROR need to rebuild refcount structures\n"); > -- > 2.0.4 >
Reviewed-by: Benoît Canet <[email protected]>
