[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [qemu-xen stable-4.10] qcow2: Always execute preallocate() in a coroutine



commit 39475b880538cbf4eeba0affd4e10486839be4b2
Author:     Max Reitz <mreitz@xxxxxxxxxx>
AuthorDate: Mon Oct 9 23:55:32 2017 +0200
Commit:     Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
CommitDate: Tue Dec 5 19:40:38 2017 -0600

    qcow2: Always execute preallocate() in a coroutine
    
    Some qcow2 functions (at least perform_cow()) expect s->lock to be
    taken.  Therefore, if we want to make use of them, we should execute
    preallocate() (as "preallocate_co") in a coroutine so that we can use
    the qemu_co_mutex_* functions.
    
    Signed-off-by: Max Reitz <mreitz@xxxxxxxxxx>
    Message-id: 20171009215533.12530-3-mreitz@xxxxxxxxxx
    Cc: qemu-stable@xxxxxxxxxx
    Reviewed-by: Eric Blake <eblake@xxxxxxxxxx>
    Reviewed-by: Jeff Cody <jcody@xxxxxxxxxx>
    Reviewed-by: Stefan Hajnoczi <stefanha@xxxxxxxxxx>
    Signed-off-by: Max Reitz <mreitz@xxxxxxxxxx>
    (cherry picked from commit 572b07bea1d1a0f7726fd95c2613c76002a379bc)
    Signed-off-by: Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
---
 block/qcow2.c | 41 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 7 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 10e3807..668665e 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2476,6 +2476,14 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, 
const char *encryptfmt,
 }
 
 
+typedef struct PreallocCo {
+    BlockDriverState *bs;
+    uint64_t offset;
+    uint64_t new_length;
+
+    int ret;
+} PreallocCo;
+
 /**
  * Preallocates metadata structures for data clusters between @offset (in the
  * guest disk) and @new_length (which is thus generally the new guest disk
@@ -2483,9 +2491,12 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, 
const char *encryptfmt,
  *
  * Returns: 0 on success, -errno on failure.
  */
-static int preallocate(BlockDriverState *bs,
-                       uint64_t offset, uint64_t new_length)
+static void coroutine_fn preallocate_co(void *opaque)
 {
+    PreallocCo *params = opaque;
+    BlockDriverState *bs = params->bs;
+    uint64_t offset = params->offset;
+    uint64_t new_length = params->new_length;
     BDRVQcow2State *s = bs->opaque;
     uint64_t bytes;
     uint64_t host_offset = 0;
@@ -2493,9 +2504,7 @@ static int preallocate(BlockDriverState *bs,
     int ret;
     QCowL2Meta *meta;
 
-    if (qemu_in_coroutine()) {
-        qemu_co_mutex_lock(&s->lock);
-    }
+    qemu_co_mutex_lock(&s->lock);
 
     assert(offset <= new_length);
     bytes = new_length - offset;
@@ -2549,10 +2558,28 @@ static int preallocate(BlockDriverState *bs,
     ret = 0;
 
 done:
+    qemu_co_mutex_unlock(&s->lock);
+    params->ret = ret;
+}
+
+static int preallocate(BlockDriverState *bs,
+                       uint64_t offset, uint64_t new_length)
+{
+    PreallocCo params = {
+        .bs         = bs,
+        .offset     = offset,
+        .new_length = new_length,
+        .ret        = -EINPROGRESS,
+    };
+
     if (qemu_in_coroutine()) {
-        qemu_co_mutex_unlock(&s->lock);
+        preallocate_co(&params);
+    } else {
+        Coroutine *co = qemu_coroutine_create(preallocate_co, &params);
+        bdrv_coroutine_enter(bs, co);
+        BDRV_POLL_WHILE(bs, params.ret == -EINPROGRESS);
     }
-    return ret;
+    return params.ret;
 }
 
 /* qcow2_refcount_metadata_size:
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#stable-4.10

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.