qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PULL 09/31] qcow2: Fix discard


From: Kevin Wolf
Subject: [Qemu-devel] [PULL 09/31] qcow2: Fix discard
Date: Wed, 30 Apr 2014 20:23:41 +0200

From: Max Reitz <address@hidden>

discard_single_l2() should not implement its own version of
qcow2_get_cluster_type(), but rather rely on this already existing
function. By doing so, it will work for compressed clusters as well
(which it did not so far).

Also, rename "old_offset" to "old_l2_entry", as both are quite different
(and the value is indeed of the latter kind).

Signed-off-by: Max Reitz <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
 block/qcow2-cluster.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 331ab08..b746429 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1360,9 +1360,9 @@ static int discard_single_l2(BlockDriverState *bs, 
uint64_t offset,
     nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
 
     for (i = 0; i < nb_clusters; i++) {
-        uint64_t old_offset;
+        uint64_t old_l2_entry;
 
-        old_offset = be64_to_cpu(l2_table[l2_index + i]);
+        old_l2_entry = be64_to_cpu(l2_table[l2_index + i]);
 
         /*
          * Make sure that a discarded area reads back as zeroes for v3 images
@@ -1373,12 +1373,22 @@ static int discard_single_l2(BlockDriverState *bs, 
uint64_t offset,
          * TODO We might want to use bdrv_get_block_status(bs) here, but we're
          * holding s->lock, so that doesn't work today.
          */
-        if (old_offset & QCOW_OFLAG_ZERO) {
-            continue;
-        }
+        switch (qcow2_get_cluster_type(old_l2_entry)) {
+            case QCOW2_CLUSTER_UNALLOCATED:
+                if (!bs->backing_hd) {
+                    continue;
+                }
+                break;
 
-        if ((old_offset & L2E_OFFSET_MASK) == 0 && !bs->backing_hd) {
-            continue;
+            case QCOW2_CLUSTER_ZERO:
+                continue;
+
+            case QCOW2_CLUSTER_NORMAL:
+            case QCOW2_CLUSTER_COMPRESSED:
+                break;
+
+            default:
+                abort();
         }
 
         /* First remove L2 entries */
@@ -1390,7 +1400,7 @@ static int discard_single_l2(BlockDriverState *bs, 
uint64_t offset,
         }
 
         /* Then decrease the refcount */
-        qcow2_free_any_clusters(bs, old_offset, 1, type);
+        qcow2_free_any_clusters(bs, old_l2_entry, 1, type);
     }
 
     ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
-- 
1.8.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]