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