diff options
Diffstat (limited to 'block/copy-before-write.c')
-rw-r--r-- | block/copy-before-write.c | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/block/copy-before-write.c b/block/copy-before-write.c index 2efe098aae..2cd68b480a 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c @@ -144,7 +144,8 @@ static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c, } } -static int cbw_init(BlockDriverState *bs, QDict *options, Error **errp) +static int cbw_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) { BDRVCopyBeforeWriteState *s = bs->opaque; BdrvDirtyBitmap *copy_bitmap; @@ -181,10 +182,21 @@ static int cbw_init(BlockDriverState *bs, QDict *options, Error **errp) return 0; } +static void cbw_close(BlockDriverState *bs) +{ + BDRVCopyBeforeWriteState *s = bs->opaque; + + block_copy_state_free(s->bcs); + s->bcs = NULL; +} + BlockDriver bdrv_cbw_filter = { .format_name = "copy-before-write", .instance_size = sizeof(BDRVCopyBeforeWriteState), + .bdrv_open = cbw_open, + .bdrv_close = cbw_close, + .bdrv_co_preadv = cbw_co_preadv, .bdrv_co_pwritev = cbw_co_pwritev, .bdrv_co_pwrite_zeroes = cbw_co_pwrite_zeroes, @@ -205,56 +217,40 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source, Error **errp) { ERRP_GUARD(); - int ret; BDRVCopyBeforeWriteState *state; BlockDriverState *top; QDict *opts; assert(source->total_sectors == target->total_sectors); - top = bdrv_new_open_driver(&bdrv_cbw_filter, filter_node_name, - BDRV_O_RDWR, errp); - if (!top) { - error_prepend(errp, "Cannot open driver: "); - return NULL; - } - state = top->opaque; - opts = qdict_new(); + qdict_put_str(opts, "driver", "copy-before-write"); + if (filter_node_name) { + qdict_put_str(opts, "node-name", filter_node_name); + } qdict_put_str(opts, "file", bdrv_get_node_name(source)); qdict_put_str(opts, "target", bdrv_get_node_name(target)); - ret = cbw_init(top, opts, errp); - qobject_unref(opts); - if (ret < 0) { - goto fail; - } - - bdrv_drained_begin(source); - ret = bdrv_replace_node(source, top, errp); - bdrv_drained_end(source); - if (ret < 0) { - error_prepend(errp, "Cannot append copy-before-write filter: "); - goto fail; + top = bdrv_insert_node(source, opts, BDRV_O_RDWR, errp); + if (!top) { + return NULL; } + state = top->opaque; *bcs = state->bcs; return top; - -fail: - block_copy_state_free(state->bcs); - bdrv_unref(top); - return NULL; } void bdrv_cbw_drop(BlockDriverState *bs) { - BDRVCopyBeforeWriteState *s = bs->opaque; - bdrv_drop_filter(bs, &error_abort); - - block_copy_state_free(s->bcs); - bdrv_unref(bs); } + +static void cbw_init(void) +{ + bdrv_register(&bdrv_cbw_filter); +} + +block_init(cbw_init); |