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:
parent
201b4bb6c7
commit
751cec7a26
|
@ -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;
|
BDRVCopyBeforeWriteState *s = bs->opaque;
|
||||||
BdrvDirtyBitmap *copy_bitmap;
|
BdrvDirtyBitmap *copy_bitmap;
|
||||||
|
@ -181,10 +182,21 @@ static int cbw_init(BlockDriverState *bs, QDict *options, Error **errp)
|
||||||
return 0;
|
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 = {
|
BlockDriver bdrv_cbw_filter = {
|
||||||
.format_name = "copy-before-write",
|
.format_name = "copy-before-write",
|
||||||
.instance_size = sizeof(BDRVCopyBeforeWriteState),
|
.instance_size = sizeof(BDRVCopyBeforeWriteState),
|
||||||
|
|
||||||
|
.bdrv_open = cbw_open,
|
||||||
|
.bdrv_close = cbw_close,
|
||||||
|
|
||||||
.bdrv_co_preadv = cbw_co_preadv,
|
.bdrv_co_preadv = cbw_co_preadv,
|
||||||
.bdrv_co_pwritev = cbw_co_pwritev,
|
.bdrv_co_pwritev = cbw_co_pwritev,
|
||||||
.bdrv_co_pwrite_zeroes = cbw_co_pwrite_zeroes,
|
.bdrv_co_pwrite_zeroes = cbw_co_pwrite_zeroes,
|
||||||
|
@ -205,56 +217,40 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
ERRP_GUARD();
|
ERRP_GUARD();
|
||||||
int ret;
|
|
||||||
BDRVCopyBeforeWriteState *state;
|
BDRVCopyBeforeWriteState *state;
|
||||||
BlockDriverState *top;
|
BlockDriverState *top;
|
||||||
QDict *opts;
|
QDict *opts;
|
||||||
|
|
||||||
assert(source->total_sectors == target->total_sectors);
|
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();
|
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, "file", bdrv_get_node_name(source));
|
||||||
qdict_put_str(opts, "target", bdrv_get_node_name(target));
|
qdict_put_str(opts, "target", bdrv_get_node_name(target));
|
||||||
|
|
||||||
ret = cbw_init(top, opts, errp);
|
top = bdrv_insert_node(source, opts, BDRV_O_RDWR, errp);
|
||||||
qobject_unref(opts);
|
if (!top) {
|
||||||
if (ret < 0) {
|
return NULL;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state = top->opaque;
|
||||||
*bcs = state->bcs;
|
*bcs = state->bcs;
|
||||||
|
|
||||||
return top;
|
return top;
|
||||||
|
|
||||||
fail:
|
|
||||||
block_copy_state_free(state->bcs);
|
|
||||||
bdrv_unref(top);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bdrv_cbw_drop(BlockDriverState *bs)
|
void bdrv_cbw_drop(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVCopyBeforeWriteState *s = bs->opaque;
|
|
||||||
|
|
||||||
bdrv_drop_filter(bs, &error_abort);
|
bdrv_drop_filter(bs, &error_abort);
|
||||||
|
|
||||||
block_copy_state_free(s->bcs);
|
|
||||||
|
|
||||||
bdrv_unref(bs);
|
bdrv_unref(bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cbw_init(void)
|
||||||
|
{
|
||||||
|
bdrv_register(&bdrv_cbw_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
block_init(cbw_init);
|
||||||
|
|
Loading…
Reference in New Issue