Commit dc0b0616 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'stefanha/block' into staging

# By Stefan Hajnoczi (14) and others
# Via Stefan Hajnoczi
* stefanha/block: (28 commits)
  blockdev: Fix up copyright and permission notice
  qemu-iotests: use -nographic in test case 007
  qemu-iotests: add tests for rebasing zero clusters
  dataplane: fix hang introduced by AioContext transition
  coroutine: use AioContext for CoQueue BH
  threadpool: drop global thread pool
  block: add bdrv_get_aio_context()
  aio: add a ThreadPool instance to AioContext
  threadpool: add thread_pool_new() and thread_pool_free()
  threadpool: move globals into struct ThreadPool
  main-loop: add qemu_get_aio_context()
  sheepdog: set io_flush handler in do_co_req
  sheepdog: use non-blocking fd in coroutine context
  qcow2: make is_allocated return true for zero clusters
  qcow2: drop unnecessary flush in qcow2_update_snapshot_refcount()
  qcow2: drop flush in update_cluster_refcount()
  qcow2: flush in qcow2_update_snapshot_refcount()
  qcow2: set L2 cache dependency in qcow2_alloc_bytes()
  qcow2: flush refcount cache correctly in qcow2_write_snapshots()
  qcow2: flush refcount cache correctly in alloc_refcount_block()
  ...
parents d4d76824 3618a094
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include "qemu-common.h"
#include "block/aio.h"
#include "block/thread-pool.h"
#include "qemu/main-loop.h"

/***********************************************************/
@@ -172,6 +173,7 @@ aio_ctx_finalize(GSource *source)
{
    AioContext *ctx = (AioContext *) source;

    thread_pool_free(ctx->thread_pool);
    aio_set_event_notifier(ctx, &ctx->notifier, NULL, NULL);
    event_notifier_cleanup(&ctx->notifier);
    g_array_free(ctx->pollfds, TRUE);
@@ -190,6 +192,14 @@ GSource *aio_get_g_source(AioContext *ctx)
    return &ctx->source;
}

ThreadPool *aio_get_thread_pool(AioContext *ctx)
{
    if (!ctx->thread_pool) {
        ctx->thread_pool = thread_pool_new(ctx);
    }
    return ctx->thread_pool;
}

void aio_notify(AioContext *ctx)
{
    event_notifier_set(&ctx->notifier);
@@ -200,6 +210,7 @@ AioContext *aio_context_new(void)
    AioContext *ctx;
    ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));
    ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
    ctx->thread_pool = NULL;
    event_notifier_init(&ctx->notifier, false);
    aio_set_event_notifier(ctx, &ctx->notifier, 
                           (EventNotifierHandler *)
+68 −19
Original line number Diff line number Diff line
@@ -665,15 +665,18 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)

/*
 * Common part for opening disk images and files
 *
 * Removes all processed options from *options.
 */
static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
    const char *filename,
    const char *filename, QDict *options,
    int flags, BlockDriver *drv)
{
    int ret, open_flags;

    assert(drv != NULL);
    assert(bs->file == NULL);
    assert(options == NULL || bs->options != options);

    trace_bdrv_open_common(bs, filename, flags, drv->format_name);

@@ -710,7 +713,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
    } else {
        assert(file != NULL);
        bs->file = file;
        ret = drv->bdrv_open(bs, open_flags);
        ret = drv->bdrv_open(bs, options, open_flags);
    }

    if (ret < 0) {
@@ -752,7 +755,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
    }

    bs = bdrv_new("");
    ret = bdrv_open_common(bs, NULL, filename, flags, drv);
    ret = bdrv_open_common(bs, NULL, filename, NULL, flags, drv);
    if (ret < 0) {
        bdrv_delete(bs);
        return ret;
@@ -788,7 +791,8 @@ int bdrv_open_backing_file(BlockDriverState *bs)
    /* backing files always opened read-only */
    back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT);

    ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
    ret = bdrv_open(bs->backing_hd, backing_filename, NULL,
                    back_flags, back_drv);
    if (ret < 0) {
        bdrv_delete(bs->backing_hd);
        bs->backing_hd = NULL;
@@ -800,15 +804,29 @@ int bdrv_open_backing_file(BlockDriverState *bs)

/*
 * Opens a disk image (raw, qcow2, vmdk, ...)
 *
 * options is a QDict of options to pass to the block drivers, or NULL for an
 * empty set of options. The reference to the QDict belongs to the block layer
 * after the call (even on failure), so if the caller intends to reuse the
 * dictionary, it needs to use QINCREF() before calling bdrv_open.
 */
int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
              BlockDriver *drv)
int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
              int flags, BlockDriver *drv)
{
    int ret;
    /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
    char tmp_filename[PATH_MAX + 1];
    BlockDriverState *file = NULL;

    /* NULL means an empty set of options */
    if (options == NULL) {
        options = qdict_new();
    }

    bs->options = options;
    options = qdict_clone_shallow(options);

    /* For snapshot=on, create a temporary qcow2 overlay */
    if (flags & BDRV_O_SNAPSHOT) {
        BlockDriverState *bs1;
        int64_t total_size;
@@ -822,10 +840,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,

        /* if there is a backing file, use it */
        bs1 = bdrv_new("");
        ret = bdrv_open(bs1, filename, 0, drv);
        ret = bdrv_open(bs1, filename, NULL, 0, drv);
        if (ret < 0) {
            bdrv_delete(bs1);
            return ret;
            goto fail;
        }
        total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;

@@ -836,15 +854,17 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,

        ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
        if (ret < 0) {
            return ret;
            goto fail;
        }

        /* Real path is meaningless for protocols */
        if (is_protocol)
        if (is_protocol) {
            snprintf(backing_filename, sizeof(backing_filename),
                     "%s", filename);
        else if (!realpath(filename, backing_filename))
            return -errno;
        } else if (!realpath(filename, backing_filename)) {
            ret = -errno;
            goto fail;
        }

        bdrv_qcow2 = bdrv_find_format("qcow2");
        options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
@@ -859,7 +879,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
        ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
        free_option_parameters(options);
        if (ret < 0) {
            return ret;
            goto fail;
        }

        filename = tmp_filename;
@@ -874,7 +894,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,

    ret = bdrv_file_open(&file, filename, bdrv_open_flags(bs, flags));
    if (ret < 0) {
        return ret;
        goto fail;
    }

    /* Find the right image format driver */
@@ -887,7 +907,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
    }

    /* Open the image */
    ret = bdrv_open_common(bs, file, filename, flags, drv);
    ret = bdrv_open_common(bs, file, filename, options, flags, drv);
    if (ret < 0) {
        goto unlink_and_fail;
    }
@@ -901,10 +921,21 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
    if ((flags & BDRV_O_NO_BACKING) == 0) {
        ret = bdrv_open_backing_file(bs);
        if (ret < 0) {
            bdrv_close(bs);
            return ret;
            goto close_and_fail;
        }
    }

    /* Check if any unknown options were used */
    if (qdict_size(options) != 0) {
        const QDictEntry *entry = qdict_first(options);
        qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by "
            "device '%s' doesn't support the option '%s'",
            drv->format_name, bs->device_name, entry->key);

        ret = -EINVAL;
        goto close_and_fail;
    }
    QDECREF(options);

    if (!bdrv_key_required(bs)) {
        bdrv_dev_change_media_cb(bs, true);
@@ -924,6 +955,15 @@ unlink_and_fail:
    if (bs->is_temporary) {
        unlink(filename);
    }
fail:
    QDECREF(bs->options);
    QDECREF(options);
    bs->options = NULL;
    return ret;

close_and_fail:
    bdrv_close(bs);
    QDECREF(options);
    return ret;
}

@@ -1193,6 +1233,8 @@ void bdrv_close(BlockDriverState *bs)
        bs->valid_key = 0;
        bs->sg = 0;
        bs->growable = 0;
        QDECREF(bs->options);
        bs->options = NULL;

        if (bs->file != NULL) {
            bdrv_delete(bs->file);
@@ -3190,7 +3232,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
    if (bs->file) {
        drv->bdrv_close(bs);
        ret = bdrv_snapshot_goto(bs->file, snapshot_id);
        open_ret = drv->bdrv_open(bs, bs->open_flags);
        open_ret = drv->bdrv_open(bs, NULL, bs->open_flags);
        if (open_ret < 0) {
            bdrv_delete(bs->file);
            bs->drv = NULL;
@@ -4594,7 +4636,8 @@ void bdrv_img_create(const char *filename, const char *fmt,

            bs = bdrv_new("");

            ret = bdrv_open(bs, backing_file->value.s, back_flags, backing_drv);
            ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
                            backing_drv);
            if (ret < 0) {
                error_setg_errno(errp, -ret, "Could not open '%s'",
                                 backing_file->value.s);
@@ -4638,3 +4681,9 @@ out:
        bdrv_delete(bs);
    }
}

AioContext *bdrv_get_aio_context(BlockDriverState *bs)
{
    /* Currently BlockDriverState always uses the main loop AioContext */
    return qemu_get_aio_context();
}
+1 −1
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ static int blkverify_open(BlockDriverState *bs, const char *filename, int flags)

    /* Open the test file */
    s->test_file = bdrv_new("");
    ret = bdrv_open(s->test_file, filename, flags, NULL);
    ret = bdrv_open(s->test_file, filename, NULL, flags, NULL);
    if (ret < 0) {
        bdrv_delete(s->test_file);
        s->test_file = NULL;
+1 −1
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
    return 0;
}

static int bochs_open(BlockDriverState *bs, int flags)
static int bochs_open(BlockDriverState *bs, QDict *options, int flags)
{
    BDRVBochsState *s = bs->opaque;
    int i;
+1 −1
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
    return 0;
}

static int cloop_open(BlockDriverState *bs, int flags)
static int cloop_open(BlockDriverState *bs, QDict *options, int flags)
{
    BDRVCloopState *s = bs->opaque;
    uint32_t offsets_size, max_compressed_block_size = 1, i;
Loading