9ae3a8
From f39d8d56b3cf31f293465bd912ae623ada8152c0 Mon Sep 17 00:00:00 2001
9ae3a8
From: Max Reitz <mreitz@redhat.com>
9ae3a8
Date: Tue, 7 Jan 2014 21:57:15 +0100
9ae3a8
Subject: [PATCH 10/14] qcow2: Free only newly allocated clusters on error
9ae3a8
9ae3a8
RH-Author: Max Reitz <mreitz@redhat.com>
9ae3a8
Message-id: <1389131839-12920-11-git-send-email-mreitz@redhat.com>
9ae3a8
Patchwork-id: 56546
9ae3a8
O-Subject: [RHEL-7.0 qemu-kvm PATCH v2 10/14] qcow2: Free only newly allocated clusters on error
9ae3a8
Bugzilla: 1033490
9ae3a8
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
RH-Acked-by: Fam Zheng <famz@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
9ae3a8
BZ: 1033490
9ae3a8
9ae3a8
In expand_zero_clusters_in_l1, a new cluster is only allocated if it was
9ae3a8
not already preallocated. On error, such preallocated clusters should
9ae3a8
not be freed, but only the newly allocated ones.
9ae3a8
9ae3a8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9ae3a8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
(cherry picked from commit 320c70666687db4dd4df8165f9fe6960de782ca9)
9ae3a8
9ae3a8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9ae3a8
---
9ae3a8
 block/qcow2-cluster.c | 16 ++++++++++------
9ae3a8
 1 file changed, 10 insertions(+), 6 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 block/qcow2-cluster.c |   16 ++++++++++------
9ae3a8
 1 files changed, 10 insertions(+), 6 deletions(-)
9ae3a8
9ae3a8
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
9ae3a8
index bfdc83a..79c3ae0 100644
9ae3a8
--- a/block/qcow2-cluster.c
9ae3a8
+++ b/block/qcow2-cluster.c
9ae3a8
@@ -1552,6 +1552,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
9ae3a8
             uint64_t l2_entry = be64_to_cpu(l2_table[j]);
9ae3a8
             int64_t offset = l2_entry & L2E_OFFSET_MASK, cluster_index;
9ae3a8
             int cluster_type = qcow2_get_cluster_type(l2_entry);
9ae3a8
+            bool preallocated = offset != 0;
9ae3a8
 
9ae3a8
             if (cluster_type == QCOW2_CLUSTER_NORMAL) {
9ae3a8
                 cluster_index = offset >> s->cluster_bits;
9ae3a8
@@ -1577,8 +1578,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
9ae3a8
                 continue;
9ae3a8
             }
9ae3a8
 
9ae3a8
-            if (!offset) {
9ae3a8
-                /* not preallocated */
9ae3a8
+            if (!preallocated) {
9ae3a8
                 if (!bs->backing_hd) {
9ae3a8
                     /* not backed; therefore we can simply deallocate the
9ae3a8
                      * cluster */
9ae3a8
@@ -1596,16 +1596,20 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
9ae3a8
 
9ae3a8
             ret = qcow2_pre_write_overlap_check(bs, 0, offset, s->cluster_size);
9ae3a8
             if (ret < 0) {
9ae3a8
-                qcow2_free_clusters(bs, offset, s->cluster_size,
9ae3a8
-                        QCOW2_DISCARD_ALWAYS);
9ae3a8
+                if (!preallocated) {
9ae3a8
+                    qcow2_free_clusters(bs, offset, s->cluster_size,
9ae3a8
+                                        QCOW2_DISCARD_ALWAYS);
9ae3a8
+                }
9ae3a8
                 goto fail;
9ae3a8
             }
9ae3a8
 
9ae3a8
             ret = bdrv_write_zeroes(bs->file, offset / BDRV_SECTOR_SIZE,
9ae3a8
                                     s->cluster_sectors, 0);
9ae3a8
             if (ret < 0) {
9ae3a8
-                qcow2_free_clusters(bs, offset, s->cluster_size,
9ae3a8
-                        QCOW2_DISCARD_ALWAYS);
9ae3a8
+                if (!preallocated) {
9ae3a8
+                    qcow2_free_clusters(bs, offset, s->cluster_size,
9ae3a8
+                                        QCOW2_DISCARD_ALWAYS);
9ae3a8
+                }
9ae3a8
                 goto fail;
9ae3a8
             }
9ae3a8
 
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8