Commit d861ab3a authored by Kevin Wolf's avatar Kevin Wolf
Browse files

block: Add BlockBackend.ctx



This adds a new parameter to blk_new() which requires its callers to
declare from which AioContext this BlockBackend is going to be used (or
the locks of which AioContext need to be taken anyway).

The given context is only stored and kept up to date when changing
AioContexts. Actually applying the stored AioContext to the root node
is saved for another commit.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 97896a48
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2884,7 +2884,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
            /* Not requesting BLK_PERM_CONSISTENT_READ because we're only
             * looking at the header to guess the image format. This works even
             * in cases where a guest would not see a consistent state. */
            file = blk_new(0, BLK_PERM_ALL);
            file = blk_new(bdrv_get_aio_context(file_bs), 0, BLK_PERM_ALL);
            blk_insert_bs(file, file_bs, &local_err);
            bdrv_unref(file_bs);
            if (local_err) {
+2 −1
Original line number Diff line number Diff line
@@ -627,7 +627,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
    }

    /* The target must match the source in size, so no resize here either */
    job->target = blk_new(BLK_PERM_WRITE,
    job->target = blk_new(job->common.job.aio_context,
                          BLK_PERM_WRITE,
                          BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
                          BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD);
    ret = blk_insert_bs(job->target, target, errp);
+15 −3
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ struct BlockBackend {
    char *name;
    int refcnt;
    BdrvChild *root;
    AioContext *ctx;
    DriveInfo *legacy_dinfo;    /* null unless created by drive_new() */
    QTAILQ_ENTRY(BlockBackend) link;         /* for block_backends */
    QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
@@ -322,12 +323,13 @@ static const BdrvChildRole child_root = {
 *
 * Return the new BlockBackend on success, null on failure.
 */
BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
{
    BlockBackend *blk;

    blk = g_new0(BlockBackend, 1);
    blk->refcnt = 1;
    blk->ctx = ctx;
    blk->perm = perm;
    blk->shared_perm = shared_perm;
    blk_set_enable_write_cache(blk, true);
@@ -347,6 +349,7 @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)

/*
 * Creates a new BlockBackend, opens a new BlockDriverState, and connects both.
 * The new BlockBackend is in the main AioContext.
 *
 * Just as with bdrv_open(), after having called this function the reference to
 * @options belongs to the block layer (even on failure).
@@ -382,7 +385,7 @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
        perm |= BLK_PERM_RESIZE;
    }

    blk = blk_new(perm, BLK_PERM_ALL);
    blk = blk_new(qemu_get_aio_context(), perm, BLK_PERM_ALL);
    bs = bdrv_open(filename, reference, options, flags, errp);
    if (!bs) {
        blk_unref(blk);
@@ -1856,9 +1859,17 @@ void blk_op_unblock_all(BlockBackend *blk, Error *reason)

AioContext *blk_get_aio_context(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);

    /* FIXME The AioContext of bs and blk can be inconsistent. For the moment,
     * we prefer the one of bs for compatibility. */
    if (bs) {
        return bdrv_get_aio_context(blk_bs(blk));
    }

    return blk->ctx;
}

static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
{
    BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb);
@@ -1888,6 +1899,7 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
        }
    }

    blk->ctx = new_context;
    return 0;
}

+7 −4
Original line number Diff line number Diff line
@@ -338,7 +338,8 @@ void commit_start(const char *job_id, BlockDriverState *bs,
        goto fail;
    }

    s->base = blk_new(BLK_PERM_CONSISTENT_READ
    s->base = blk_new(s->common.job.aio_context,
                      BLK_PERM_CONSISTENT_READ
                      | BLK_PERM_WRITE
                      | BLK_PERM_RESIZE,
                      BLK_PERM_CONSISTENT_READ
@@ -351,7 +352,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
    s->base_bs = base;

    /* Required permissions are already taken with block_job_add_bdrv() */
    s->top = blk_new(0, BLK_PERM_ALL);
    s->top = blk_new(s->common.job.aio_context, 0, BLK_PERM_ALL);
    ret = blk_insert_bs(s->top, top, errp);
    if (ret < 0) {
        goto fail;
@@ -395,6 +396,7 @@ int bdrv_commit(BlockDriverState *bs)
    BlockDriverState *backing_file_bs = NULL;
    BlockDriverState *commit_top_bs = NULL;
    BlockDriver *drv = bs->drv;
    AioContext *ctx;
    int64_t offset, length, backing_length;
    int ro;
    int64_t n;
@@ -422,8 +424,9 @@ int bdrv_commit(BlockDriverState *bs)
        }
    }

    src = blk_new(BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
    backing = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
    ctx = bdrv_get_aio_context(bs);
    src = blk_new(ctx, BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
    backing = blk_new(ctx, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);

    ret = blk_insert_bs(src, bs, &local_err);
    if (ret < 0) {
+2 −1
Original line number Diff line number Diff line
@@ -257,7 +257,8 @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
    QCryptoBlock *crypto = NULL;
    struct BlockCryptoCreateData data;

    blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
    blk = blk_new(bdrv_get_aio_context(bs),
                  BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);

    ret = blk_insert_bs(blk, bs, errp);
    if (ret < 0) {
Loading