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

block: Add error parameter to blk_insert_bs()



Now that blk_insert_bs() requests the BlockBackend permissions for the
node it attaches to, it can fail. Instead of aborting, pass the errors
to the callers.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Acked-by: default avatarFam Zheng <famz@redhat.com>
parent 6d0eb64d
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -2194,8 +2194,11 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
        }
        if (file_bs != NULL) {
            file = blk_new(BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
            blk_insert_bs(file, file_bs);
            blk_insert_bs(file, file_bs, &local_err);
            bdrv_unref(file_bs);
            if (local_err) {
                goto fail;
            }

            qdict_put(options, "file",
                      qstring_from_str(bdrv_get_node_name(file_bs)));
+4 −1
Original line number Diff line number Diff line
@@ -626,7 +626,10 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,

    /* FIXME Use real permissions */
    job->target = blk_new(0, BLK_PERM_ALL);
    blk_insert_bs(job->target, target);
    ret = blk_insert_bs(job->target, target, errp);
    if (ret < 0) {
        goto error;
    }

    job->on_source_error = on_source_error;
    job->on_target_error = on_target_error;
+8 −5
Original line number Diff line number Diff line
@@ -508,19 +508,22 @@ void blk_remove_bs(BlockBackend *blk)
/*
 * Associates a new BlockDriverState with @blk.
 */
void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs)
int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
{
    bdrv_ref(bs);
    /* FIXME Error handling */
    blk->root = bdrv_root_attach_child(bs, "root", &child_root,
                                       blk->perm, blk->shared_perm, blk,
                                       &error_abort);
                                       blk->perm, blk->shared_perm, blk, errp);
    if (blk->root == NULL) {
        return -EPERM;
    }
    bdrv_ref(bs);

    notifier_list_notify(&blk->insert_bs_notifiers, blk);
    if (blk->public.throttle_state) {
        throttle_timers_attach_aio_context(
            &blk->public.throttle_timers, bdrv_get_aio_context(bs));
    }

    return 0;
}

/*
+30 −8
Original line number Diff line number Diff line
@@ -220,6 +220,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
    BlockDriverState *iter;
    BlockDriverState *overlay_bs;
    Error *local_err = NULL;
    int ret;

    assert(top != bs);
    if (top == base) {
@@ -256,8 +257,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
        bdrv_reopen_multiple(bdrv_get_aio_context(bs), reopen_queue, &local_err);
        if (local_err != NULL) {
            error_propagate(errp, local_err);
            block_job_unref(&s->common);
            return;
            goto fail;
        }
    }

@@ -277,11 +277,17 @@ void commit_start(const char *job_id, BlockDriverState *bs,

    /* FIXME Use real permissions */
    s->base = blk_new(0, BLK_PERM_ALL);
    blk_insert_bs(s->base, base);
    ret = blk_insert_bs(s->base, base, errp);
    if (ret < 0) {
        goto fail;
    }

    /* FIXME Use real permissions */
    s->top = blk_new(0, BLK_PERM_ALL);
    blk_insert_bs(s->top, top);
    ret = blk_insert_bs(s->top, top, errp);
    if (ret < 0) {
        goto fail;
    }

    s->active = bs;

@@ -294,6 +300,16 @@ void commit_start(const char *job_id, BlockDriverState *bs,

    trace_commit_start(bs, base, top, s);
    block_job_start(&s->common);
    return;

fail:
    if (s->base) {
        blk_unref(s->base);
    }
    if (s->top) {
        blk_unref(s->top);
    }
    block_job_unref(&s->common);
}


@@ -332,11 +348,17 @@ int bdrv_commit(BlockDriverState *bs)

    /* FIXME Use real permissions */
    src = blk_new(0, BLK_PERM_ALL);
    blk_insert_bs(src, bs);

    /* FIXME Use real permissions */
    backing = blk_new(0, BLK_PERM_ALL);
    blk_insert_bs(backing, bs->backing->bs);

    ret = blk_insert_bs(src, bs, NULL);
    if (ret < 0) {
        goto ro_cleanup;
    }

    ret = blk_insert_bs(backing, bs->backing->bs, NULL);
    if (ret < 0) {
        goto ro_cleanup;
    }

    length = blk_getlength(src);
    if (length < 0) {
+12 −3
Original line number Diff line number Diff line
@@ -525,9 +525,12 @@ static void mirror_exit(BlockJob *job, void *opaque)
        bdrv_replace_in_backing_chain(to_replace, target_bs);
        bdrv_drained_end(target_bs);

        /* We just changed the BDS the job BB refers to */
        /* We just changed the BDS the job BB refers to, so switch the BB back
         * so the cleanup does the right thing. We don't need any permissions
         * any more now. */
        blk_remove_bs(job->blk);
        blk_insert_bs(job->blk, src);
        blk_set_perm(job->blk, 0, BLK_PERM_ALL, &error_abort);
        blk_insert_bs(job->blk, src, &error_abort);
    }
    if (s->to_replace) {
        bdrv_op_unblock_all(s->to_replace, s->replace_blocker);
@@ -995,6 +998,7 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
                             bool auto_complete)
{
    MirrorBlockJob *s;
    int ret;

    if (granularity == 0) {
        granularity = bdrv_get_default_bitmap_granularity(target);
@@ -1019,7 +1023,12 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,

    /* FIXME Use real permissions */
    s->target = blk_new(0, BLK_PERM_ALL);
    blk_insert_bs(s->target, target);
    ret = blk_insert_bs(s->target, target, errp);
    if (ret < 0) {
        blk_unref(s->target);
        block_job_unref(&s->common);
        return;
    }

    s->replaces = g_strdup(replaces);
    s->on_source_error = on_source_error;
Loading