|
|
4a2fec |
From 98ebc4e55985747726bbcbedecbe06fed8d7ea0a Mon Sep 17 00:00:00 2001
|
|
|
4a2fec |
From: Max Reitz <mreitz@redhat.com>
|
|
|
4a2fec |
Date: Mon, 27 Nov 2017 16:19:58 +0100
|
|
|
4a2fec |
Subject: [PATCH 03/21] qcow2: Always execute preallocate() in a coroutine
|
|
|
4a2fec |
|
|
|
4a2fec |
RH-Author: Max Reitz <mreitz@redhat.com>
|
|
|
4a2fec |
Message-id: <20171127161959.13234-4-mreitz@redhat.com>
|
|
|
4a2fec |
Patchwork-id: 77913
|
|
|
4a2fec |
O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 3/4] qcow2: Always execute preallocate() in a coroutine
|
|
|
4a2fec |
Bugzilla: 1414049
|
|
|
4a2fec |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
4a2fec |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
4a2fec |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
4a2fec |
RH-Acked-by: John Snow <jsnow@redhat.com>
|
|
|
4a2fec |
|
|
|
4a2fec |
Some qcow2 functions (at least perform_cow()) expect s->lock to be
|
|
|
4a2fec |
taken. Therefore, if we want to make use of them, we should execute
|
|
|
4a2fec |
preallocate() (as "preallocate_co") in a coroutine so that we can use
|
|
|
4a2fec |
the qemu_co_mutex_* functions.
|
|
|
4a2fec |
|
|
|
4a2fec |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
4a2fec |
Message-id: 20171009215533.12530-3-mreitz@redhat.com
|
|
|
4a2fec |
Cc: qemu-stable@nongnu.org
|
|
|
4a2fec |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
4a2fec |
Reviewed-by: Jeff Cody <jcody@redhat.com>
|
|
|
4a2fec |
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
4a2fec |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
4a2fec |
(cherry picked from commit 572b07bea1d1a0f7726fd95c2613c76002a379bc)
|
|
|
4a2fec |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
4a2fec |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
4a2fec |
---
|
|
|
4a2fec |
block/qcow2.c | 41 ++++++++++++++++++++++++++++++++++-------
|
|
|
4a2fec |
1 file changed, 34 insertions(+), 7 deletions(-)
|
|
|
4a2fec |
|
|
|
4a2fec |
diff --git a/block/qcow2.c b/block/qcow2.c
|
|
|
4a2fec |
index 2cfe706..b26cbbf 100644
|
|
|
4a2fec |
--- a/block/qcow2.c
|
|
|
4a2fec |
+++ b/block/qcow2.c
|
|
|
4a2fec |
@@ -2476,6 +2476,14 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
|
|
|
4a2fec |
}
|
|
|
4a2fec |
|
|
|
4a2fec |
|
|
|
4a2fec |
+typedef struct PreallocCo {
|
|
|
4a2fec |
+ BlockDriverState *bs;
|
|
|
4a2fec |
+ uint64_t offset;
|
|
|
4a2fec |
+ uint64_t new_length;
|
|
|
4a2fec |
+
|
|
|
4a2fec |
+ int ret;
|
|
|
4a2fec |
+} PreallocCo;
|
|
|
4a2fec |
+
|
|
|
4a2fec |
/**
|
|
|
4a2fec |
* Preallocates metadata structures for data clusters between @offset (in the
|
|
|
4a2fec |
* guest disk) and @new_length (which is thus generally the new guest disk
|
|
|
4a2fec |
@@ -2483,9 +2491,12 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
|
|
|
4a2fec |
*
|
|
|
4a2fec |
* Returns: 0 on success, -errno on failure.
|
|
|
4a2fec |
*/
|
|
|
4a2fec |
-static int preallocate(BlockDriverState *bs,
|
|
|
4a2fec |
- uint64_t offset, uint64_t new_length)
|
|
|
4a2fec |
+static void coroutine_fn preallocate_co(void *opaque)
|
|
|
4a2fec |
{
|
|
|
4a2fec |
+ PreallocCo *params = opaque;
|
|
|
4a2fec |
+ BlockDriverState *bs = params->bs;
|
|
|
4a2fec |
+ uint64_t offset = params->offset;
|
|
|
4a2fec |
+ uint64_t new_length = params->new_length;
|
|
|
4a2fec |
BDRVQcow2State *s = bs->opaque;
|
|
|
4a2fec |
uint64_t bytes;
|
|
|
4a2fec |
uint64_t host_offset = 0;
|
|
|
4a2fec |
@@ -2493,9 +2504,7 @@ static int preallocate(BlockDriverState *bs,
|
|
|
4a2fec |
int ret;
|
|
|
4a2fec |
QCowL2Meta *meta;
|
|
|
4a2fec |
|
|
|
4a2fec |
- if (qemu_in_coroutine()) {
|
|
|
4a2fec |
- qemu_co_mutex_lock(&s->lock);
|
|
|
4a2fec |
- }
|
|
|
4a2fec |
+ qemu_co_mutex_lock(&s->lock);
|
|
|
4a2fec |
|
|
|
4a2fec |
assert(offset <= new_length);
|
|
|
4a2fec |
bytes = new_length - offset;
|
|
|
4a2fec |
@@ -2549,10 +2558,28 @@ static int preallocate(BlockDriverState *bs,
|
|
|
4a2fec |
ret = 0;
|
|
|
4a2fec |
|
|
|
4a2fec |
done:
|
|
|
4a2fec |
+ qemu_co_mutex_unlock(&s->lock);
|
|
|
4a2fec |
+ params->ret = ret;
|
|
|
4a2fec |
+}
|
|
|
4a2fec |
+
|
|
|
4a2fec |
+static int preallocate(BlockDriverState *bs,
|
|
|
4a2fec |
+ uint64_t offset, uint64_t new_length)
|
|
|
4a2fec |
+{
|
|
|
4a2fec |
+ PreallocCo params = {
|
|
|
4a2fec |
+ .bs = bs,
|
|
|
4a2fec |
+ .offset = offset,
|
|
|
4a2fec |
+ .new_length = new_length,
|
|
|
4a2fec |
+ .ret = -EINPROGRESS,
|
|
|
4a2fec |
+ };
|
|
|
4a2fec |
+
|
|
|
4a2fec |
if (qemu_in_coroutine()) {
|
|
|
4a2fec |
- qemu_co_mutex_unlock(&s->lock);
|
|
|
4a2fec |
+ preallocate_co(¶ms);
|
|
|
4a2fec |
+ } else {
|
|
|
4a2fec |
+ Coroutine *co = qemu_coroutine_create(preallocate_co, ¶ms);
|
|
|
4a2fec |
+ bdrv_coroutine_enter(bs, co);
|
|
|
4a2fec |
+ BDRV_POLL_WHILE(bs, params.ret == -EINPROGRESS);
|
|
|
4a2fec |
}
|
|
|
4a2fec |
- return ret;
|
|
|
4a2fec |
+ return params.ret;
|
|
|
4a2fec |
}
|
|
|
4a2fec |
|
|
|
4a2fec |
/* qcow2_refcount_metadata_size:
|
|
|
4a2fec |
--
|
|
|
4a2fec |
1.8.3.1
|
|
|
4a2fec |
|