From 146cb245562e61e512e193d57a6fc5cfe6e39571 Mon Sep 17 00:00:00 2001
From: Markus Armbruster <armbru@redhat.com>
Date: Wed, 18 Jan 2012 10:38:12 +0100
Subject: [PATCH 18/52] qcow2: Fix memory leaks in error cases

RH-Author: Markus Armbruster <armbru@redhat.com>
Message-id: <1326883126-22053-19-git-send-email-armbru@redhat.com>
Patchwork-id: 36587
O-Subject: [RHEL-6.3 PATCH qemu-kvm 18/52] qcow2: Fix memory leaks in error cases
Bugzilla: 758194
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Amit Shah <amit.shah@redhat.com>

From: Kevin Wolf <kwolf@redhat.com>

This fixes memory leaks that may be caused by I/O errors during L1 table growth
(can happen during save_vm) and in qemu-img check.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 80fa3341a70151d250be92ae900e3c1580817540)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/qcow2-cluster.c  |    2 +-
 block/qcow2-refcount.c |    9 ++++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 block/qcow2-cluster.c  |    2 +-
 block/qcow2-refcount.c |    9 ++++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 612712a..945bad4 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -63,7 +63,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
 
     ret = qcow2_cache_flush(bs, s->refcount_block_cache);
     if (ret < 0) {
-        return ret;
+        goto fail;
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index beea8ef..d75d322 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1089,7 +1089,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
     ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
                        s->l1_table_offset, s->l1_size, 1);
     if (ret < 0) {
-        return ret;
+        goto fail;
     }
 
     /* snapshots */
@@ -1098,7 +1098,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
         ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
             sn->l1_table_offset, sn->l1_size, 0);
         if (ret < 0) {
-            return ret;
+            goto fail;
         }
     }
     inc_refcounts(bs, res, refcount_table, nb_clusters,
@@ -1162,8 +1162,11 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
         }
     }
 
+    ret = 0;
+
+fail:
     qemu_free(refcount_table);
 
-    return 0;
+    return ret;
 }
 
-- 
1.7.7.5

