Commit 8ff7fd8a authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging



Block layer patches

# gpg: Signature made Mon 31 Oct 2016 16:10:07 GMT
# gpg:                using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (29 commits)
  qapi: allow blockdev-add for NFS
  block/nfs: Introduce runtime_opts in NFS
  block: Mention replication in BlockdevDriver enum docs
  qemu-iotests: test 'offset' and 'size' options in raw driver
  raw_bsd: add offset and size options
  qemu-iotests: Test the 'base-node' parameter of 'block-stream'
  block: Add 'base-node' parameter to the 'block-stream' command
  qemu-iotests: Test streaming to a Quorum child
  qemu-iotests: Add iotests.supports_quorum()
  qemu-iotests: Test block-stream and block-commit in parallel
  qemu-iotests: Test overlapping stream and commit operations
  qemu-iotests: Test block-stream operations in parallel
  qemu-iotests: Test streaming to an intermediate layer
  docs: Document how to stream to an intermediate layer
  block: Add QMP support for streaming to an intermediate layer
  block: Support streaming to an intermediate layer
  block: Block all intermediate nodes in commit_active_start()
  block: Block all nodes involved in the block-commit operation
  block: Check blockers in all nodes involved in a block-commit job
  block: Use block_job_add_bdrv() in backup_start()
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 6bc56d31 aa2623d8
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -1428,9 +1428,11 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd)
            backing_hd->drv ? backing_hd->drv->format_name : "");

    bdrv_op_block_all(backing_hd, bs->backing_blocker);
    /* Otherwise we won't be able to commit due to check in bdrv_commit */
    /* Otherwise we won't be able to commit or stream */
    bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_COMMIT_TARGET,
                    bs->backing_blocker);
    bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_STREAM,
                    bs->backing_blocker);
    /*
     * We do backup in 3 ways:
     * 1. drive backup
@@ -2091,7 +2093,7 @@ int bdrv_reopen_multiple(AioContext *ctx, BlockReopenQueue *bs_queue, Error **er
    assert(bs_queue != NULL);

    aio_context_release(ctx);
    bdrv_drain_all();
    bdrv_drain_all_begin();
    aio_context_acquire(ctx);

    QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
@@ -2122,6 +2124,9 @@ cleanup:
        g_free(bs_entry);
    }
    g_free(bs_queue);

    bdrv_drain_all_end();

    return ret;
}

+1 −4
Original line number Diff line number Diff line
@@ -446,7 +446,6 @@ static void coroutine_fn backup_run(void *opaque)
    BackupBlockJob *job = opaque;
    BackupCompleteData *data;
    BlockDriverState *bs = blk_bs(job->common.blk);
    BlockBackend *target = job->target;
    int64_t start, end;
    int64_t sectors_per_cluster = cluster_size_sectors(job);
    int ret = 0;
@@ -533,8 +532,6 @@ static void coroutine_fn backup_run(void *opaque)
    qemu_co_rwlock_unlock(&job->flush_rwlock);
    g_free(job->done_bitmap);

    bdrv_op_unblock_all(blk_bs(target), job->common.blocker);

    data = g_malloc(sizeof(*data));
    data->ret = ret;
    block_job_defer_to_main_loop(&job->common, backup_complete, data);
@@ -648,7 +645,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
        job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
    }

    bdrv_op_block_all(target, job->common.blocker);
    block_job_add_bdrv(&job->common, target);
    job->common.len = len;
    job->common.co = qemu_coroutine_create(backup_run, job);
    block_job_txn_add_job(txn, &job->common);
+14 −0
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
    BlockReopenQueue *reopen_queue = NULL;
    int orig_overlay_flags;
    int orig_base_flags;
    BlockDriverState *iter;
    BlockDriverState *overlay_bs;
    Error *local_err = NULL;

@@ -260,6 +261,19 @@ void commit_start(const char *job_id, BlockDriverState *bs,
    }


    /* Block all nodes between top and base, because they will
     * disappear from the chain after this operation. */
    assert(bdrv_chain_contains(top, base));
    for (iter = top; iter != backing_bs(base); iter = backing_bs(iter)) {
        block_job_add_bdrv(&s->common, iter);
    }
    /* overlay_bs must be blocked because it needs to be modified to
     * update the backing image string, but if it's the root node then
     * don't block it again */
    if (bs != overlay_bs) {
        block_job_add_bdrv(&s->common, overlay_bs);
    }

    s->base = blk_new();
    blk_insert_bs(s->base, base);

+24 −3
Original line number Diff line number Diff line
@@ -273,8 +273,14 @@ void bdrv_drain(BlockDriverState *bs)
 *
 * This function does not flush data to disk, use bdrv_flush_all() for that
 * after calling this function.
 *
 * This pauses all block jobs and disables external clients. It must
 * be paired with bdrv_drain_all_end().
 *
 * NOTE: no new block jobs or BlockDriverStates can be created between
 * the bdrv_drain_all_begin() and bdrv_drain_all_end() calls.
 */
void bdrv_drain_all(void)
void bdrv_drain_all_begin(void)
{
    /* Always run first iteration so any pending completion BHs run */
    bool waited = true;
@@ -297,6 +303,7 @@ void bdrv_drain_all(void)
        aio_context_acquire(aio_context);
        bdrv_parent_drained_begin(bs);
        bdrv_io_unplugged_begin(bs);
        aio_disable_external(aio_context);
        aio_context_release(aio_context);

        if (!g_slist_find(aio_ctxs, aio_context)) {
@@ -326,17 +333,25 @@ void bdrv_drain_all(void)
        }
    }

    g_slist_free(aio_ctxs);
}

void bdrv_drain_all_end(void)
{
    BlockDriverState *bs;
    BdrvNextIterator it;
    BlockJob *job = NULL;

    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
        AioContext *aio_context = bdrv_get_aio_context(bs);

        aio_context_acquire(aio_context);
        aio_enable_external(aio_context);
        bdrv_io_unplugged_end(bs);
        bdrv_parent_drained_end(bs);
        aio_context_release(aio_context);
    }
    g_slist_free(aio_ctxs);

    job = NULL;
    while ((job = block_job_next(job))) {
        AioContext *aio_context = blk_get_aio_context(job->blk);

@@ -346,6 +361,12 @@ void bdrv_drain_all(void)
    }
}

void bdrv_drain_all(void)
{
    bdrv_drain_all_begin();
    bdrv_drain_all_end();
}

/**
 * Remove an active request from the tracked requests list
 *
+9 −2
Original line number Diff line number Diff line
@@ -530,7 +530,6 @@ static void mirror_exit(BlockJob *job, void *opaque)
        aio_context_release(replace_aio_context);
    }
    g_free(s->replaces);
    bdrv_op_unblock_all(target_bs, s->common.blocker);
    blk_unref(s->target);
    s->target = NULL;
    block_job_completed(&s->common, data->ret);
@@ -997,7 +996,15 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
        return;
    }

    bdrv_op_block_all(target, s->common.blocker);
    block_job_add_bdrv(&s->common, target);
    /* In commit_active_start() all intermediate nodes disappear, so
     * any jobs in them must be blocked */
    if (bdrv_chain_contains(bs, target)) {
        BlockDriverState *iter;
        for (iter = backing_bs(bs); iter != target; iter = backing_bs(iter)) {
            block_job_add_bdrv(&s->common, iter);
        }
    }

    s->common.co = qemu_coroutine_create(mirror_run, s);
    trace_mirror_start(bs, s, s->common.co, opaque);
Loading