9ae3a8
From 8be02a0613ef6aee7a95ab7dae3d0aa489b65249 Mon Sep 17 00:00:00 2001
9ae3a8
From: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
Date: Tue, 1 Apr 2014 09:45:35 +0200
9ae3a8
Subject: [PATCH 2/2] qcow2: link all L2 meta updates in preallocate()
9ae3a8
9ae3a8
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
Message-id: <1396345535-19829-1-git-send-email-stefanha@redhat.com>
9ae3a8
Patchwork-id: 58320
9ae3a8
O-Subject: [RHEL7 qemu-kvm PATCH] qcow2: link all L2 meta updates in preallocate()
9ae3a8
Bugzilla: 1081393
9ae3a8
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
9ae3a8
9ae3a8
BZ: 1081393
9ae3a8
Upstream: not merged yet, http://article.gmane.org/gmane.comp.emulators.qemu/264904
9ae3a8
BREW: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=7282765
9ae3a8
9ae3a8
preallocate() only links the first QCowL2Meta's data clusters into the
9ae3a8
L2 table and ignores any chained QCowL2Metas in the linked list.
9ae3a8
9ae3a8
Chains of QCowL2Meta structs are built up when contiguous clusters span
9ae3a8
L2 tables.  Each QCowL2Meta describes one L2 table update.  This is a
9ae3a8
rare case in preallocate() but can happen.
9ae3a8
9ae3a8
This patch fixes preallocate() by iterating over the whole list of
9ae3a8
QCowL2Metas.  Compare with the qcow2_co_writev() function's
9ae3a8
implementation, which is similar but also also handles request
9ae3a8
dependencies.  preallocate() only performs one allocation at a time so
9ae3a8
there can be no dependencies.
9ae3a8
9ae3a8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
---
9ae3a8
 block/qcow2.c | 7 ++++++-
9ae3a8
 1 file changed, 6 insertions(+), 1 deletion(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 block/qcow2.c |    7 ++++++-
9ae3a8
 1 files changed, 6 insertions(+), 1 deletions(-)
9ae3a8
9ae3a8
diff --git a/block/qcow2.c b/block/qcow2.c
9ae3a8
index 66ed906..7398b16 100644
9ae3a8
--- a/block/qcow2.c
9ae3a8
+++ b/block/qcow2.c
9ae3a8
@@ -1509,7 +1509,9 @@ static int preallocate(BlockDriverState *bs)
9ae3a8
             return ret;
9ae3a8
         }
9ae3a8
 
9ae3a8
-        if (meta != NULL) {
9ae3a8
+        while (meta) {
9ae3a8
+            QCowL2Meta *next = meta->next;
9ae3a8
+
9ae3a8
             ret = qcow2_alloc_cluster_link_l2(bs, meta);
9ae3a8
             if (ret < 0) {
9ae3a8
                 qcow2_free_any_clusters(bs, meta->alloc_offset,
9ae3a8
@@ -1520,6 +1522,9 @@ static int preallocate(BlockDriverState *bs)
9ae3a8
             /* There are no dependent requests, but we need to remove our
9ae3a8
              * request from the list of in-flight requests */
9ae3a8
             QLIST_REMOVE(meta, next_in_flight);
9ae3a8
+
9ae3a8
+            g_free(meta);
9ae3a8
+            meta = next;
9ae3a8
         }
9ae3a8
 
9ae3a8
         /* TODO Preallocate data if requested */
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8