Commit 572b07be authored by Max Reitz's avatar Max Reitz
Browse files

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: default avatarMax Reitz <mreitz@redhat.com>
Message-id: 20171009215533.12530-3-mreitz@redhat.com
Cc: qemu-stable@nongnu.org
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Reviewed-by: default avatarJeff Cody <jcody@redhat.com>
Reviewed-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
parent e400ad1e
Loading
Loading
Loading
Loading
+34 −7
Original line number Diff line number Diff line
@@ -2460,6 +2460,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
@@ -2467,9 +2475,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;
@@ -2477,9 +2488,7 @@ static int preallocate(BlockDriverState *bs,
    int ret;
    QCowL2Meta *meta;

    if (qemu_in_coroutine()) {
    qemu_co_mutex_lock(&s->lock);
    }

    assert(offset <= new_length);
    bytes = new_length - offset;
@@ -2533,10 +2542,28 @@ static int preallocate(BlockDriverState *bs,
    ret = 0;

done:
    if (qemu_in_coroutine()) {
    qemu_co_mutex_unlock(&s->lock);
    params->ret = ret;
}
    return 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()) {
        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 params.ret;
}

/* qcow2_refcount_metadata_size: