Commit 2c8cfc0b 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 19 Mar 2018 11:01:45 GMT
# gpg:                using RSA key 7F09B272C88F2FD6
# 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: (46 commits)
  iotests: Avoid realpath, for CentOS 6
  block: fix iotest 146 output expectations
  iscsi: fix iSER compilation
  block: Fix leak of ignore_children in error path
  vvfat: Fix inherit_options flags
  block/mirror: change the semantic of 'force' of block-job-cancel
  vpc: Require aligned size in .bdrv_co_create
  vpc: Support .bdrv_co_create
  vhdx: Support .bdrv_co_create
  vdi: Make comments consistent with other drivers
  qed: Support .bdrv_co_create
  qcow: Support .bdrv_co_create
  qemu-iotests: Enable write tests for parallels
  parallels: Support .bdrv_co_create
  iotests: Add regression test for commit base locking
  block: Fix flags in reopen queue
  vdi: Implement .bdrv_co_create
  vdi: Move file creation to vdi_co_create_opts
  vdi: Pull option parsing from vdi_co_create
  qemu-iotests: Test luks QMP image creation
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 590a3914 63ca8406
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -2883,8 +2883,16 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,

    /* Inherit from parent node */
    if (parent_options) {
        QemuOpts *opts;
        QDict *options_copy;
        assert(!flags);
        role->inherit_options(&flags, options, parent_flags, parent_options);
        options_copy = qdict_clone_shallow(options);
        opts = qemu_opts_create(&bdrv_runtime_opts, NULL, 0, &error_abort);
        qemu_opts_absorb_qdict(opts, options_copy, NULL);
        update_flags_from_options(&flags, opts);
        qemu_opts_del(opts);
        QDECREF(options_copy);
    }

    /* Old values are used for options that aren't set yet */
@@ -3671,12 +3679,12 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
        GSList *ignore_children = g_slist_prepend(NULL, c);
        bdrv_check_update_perm(base, NULL, c->perm, c->shared_perm,
                               ignore_children, &local_err);
        g_slist_free(ignore_children);
        if (local_err) {
            ret = -EPERM;
            error_report_err(local_err);
            goto exit;
        }
        g_slist_free(ignore_children);

        /* If so, update the backing file path in the image file */
        if (c->role->update_filename) {
+2 −3
Original line number Diff line number Diff line
@@ -206,7 +206,7 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
    BdrvDirtyBitmap *bm;
    BlockDriverState *bs = blk_bs(job->common.blk);

    if (ret < 0 || block_job_is_cancelled(&job->common)) {
    if (ret < 0) {
        /* Merge the successor back into the parent, delete nothing. */
        bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
        assert(bm);
@@ -621,7 +621,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
    }

    /* job->common.len is fixed, so we can't allow resize */
    job = block_job_create(job_id, &backup_job_driver, bs,
    job = block_job_create(job_id, &backup_job_driver, txn, bs,
                           BLK_PERM_CONSISTENT_READ,
                           BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
                           BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD,
@@ -677,7 +677,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
    block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
                       &error_abort);
    job->common.len = len;
    block_job_txn_add_job(txn, &job->common);

    return &job->common;

+1 −1
Original line number Diff line number Diff line
@@ -289,7 +289,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
        return;
    }

    s = block_job_create(job_id, &commit_job_driver, bs, 0, BLK_PERM_ALL,
    s = block_job_create(job_id, &commit_job_driver, NULL, bs, 0, BLK_PERM_ALL,
                         speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);
    if (!s) {
        return;
+108 −42
Original line number Diff line number Diff line
@@ -71,8 +71,6 @@ static ssize_t block_crypto_read_func(QCryptoBlock *block,


struct BlockCryptoCreateData {
    const char *filename;
    QemuOpts *opts;
    BlockBackend *blk;
    uint64_t size;
};
@@ -103,27 +101,18 @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
                                      Error **errp)
{
    struct BlockCryptoCreateData *data = opaque;
    int ret;

    if (data->size > INT64_MAX || headerlen > INT64_MAX - data->size) {
        error_setg(errp, "The requested file size is too large");
        return -EFBIG;
    }

    /* User provided size should reflect amount of space made
     * available to the guest, so we must take account of that
     * which will be used by the crypto header
     */
    data->size += headerlen;

    qemu_opt_set_number(data->opts, BLOCK_OPT_SIZE, data->size, &error_abort);
    ret = bdrv_create_file(data->filename, data->opts, errp);
    if (ret < 0) {
        return -1;
    }

    data->blk = blk_new_open(data->filename, NULL, NULL,
                             BDRV_O_RDWR | BDRV_O_PROTOCOL, errp);
    if (!data->blk) {
        return -1;
    }

    return 0;
    return blk_truncate(data->blk, data->size + headerlen, PREALLOC_MODE_OFF,
                        errp);
}


@@ -322,30 +311,29 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
}


static int block_crypto_create_generic(QCryptoBlockFormat format,
                                       const char *filename,
                                       QemuOpts *opts,
static int block_crypto_co_create_generic(BlockDriverState *bs,
                                          int64_t size,
                                          QCryptoBlockCreateOptions *opts,
                                          Error **errp)
{
    int ret = -EINVAL;
    QCryptoBlockCreateOptions *create_opts = NULL;
    int ret;
    BlockBackend *blk;
    QCryptoBlock *crypto = NULL;
    struct BlockCryptoCreateData data = {
        .size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
                         BDRV_SECTOR_SIZE),
        .opts = opts,
        .filename = filename,
    };
    QDict *cryptoopts;
    struct BlockCryptoCreateData data;

    cryptoopts = qemu_opts_to_qdict(opts, NULL);
    blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);

    create_opts = block_crypto_create_opts_init(format, cryptoopts, errp);
    if (!create_opts) {
        return -1;
    ret = blk_insert_bs(blk, bs, errp);
    if (ret < 0) {
        goto cleanup;
    }

    crypto = qcrypto_block_create(create_opts, NULL,
    data = (struct BlockCryptoCreateData) {
        .blk = blk,
        .size = size,
    };

    crypto = qcrypto_block_create(opts, NULL,
                                  block_crypto_init_func,
                                  block_crypto_write_func,
                                  &data,
@@ -358,10 +346,8 @@ static int block_crypto_create_generic(QCryptoBlockFormat format,

    ret = 0;
 cleanup:
    QDECREF(cryptoopts);
    qcrypto_block_free(crypto);
    blk_unref(data.blk);
    qapi_free_QCryptoBlockCreateOptions(create_opts);
    blk_unref(blk);
    return ret;
}

@@ -537,7 +523,10 @@ static int64_t block_crypto_getlength(BlockDriverState *bs)

    uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
    assert(offset < INT64_MAX);
    assert(offset < len);

    if (offset > len) {
        return -EIO;
    }

    len -= offset;

@@ -562,12 +551,88 @@ static int block_crypto_open_luks(BlockDriverState *bs,
                                     bs, options, flags, errp);
}

static int coroutine_fn
block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
{
    BlockdevCreateOptionsLUKS *luks_opts;
    BlockDriverState *bs = NULL;
    QCryptoBlockCreateOptions create_opts;
    int ret;

    assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
    luks_opts = &create_options->u.luks;

    bs = bdrv_open_blockdev_ref(luks_opts->file, errp);
    if (bs == NULL) {
        return -EIO;
    }

    create_opts = (QCryptoBlockCreateOptions) {
        .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
        .u.luks = *qapi_BlockdevCreateOptionsLUKS_base(luks_opts),
    };

    ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
                                         errp);
    if (ret < 0) {
        goto fail;
    }

    ret = 0;
fail:
    bdrv_unref(bs);
    return ret;
}

static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename,
                                                         QemuOpts *opts,
                                                         Error **errp)
{
    return block_crypto_create_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
                                       filename, opts, errp);
    QCryptoBlockCreateOptions *create_opts = NULL;
    BlockDriverState *bs = NULL;
    QDict *cryptoopts;
    int64_t size;
    int ret;

    /* Parse options */
    size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);

    cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
                                             &block_crypto_create_opts_luks,
                                             true);

    create_opts = block_crypto_create_opts_init(Q_CRYPTO_BLOCK_FORMAT_LUKS,
                                                cryptoopts, errp);
    if (!create_opts) {
        ret = -EINVAL;
        goto fail;
    }

    /* Create protocol layer */
    ret = bdrv_create_file(filename, opts, errp);
    if (ret < 0) {
        return ret;
    }

    bs = bdrv_open(filename, NULL, NULL,
                   BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
    if (!bs) {
        ret = -EINVAL;
        goto fail;
    }

    /* Create format layer */
    ret = block_crypto_co_create_generic(bs, size, create_opts, errp);
    if (ret < 0) {
        goto fail;
    }

    ret = 0;
fail:
    bdrv_unref(bs);
    qapi_free_QCryptoBlockCreateOptions(create_opts);
    QDECREF(cryptoopts);
    return ret;
}

static int block_crypto_get_info_luks(BlockDriverState *bs,
@@ -623,6 +688,7 @@ BlockDriver bdrv_crypto_luks = {
    .bdrv_open          = block_crypto_open_luks,
    .bdrv_close         = block_crypto_close,
    .bdrv_child_perm    = bdrv_format_default_perms,
    .bdrv_co_create     = block_crypto_co_create_luks,
    .bdrv_co_create_opts = block_crypto_co_create_opts_luks,
    .bdrv_truncate      = block_crypto_truncate,
    .create_opts        = &block_crypto_create_opts_luks,
+1 −1
Original line number Diff line number Diff line
@@ -2244,7 +2244,7 @@ static BlockDriver bdrv_iser = {
    .create_opts            = &iscsi_create_opts,
    .bdrv_reopen_prepare    = iscsi_reopen_prepare,
    .bdrv_reopen_commit     = iscsi_reopen_commit,
    .bdrv_invalidate_cache  = iscsi_invalidate_cache,
    .bdrv_co_invalidate_cache  = iscsi_co_invalidate_cache,

    .bdrv_getlength  = iscsi_getlength,
    .bdrv_get_info   = iscsi_get_info,
Loading