diff options
Diffstat (limited to 'block/qcow2-refcount.c')
-rw-r--r-- | block/qcow2-refcount.c | 102 |
1 files changed, 49 insertions, 53 deletions
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index e8b9df9306..24f297f561 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1535,59 +1535,6 @@ done: return new_offset; } -static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res, - BdrvCheckMode fix, uint16_t **refcount_table, - int64_t *nb_clusters); - -/* - * Calculates an in-memory refcount table. - */ -static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, - BdrvCheckMode fix, uint16_t **refcount_table, - int64_t *nb_clusters) -{ - BDRVQcowState *s = bs->opaque; - int64_t i; - QCowSnapshot *sn; - int ret; - - *refcount_table = g_try_new0(uint16_t, *nb_clusters); - if (*nb_clusters && *refcount_table == NULL) { - res->check_errors++; - return -ENOMEM; - } - - /* header */ - inc_refcounts(bs, res, *refcount_table, *nb_clusters, - 0, s->cluster_size); - - /* current L1 table */ - ret = check_refcounts_l1(bs, res, *refcount_table, *nb_clusters, - s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO); - if (ret < 0) { - return ret; - } - - /* snapshots */ - for (i = 0; i < s->nb_snapshots; i++) { - sn = s->snapshots + i; - ret = check_refcounts_l1(bs, res, *refcount_table, *nb_clusters, - sn->l1_table_offset, sn->l1_size, 0); - if (ret < 0) { - return ret; - } - } - inc_refcounts(bs, res, *refcount_table, *nb_clusters, - s->snapshots_offset, s->snapshots_size); - - /* refcount data */ - inc_refcounts(bs, res, *refcount_table, *nb_clusters, - s->refcount_table_offset, - s->refcount_table_size * sizeof(uint64_t)); - - return check_refblocks(bs, res, fix, refcount_table, nb_clusters); -} - /* * Checks consistency of refblocks and accounts for each refblock in * *refcount_table. @@ -1665,6 +1612,55 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res, } /* + * Calculates an in-memory refcount table. + */ +static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, + BdrvCheckMode fix, uint16_t **refcount_table, + int64_t *nb_clusters) +{ + BDRVQcowState *s = bs->opaque; + int64_t i; + QCowSnapshot *sn; + int ret; + + *refcount_table = g_try_new0(uint16_t, *nb_clusters); + if (*nb_clusters && *refcount_table == NULL) { + res->check_errors++; + return -ENOMEM; + } + + /* header */ + inc_refcounts(bs, res, *refcount_table, *nb_clusters, + 0, s->cluster_size); + + /* current L1 table */ + ret = check_refcounts_l1(bs, res, *refcount_table, *nb_clusters, + s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO); + if (ret < 0) { + return ret; + } + + /* snapshots */ + for (i = 0; i < s->nb_snapshots; i++) { + sn = s->snapshots + i; + ret = check_refcounts_l1(bs, res, *refcount_table, *nb_clusters, + sn->l1_table_offset, sn->l1_size, 0); + if (ret < 0) { + return ret; + } + } + inc_refcounts(bs, res, *refcount_table, *nb_clusters, + s->snapshots_offset, s->snapshots_size); + + /* refcount data */ + inc_refcounts(bs, res, *refcount_table, *nb_clusters, + s->refcount_table_offset, + s->refcount_table_size * sizeof(uint64_t)); + + return check_refblocks(bs, res, fix, refcount_table, nb_clusters); +} + +/* * Compares the actual reference count for each cluster in the image against the * refcount as reported by the refcount structures on-disk. */ |