[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC V3 17/24] qcow2: Behave correctly when refcount reach
From: |
Benoît Canet |
Subject: |
[Qemu-devel] [RFC V3 17/24] qcow2: Behave correctly when refcount reach 0 or 2^16. |
Date: |
Mon, 26 Nov 2012 14:05:16 +0100 |
When refcount reach zero we destroy the hash on disk and remove it from GTree.
When refcount is at it's maximum value we mark the hash so it won't be loaded
at next startup and remove it from GTree.
Signed-off-by: Benoit Canet <address@hidden>
---
block/qcow2-dedup.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
block/qcow2-refcount.c | 6 ++++++
block/qcow2.h | 6 ++++++
3 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/block/qcow2-dedup.c b/block/qcow2-dedup.c
index 80e9477..097d71b 100644
--- a/block/qcow2-dedup.c
+++ b/block/qcow2-dedup.c
@@ -743,8 +743,9 @@ void coroutine_fn qcow2_co_load_dedup_hashes(void *opaque)
error_report("Failed to load deduplication hash.");
}
- /* if the hash is not null load it into the tree */
- if (memcmp(hash, null_hash, HASH_LENGTH)) {
+ /* if the hash is not null load it into red black tree */
+ if (memcmp(hash, null_hash, HASH_LENGTH) &&
+ !(first_logical_offset & QCOW_FLAG_MAX_REFCOUNT)) {
hash_node = qcow2_dedup_build_qcow_hash_node(hash,
i *
s->cluster_sectors,
first_logical_offset);
@@ -809,3 +810,44 @@ void qcow2_dedup_close(BlockDriverState *bs)
BDRVQcowState *s = bs->opaque;
g_free(s->dedup_table);
}
+
+static void qcow2_dedup_refcount_limit_reached(BlockDriverState *bs,
+ uint64_t cluster_index,
+ bool bottom)
+{
+ BDRVQcowState *s = bs->opaque;
+ QCowHashNode *hash_node;
+ uint64_t offset = cluster_index * s->cluster_sectors;
+
+ hash_node = g_tree_lookup(s->dedup_tree_by_offset, &offset);
+ if (!hash_node) {
+ return;
+ }
+
+ if (bottom) {
+ /* clear the hash from disk */
+ memset(hash_node->hash, 0, HASH_LENGTH);
+ } else {
+ /* mark this hash so we won't load it anymore at startup */
+ hash_node->first_logical_offset |= QCOW_FLAG_MAX_REFCOUNT;
+ }
+ qcow2_dedup_read_write_hash(bs,
+ &hash_node->hash,
+ &hash_node->first_logical_offset,
+ hash_node->offset,
+ true);
+ g_tree_remove(s->dedup_tree_by_offset, &hash_node->offset);
+ g_tree_remove(s->dedup_tree_by_hash, hash_node->hash);
+}
+
+void qcow2_dedup_refcount_zero_reached(BlockDriverState *bs,
+ uint64_t cluster_index)
+{
+ qcow2_dedup_refcount_limit_reached(bs, cluster_index, true);
+}
+
+void qcow2_dedup_refcount_max_reached(BlockDriverState *bs,
+ uint64_t cluster_index)
+{
+ qcow2_dedup_refcount_limit_reached(bs, cluster_index, false);
+}
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 7681001..efc1179 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -492,6 +492,12 @@ static int QEMU_WARN_UNUSED_RESULT
update_refcount(BlockDriverState *bs,
ret = -EINVAL;
goto fail;
}
+ if (s->has_dedup && refcount == 0) {
+ qcow2_dedup_refcount_zero_reached(bs, cluster_index);
+ }
+ if (s->has_dedup && refcount == 0xffff) {
+ qcow2_dedup_refcount_max_reached(bs, cluster_index);
+ }
if (refcount == 0 && cluster_index < s->free_cluster_index) {
s->free_cluster_index = cluster_index;
}
diff --git a/block/qcow2.h b/block/qcow2.h
index 90dcdd9..8852696 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -60,6 +60,8 @@
#define DEFAULT_CLUSTER_SIZE 65536
+/* indicate that this cluster refcount has reached its maximum value */
+#define QCOW_FLAG_MAX_REFCOUNT (1LL << 61)
/* indicate that the hash structure is empty and miss offset */
#define QCOW_FLAG_EMPTY (1LL << 62)
/* indicate that the cluster for this hash has QCOW_OFLAG_COPIED on disk */
@@ -409,5 +411,9 @@ int qcow2_dedup_grow_table(BlockDriverState *bs,
bool exact_size);
int qcow2_dedup_init(BlockDriverState *bs);
void qcow2_dedup_close(BlockDriverState *bs);
+void qcow2_dedup_refcount_zero_reached(BlockDriverState *bs,
+ uint64_t cluster_index);
+void qcow2_dedup_refcount_max_reached(BlockDriverState *bs,
+ uint64_t cluster_index);
#endif
--
1.7.10.4
- [Qemu-devel] [RFC V3 04/24] qcow2: Make update_cluster_refcount public., (continued)
- [Qemu-devel] [RFC V3 04/24] qcow2: Make update_cluster_refcount public., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 05/24] qcow2: Create a way to link to l2 tables in dedup., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 03/24] qcow2: Add qcow2_de dup_read_missing_and_concatenate, Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 06/24] qcow2: Add qcow2_dedup and related functions., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 09/24] qcow2: Extract qcow2_dedup_grow_table, Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 13/24] qcow2: Add qcow2_dedup_init and qcow2_dedup_close., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 12/24] qcow2: Extract qcow2_do_table_init., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 11/24] qcow2: Load and save deduplication table header extension., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 14/24] qcow2: Extract qcow2_add_feature and qcow2_remove_feature., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 16/24] qcow2: Allow creation of images using deduplication., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 17/24] qcow2: Behave correctly when refcount reach 0 or 2^16.,
Benoît Canet <=
- [Qemu-devel] [RFC V3 19/24] qcow2: Add verification of dedup table., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 24/24] qemu-iotests: Filter dedup=on/off so existing tests don't break., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 20/24] qcow2: Adapt checking of QCOW_OFLAG_COPIED for dedup., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 22/24] qcow2: Do not overwrite existing entries with QCOW_OFLAG_COPIED., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 07/24] qcow2: Add qcow2_dedup_write_new_hashes., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 18/24] qcow2: Integrate deduplication in qcow2_co_writev loop., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 08/24] qcow2: Implement qcow2_compute_cluster_hash., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 21/24] qcow2: Add check_dedup_l2 in order to check l2 of dedup table., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 23/24] qcow2: init and cleanup deduplication., Benoît Canet, 2012/11/26
- [Qemu-devel] [RFC V3 10/24] qcow2: create function to load deduplication hashes at startup., Benoît Canet, 2012/11/26