Patchwork [RFC,V7,09/32] qcow2: Do allocate on rewrite on the dedup case.

login
register
mail settings
Submitter Benoît Canet
Date March 15, 2013, 2:49 p.m.
Message ID <1363358986-8360-10-git-send-email-benoit@irqsave.net>
Download mbox | patch
Permalink /patch/228022/
State New
Headers show

Comments

Benoît Canet - March 15, 2013, 2:49 p.m.
This patch does allocate on rewrite when deduplication is on.
This get rid of the need of removing the old hash of the lookup structure
when a cluster get rewritten.
The old data is left in place and will be collected/deleted when it's cluster
will reach 0.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
---
 block/qcow2-cluster.c |   22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

Patch

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 3354f39..fae4110 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -898,11 +898,17 @@  again:
 
     cluster_offset = be64_to_cpu(l2_table[l2_index]);
 
+    /* If dedup is on we are always allocating wether it's a write or a
+     * rewrite. Doing this simplify a lot the rewrite cluster case since
+     * we don't need to remove the obsolete hash from the tree.
+     * Old clusters will be deleted when their refcount will reach 0.
+     */
     /*
-     * Check how many clusters are already allocated and don't need COW, and how
-     * many need a new allocation.
+     * Check how many clusters are already allocated and don't need COW,
+     * and how many need a new allocation.
      */
-    if (qcow2_get_cluster_type(cluster_offset) == QCOW2_CLUSTER_NORMAL
+    if (!s->has_dedup &&
+        qcow2_get_cluster_type(cluster_offset) == QCOW2_CLUSTER_NORMAL
         && (cluster_offset & QCOW_OFLAG_COPIED))
     {
         /* We keep all QCOW_OFLAG_COPIED clusters */
@@ -931,11 +937,11 @@  again:
     cluster_offset &= L2E_OFFSET_MASK;
 
     /*
-     * The L2 table isn't used any more after this. As long as the cache works
-     * synchronously, it's important to release it before calling
-     * do_alloc_cluster_offset, which may yield if we need to wait for another
-     * request to complete. If we still had the reference, we could use up the
-     * whole cache with sleeping requests.
+     * The L2 table isn't used any more after this. As long as the cache
+     * works synchronously, it's important to release it before calling
+     * do_alloc_cluster_offset, which may yield if we need to wait for
+     * another request to complete. If we still had the reference, we could
+     * use up the whole cache with sleeping requests.
      */
     ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
     if (ret < 0) {