Patchwork [RFC,V6,22/33] qcow2: Remove hash when cluster is deleted.

login
register
mail settings
Submitter Benoît Canet
Date Feb. 6, 2013, 12:31 p.m.
Message ID <1360153926-9492-23-git-send-email-benoit@irqsave.net>
Download mbox | patch
Permalink /patch/218653/
State New
Headers show

Comments

Benoît Canet - Feb. 6, 2013, 12:31 p.m.
Signed-off-by: Benoit Canet <benoit@irqsave.net>
---
 block/qcow2-dedup.c    |   26 ++++++++++++++++++++++++++
 block/qcow2-refcount.c |    3 +++
 block/qcow2.h          |    2 ++
 3 files changed, 31 insertions(+)
Stefan Hajnoczi - Feb. 7, 2013, 10:31 a.m.
On Wed, Feb 06, 2013 at 01:31:55PM +0100, Benoît Canet wrote:
> diff --git a/block/qcow2-dedup.c b/block/qcow2-dedup.c
> index 4819eb3..1ed219d 100644
> --- a/block/qcow2-dedup.c
> +++ b/block/qcow2-dedup.c
> @@ -942,6 +942,32 @@ int qcow2_dedup_store_new_hashes(BlockDriverState *bs,
>      return ret;
>  }
>  
> +/* Clean the last reference to a given cluster when it's refcount is zero

s/it's/its/

> + *
> + * @cluster_index: the index of the physical cluster
> + */
> +void qcow2_dedup_refcount_zero_reached(BlockDriverState *bs,
> +                                      uint64_t cluster_index)

"refcount zero reached" is the condition under which this function is
called.  It does not describe what the function actually does.

Maybe qcow2_dedup_write_zeroed_hash()?

Patch

diff --git a/block/qcow2-dedup.c b/block/qcow2-dedup.c
index 4819eb3..1ed219d 100644
--- a/block/qcow2-dedup.c
+++ b/block/qcow2-dedup.c
@@ -942,6 +942,32 @@  int qcow2_dedup_store_new_hashes(BlockDriverState *bs,
     return ret;
 }
 
+/* Clean the last reference to a given cluster when it's refcount is zero
+ *
+ * @cluster_index: the index of the physical cluster
+ */
+void qcow2_dedup_refcount_zero_reached(BlockDriverState *bs,
+                                      uint64_t cluster_index)
+{
+    BDRVQcowState *s = bs->opaque;
+    QCowHash null_hash;
+    uint64_t logical_sect = 0;
+    uint64_t physical_sect = cluster_index * s->cluster_sectors;
+
+    /* prepare null hash */
+    memset(&null_hash, 0, sizeof(null_hash));
+
+    /* clear from disk */
+    qcow2_dedup_read_write_hash(bs,
+                                &null_hash,
+                                &logical_sect,
+                                physical_sect,
+                                true);
+
+    /* remove from ram if present so we won't dedup with it anymore */
+    qcow2_remove_hash_node_by_sector(bs, physical_sect);
+}
+
 /* Force to use a new physical cluster and QCowHashNode when the refcount pass
  * 2^16/2.
  *
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index fa2559f..f6a80db 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -492,6 +492,9 @@  int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
         if (s->has_dedup && deduplication && refcount >= 0xFFFF/2) {
             qcow2_dedup_refcount_half_max_reached(bs, cluster_index);
         }
+        if (s->has_dedup && refcount == 0) {
+            qcow2_dedup_refcount_zero_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 f281832..6d6f5d3 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -498,6 +498,8 @@  int qcow2_dedup_store_new_hashes(BlockDriverState *bs,
                                  int count,
                                  uint64_t logical_sect,
                                  uint64_t physical_sect);
+void qcow2_dedup_refcount_zero_reached(BlockDriverState *bs,
+                                       uint64_t cluster_index);
 void qcow2_dedup_refcount_half_max_reached(BlockDriverState *bs,
                                            uint64_t cluster_index);