block/copy-before-write: make public block driver

Finally, copy-before-write gets own .bdrv_open and .bdrv_close
handlers, block_init() call and becomes available through bdrv_open().

To achieve this:

 - cbw_init gets unused flags argument and becomes cbw_open
 - block_copy_state_free() call moved to new cbw_close()
 - in bdrv_cbw_append:
   - options are completed with driver and node-name, and we can simply
     use bdrv_insert_node() to do both open and drained replacing
 - in bdrv_cbw_drop:
   - cbw_close() is now responsible for freeing s->bcs, so don't do it
     here

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210824083856.17408-22-vsementsov@virtuozzo.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
This commit is contained in:
Vladimir Sementsov-Ogievskiy 2021-08-24 11:38:43 +03:00 committed by Hanna Reitz
parent 201b4bb6c7
commit 751cec7a26
1 changed files with 28 additions and 32 deletions

View File

@ -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);