Blame SOURCES/kvm-qcow2-refcount-Snapshot-update-for-zero-clusters.patch

0a122b
From 4d45b1791fb8bc24c17045a91b39c1d62e9e47c3 Mon Sep 17 00:00:00 2001
0a122b
From: Max Reitz <mreitz@redhat.com>
0a122b
Date: Tue, 7 Jan 2014 21:57:07 +0100
0a122b
Subject: [PATCH 02/14] qcow2-refcount: Snapshot update for zero clusters
0a122b
0a122b
RH-Author: Max Reitz <mreitz@redhat.com>
0a122b
Message-id: <1389131839-12920-3-git-send-email-mreitz@redhat.com>
0a122b
Patchwork-id: 56538
0a122b
O-Subject: [RHEL-7.0 qemu-kvm PATCH v2 02/14] qcow2-refcount: Snapshot update for zero clusters
0a122b
Bugzilla: 1033490
0a122b
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
0a122b
RH-Acked-by: Fam Zheng <famz@redhat.com>
0a122b
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
0a122b
BZ: 1033490
0a122b
0a122b
Account for all cluster types in qcow2_update_snapshot_refcounts;
0a122b
this prevents this function from updating the refcount of unallocated
0a122b
zero clusters which effectively led to wrong adjustments of the refcount
0a122b
of cluster 0 (the main qcow2 header). This in turn resulted in images
0a122b
with (unallocated) zero clusters having a cluster 0 refcount greater
0a122b
than one after creating a snapshot.
0a122b
0a122b
Signed-off-by: Max Reitz <mreitz@redhat.com>
0a122b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
0a122b
(cherry picked from commit 8b81a7b6ba8686f35f9cb0acdd54004d63206f03)
0a122b
0a122b
Signed-off-by: Max Reitz <mreitz@redhat.com>
0a122b
---
0a122b
 block/qcow2-refcount.c | 52 +++++++++++++++++++++++++++++++++-----------------
0a122b
 1 file changed, 35 insertions(+), 17 deletions(-)
0a122b
0a122b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
0a122b
---
0a122b
 block/qcow2-refcount.c |   52 ++++++++++++++++++++++++++++++++---------------
0a122b
 1 files changed, 35 insertions(+), 17 deletions(-)
0a122b
0a122b
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
0a122b
index 3787314..2b72d5e 100644
0a122b
--- a/block/qcow2-refcount.c
0a122b
+++ b/block/qcow2-refcount.c
0a122b
@@ -863,11 +863,14 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
0a122b
             }
0a122b
 
0a122b
             for(j = 0; j < s->l2_size; j++) {
0a122b
+                uint64_t cluster_index;
0a122b
+
0a122b
                 offset = be64_to_cpu(l2_table[j]);
0a122b
-                if (offset != 0) {
0a122b
-                    old_offset = offset;
0a122b
-                    offset &= ~QCOW_OFLAG_COPIED;
0a122b
-                    if (offset & QCOW_OFLAG_COMPRESSED) {
0a122b
+                old_offset = offset;
0a122b
+                offset &= ~QCOW_OFLAG_COPIED;
0a122b
+
0a122b
+                switch (qcow2_get_cluster_type(offset)) {
0a122b
+                    case QCOW2_CLUSTER_COMPRESSED:
0a122b
                         nb_csectors = ((offset >> s->csize_shift) &
0a122b
                                        s->csize_mask) + 1;
0a122b
                         if (addend != 0) {
0a122b
@@ -882,8 +885,16 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
0a122b
                         }
0a122b
                         /* compressed clusters are never modified */
0a122b
                         refcount = 2;
0a122b
-                    } else {
0a122b
-                        uint64_t cluster_index = (offset & L2E_OFFSET_MASK) >> s->cluster_bits;
0a122b
+                        break;
0a122b
+
0a122b
+                    case QCOW2_CLUSTER_NORMAL:
0a122b
+                    case QCOW2_CLUSTER_ZERO:
0a122b
+                        cluster_index = (offset & L2E_OFFSET_MASK) >> s->cluster_bits;
0a122b
+                        if (!cluster_index) {
0a122b
+                            /* unallocated */
0a122b
+                            refcount = 0;
0a122b
+                            break;
0a122b
+                        }
0a122b
                         if (addend != 0) {
0a122b
                             refcount = update_cluster_refcount(bs, cluster_index, addend,
0a122b
                                                                QCOW2_DISCARD_SNAPSHOT);
0a122b
@@ -895,19 +906,26 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
0a122b
                             ret = refcount;
0a122b
                             goto fail;
0a122b
                         }
0a122b
-                    }
0a122b
+                        break;
0a122b
 
0a122b
-                    if (refcount == 1) {
0a122b
-                        offset |= QCOW_OFLAG_COPIED;
0a122b
-                    }
0a122b
-                    if (offset != old_offset) {
0a122b
-                        if (addend > 0) {
0a122b
-                            qcow2_cache_set_dependency(bs, s->l2_table_cache,
0a122b
-                                s->refcount_block_cache);
0a122b
-                        }
0a122b
-                        l2_table[j] = cpu_to_be64(offset);
0a122b
-                        qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
0a122b
+                    case QCOW2_CLUSTER_UNALLOCATED:
0a122b
+                        refcount = 0;
0a122b
+                        break;
0a122b
+
0a122b
+                    default:
0a122b
+                        abort();
0a122b
+                }
0a122b
+
0a122b
+                if (refcount == 1) {
0a122b
+                    offset |= QCOW_OFLAG_COPIED;
0a122b
+                }
0a122b
+                if (offset != old_offset) {
0a122b
+                    if (addend > 0) {
0a122b
+                        qcow2_cache_set_dependency(bs, s->l2_table_cache,
0a122b
+                            s->refcount_block_cache);
0a122b
                     }
0a122b
+                    l2_table[j] = cpu_to_be64(offset);
0a122b
+                    qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
0a122b
                 }
0a122b
             }
0a122b
 
0a122b
-- 
0a122b
1.7.1
0a122b