Patchwork [RFC,V6,20/33] qcow2: Add a deduplication boolean to update_refcount.

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

Comments

Benoît Canet - Feb. 6, 2013, 12:31 p.m.
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(-)
Stefan Hajnoczi - Feb. 7, 2013, 10:24 a.m.
On Wed, Feb 06, 2013 at 01:31:53PM +0100, Benoît Canet wrote:
> @@ -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)

This is a layering violation and is easy to avoid.  More details in
reply to the next patch.

Stefan

Patch

diff --git a/block/qcow2-dedup.c b/block/qcow2-dedup.c
index 9fb0ced..b1922ab 100644
--- a/block/qcow2-dedup.c
+++ b/block/qcow2-dedup.c
@@ -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.
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 9c16816..a932ff6 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -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 */
@@ -791,7 +793,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;
                             }
@@ -1224,7 +1226,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;
diff --git a/block/qcow2.h b/block/qcow2.h
index 5b51005..dc378a7 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -415,7 +415,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,