Commit 57fac92c authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging



Block pull request

# gpg: Signature made Thu 13 Mar 2014 13:50:49 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/block-pull-request: (24 commits)
  block/raw-win32: bdrv_parse_filename() for hdev
  block/raw-posix: Strip protocol prefix on creation
  block/raw-posix: bdrv_parse_filename() for cdrom
  block/raw-posix: bdrv_parse_filename() for floppy
  block/raw-posix: bdrv_parse_filename() for hdev
  qemu-io: Fix warnings from static code analysis
  block: Unlink temporary file
  qcow2: Don't write with BDRV_O_INCOMING
  qcow2: Keep option in qcow2_invalidate_cache()
  qmp: add query-iothreads command
  iothread: stash thread ID away
  dataplane: replace internal thread with IOThread
  iothread: add "iothread" qdev property type
  qdev: make get_pointer() handle temporary strings
  iothread: add I/O thread object
  aio: add aio_context_acquire() and aio_context_release()
  rfifolock: add recursive FIFO lock
  object: add object_get_canonical_path_component()
  block: Rewrite the snapshot authorization mechanism for block filters.
  iotests: Test corruption during COW request
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 41975b26 57ed25b1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ libcacard-y += libcacard/vcardt.o

ifeq ($(CONFIG_SOFTMMU),y)
common-obj-y = blockdev.o blockdev-nbd.o block/
common-obj-y += iothread.o
common-obj-y += net/
common-obj-y += qdev-monitor.o device-hotplug.o
common-obj-$(CONFIG_WIN32) += os-win32.o
+18 −0
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ aio_ctx_finalize(GSource *source)
    thread_pool_free(ctx->thread_pool);
    aio_set_event_notifier(ctx, &ctx->notifier, NULL);
    event_notifier_cleanup(&ctx->notifier);
    rfifolock_destroy(&ctx->lock);
    qemu_mutex_destroy(&ctx->bh_lock);
    g_array_free(ctx->pollfds, TRUE);
    timerlistgroup_deinit(&ctx->tlg);
@@ -250,6 +251,12 @@ static void aio_timerlist_notify(void *opaque)
    aio_notify(opaque);
}

static void aio_rfifolock_cb(void *opaque)
{
    /* Kick owner thread in case they are blocked in aio_poll() */
    aio_notify(opaque);
}

AioContext *aio_context_new(void)
{
    AioContext *ctx;
@@ -257,6 +264,7 @@ AioContext *aio_context_new(void)
    ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
    ctx->thread_pool = NULL;
    qemu_mutex_init(&ctx->bh_lock);
    rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
    event_notifier_init(&ctx->notifier, false);
    aio_set_event_notifier(ctx, &ctx->notifier, 
                           (EventNotifierHandler *)
@@ -275,3 +283,13 @@ void aio_context_unref(AioContext *ctx)
{
    g_source_unref(&ctx->source);
}

void aio_context_acquire(AioContext *ctx)
{
    rfifolock_lock(&ctx->lock);
}

void aio_context_release(AioContext *ctx)
{
    rfifolock_unlock(&ctx->lock);
}
+32 −29
Original line number Diff line number Diff line
@@ -1321,7 +1321,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
                          bdrv_open_flags(bs, flags | BDRV_O_UNMAP) |
                          BDRV_O_PROTOCOL, true, &local_err);
    if (ret < 0) {
        goto fail;
        goto unlink_and_fail;
    }

    /* Find the right image format driver */
@@ -4055,7 +4055,7 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)

int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
{
    while (bs && bs->drv && !bs->drv->bdrv_debug_resume) {
    while (bs && (!bs->drv || !bs->drv->bdrv_debug_resume)) {
        bs = bs->file;
    }

@@ -4776,9 +4776,17 @@ flush_parent:

void bdrv_invalidate_cache(BlockDriverState *bs)
{
    if (bs->drv && bs->drv->bdrv_invalidate_cache) {
    if (!bs->drv)  {
        return;
    }

    if (bs->drv->bdrv_invalidate_cache) {
        bs->drv->bdrv_invalidate_cache(bs);
    } else if (bs->file) {
        bdrv_invalidate_cache(bs->file);
    }

    refresh_total_sectors(bs, bs->total_sectors);
}

void bdrv_invalidate_cache_all(void)
@@ -5390,43 +5398,37 @@ int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options)
    return bs->drv->bdrv_amend_options(bs, options);
}

/* Used to recurse on single child block filters.
 * Single child block filter will store their child in bs->file.
/* This function will be called by the bdrv_recurse_is_first_non_filter method
 * of block filter and by bdrv_is_first_non_filter.
 * It is used to test if the given bs is the candidate or recurse more in the
 * node graph.
 */
bool bdrv_generic_is_first_non_filter(BlockDriverState *bs,
bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
                                      BlockDriverState *candidate)
{
    if (!bs->drv) {
        return false;
    }

    if (!bs->drv->authorizations[BS_IS_A_FILTER]) {
        if (bs == candidate) {
            return true;
        } else {
            return false;
        }
    }

    if (!bs->drv->authorizations[BS_FILTER_PASS_DOWN]) {
        return false;
    }

    if (!bs->file) {
    /* return false if basic checks fails */
    if (!bs || !bs->drv) {
        return false;
    }

    return bdrv_recurse_is_first_non_filter(bs->file, candidate);
    /* the code reached a non block filter driver -> check if the bs is
     * the same as the candidate. It's the recursion termination condition.
     */
    if (!bs->drv->is_filter) {
        return bs == candidate;
    }
    /* Down this path the driver is a block filter driver */

bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
                                      BlockDriverState *candidate)
{
    if (bs->drv && bs->drv->bdrv_recurse_is_first_non_filter) {
    /* If the block filter recursion method is defined use it to recurse down
     * the node graph.
     */
    if (bs->drv->bdrv_recurse_is_first_non_filter) {
        return bs->drv->bdrv_recurse_is_first_non_filter(bs, candidate);
    }

    return bdrv_generic_is_first_non_filter(bs, candidate);
    /* the driver is a block filter but don't allow to recurse -> return false
     */
    return false;
}

/* This function checks if the candidate is the first non filter bs down it's
@@ -5441,6 +5443,7 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate)
    QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
        bool perm;

        /* try to recurse in this top level bs */
        perm = bdrv_recurse_is_first_non_filter(bs, candidate);

        /* candidate is the first non filter */
+16 −1
Original line number Diff line number Diff line
@@ -288,6 +288,20 @@ static BlockDriverAIOCB *blkverify_aio_flush(BlockDriverState *bs,
    return bdrv_aio_flush(s->test_file, cb, opaque);
}

static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
                                                  BlockDriverState *candidate)
{
    BDRVBlkverifyState *s = bs->opaque;

    bool perm = bdrv_recurse_is_first_non_filter(bs->file, candidate);

    if (perm) {
        return true;
    }

    return bdrv_recurse_is_first_non_filter(s->test_file, candidate);
}

static BlockDriver bdrv_blkverify = {
    .format_name            = "blkverify",
    .protocol_name          = "blkverify",
@@ -302,7 +316,8 @@ static BlockDriver bdrv_blkverify = {
    .bdrv_aio_writev        = blkverify_aio_writev,
    .bdrv_aio_flush         = blkverify_aio_flush,

    .authorizations         = { true, false },
    .is_filter              = true,
    .bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter,
};

static void bdrv_blkverify_init(void)
+4 −0
Original line number Diff line number Diff line
@@ -380,6 +380,10 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,

    BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);

    if (!bs->drv) {
        return -ENOMEDIUM;
    }

    /* Call .bdrv_co_readv() directly instead of using the public block-layer
     * interface.  This avoids double I/O throttling and request tracking,
     * which can lead to deadlock when block layer copy-on-read is enabled.
Loading