Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 340e01248478ba8b78a6d4d1809b1eff > files > 648

kvm-83-270.el5_11.src.rpm

From 1f3ac8139fc77911c8f67b654ea0b6b0fba7002c Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Fri, 18 Jun 2010 15:22:30 -0300
Subject: [PATCH 12/18] qcow2: Fix error handling in l2_allocate

RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <1276874554-9820-13-git-send-email-kwolf@redhat.com>
Patchwork-id: 9987
O-Subject: [RHEL-5.6 KVM PATCH 12/16] qcow2: Fix error handling in l2_allocate
Bugzilla: 605701
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Christoph Hellwig <chellwig@redhat.com>
RH-Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>

Bugzilla: 605701
Upstream commit: 175e11526e2613b3dc031c23fec3107aa4a80307

l2_allocate has some intermediate states in which the image is inconsistent.
Change the order to write to the L1 table only after the new L2 table has
successfully been initialized.

Also reset the L2 cache in failure case, it's very likely wrong.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu/block-qcow2.c |   23 +++++++++++++----------
 1 files changed, 13 insertions(+), 10 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/block-qcow2.c |   23 +++++++++++++----------
 1 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/qemu/block-qcow2.c b/qemu/block-qcow2.c
index ef0e26b..208af96 100644
--- a/qemu/block-qcow2.c
+++ b/qemu/block-qcow2.c
@@ -715,14 +715,6 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
         return l2_offset;
     }
 
-    /* update the L1 entry */
-
-    s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
-    ret = write_l1_entry(s, l1_index);
-    if (ret < 0) {
-        return ret;
-    }
-
     /* allocate a new entry in the l2 cache */
 
     min_index = l2_cache_new_entry(bs);
@@ -736,14 +728,21 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
         ret = bdrv_pread(s->hd, old_l2_offset, l2_table,
             s->l2_size * sizeof(uint64_t));
         if (ret < 0) {
-            return ret;
+            goto fail;
         }
     }
     /* write the l2 table to the file */
     ret = bdrv_pwrite(s->hd, l2_offset, l2_table,
         s->l2_size * sizeof(uint64_t));
     if (ret < 0) {
-        return ret;
+        goto fail;
+    }
+
+    /* update the L1 entry */
+    s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
+    ret = write_l1_entry(s, l1_index);
+    if (ret < 0) {
+        goto fail;
     }
 
     /* update the l2 cache entry */
@@ -753,6 +752,10 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
 
     *table = l2_table;
     return 0;
+
+fail:
+    l2_cache_reset(bs);
+    return ret;
 }
 
 static int size_to_clusters(BDRVQcowState *s, int64_t size)
-- 
1.7.0.3