@@ -386,7 +386,7 @@ static int qcow2_deduplicate_cluster(BlockDriverState *bs,
return update_refcount(bs,
(hash_node->physical_sect /
s->cluster_sectors) << s->cluster_bits,
- 1, 1);
+ 1, 1, true);
}
/* This function tries to deduplicate a given cluster.
@@ -245,7 +245,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
} else {
/* Described somewhere else. This can recurse at most twice before we
* arrive at a block that describes itself. */
- ret = update_refcount(bs, new_block, s->cluster_size, 1);
+ ret = update_refcount(bs, new_block, s->cluster_size, 1, false);
if (ret < 0) {
goto fail_block;
}
@@ -427,7 +427,7 @@ fail_block:
/* XXX: cache several refcount block clusters ? */
int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length, int addend)
+ int64_t offset, int64_t length, int addend, bool deduplication)
{
BDRVQcowState *s = bs->opaque;
int64_t start, last, cluster_offset;
@@ -513,7 +513,8 @@ fail:
*/
if (ret < 0) {
int dummy;
- dummy = update_refcount(bs, offset, cluster_offset - offset, -addend);
+ dummy = update_refcount(bs, offset, cluster_offset - offset, -addend,
+ deduplication);
(void)dummy;
}
@@ -534,7 +535,8 @@ static int update_cluster_refcount(BlockDriverState *bs,
BDRVQcowState *s = bs->opaque;
int ret;
- ret = update_refcount(bs, cluster_index << s->cluster_bits, 1, addend);
+ ret = update_refcount(bs, cluster_index << s->cluster_bits, 1, addend,
+ false);
if (ret < 0) {
return ret;
}
@@ -588,7 +590,7 @@ int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size)
return offset;
}
- ret = update_refcount(bs, offset, size, 1);
+ ret = update_refcount(bs, offset, size, 1, false);
if (ret < 0) {
return ret;
}
@@ -620,7 +622,7 @@ int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
old_free_cluster_index = s->free_cluster_index;
s->free_cluster_index = cluster_index + i;
- ret = update_refcount(bs, offset, i << s->cluster_bits, 1);
+ ret = update_refcount(bs, offset, i << s->cluster_bits, 1, false);
if (ret < 0) {
return ret;
}
@@ -686,7 +688,7 @@ void qcow2_free_clusters(BlockDriverState *bs,
int ret;
BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_FREE);
- ret = update_refcount(bs, offset, size, -1);
+ ret = update_refcount(bs, offset, size, -1, false);
if (ret < 0) {
fprintf(stderr, "qcow2_free_clusters failed: %s\n", strerror(-ret));
/* TODO Remember the clusters to free them later and avoid leaking */
@@ -795,7 +797,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
int ret;
ret = update_refcount(bs,
(offset & s->cluster_offset_mask) & ~511,
- nb_csectors * 512, addend);
+ nb_csectors * 512, addend, false);
if (ret < 0) {
goto fail;
}
@@ -1228,7 +1230,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
if (num_fixed) {
ret = update_refcount(bs, i << s->cluster_bits, 1,
- refcount2 - refcount1);
+ refcount2 - refcount1, false);
if (ret >= 0) {
(*num_fixed)++;
continue;
@@ -418,7 +418,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
BdrvCheckMode fix);
int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length, int addend);
+ int64_t offset, int64_t length, int addend, bool deduplication);
/* qcow2-cluster.c functions */
typedef int (*qcow2_save_table)(BlockDriverState *bs,
This is needed for next commit which handle the deduplication refcount overflow case. Signed-off-by: Benoit Canet <benoit@irqsave.net> --- block/qcow2-dedup.c | 2 +- block/qcow2-refcount.c | 20 +++++++++++--------- block/qcow2.h | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-)