block/copy-before-write: use file child instead of backing

We are going to publish copy-before-write filter, and there no public
backing-child-based filter in Qemu. No reason to create a precedent, so
let's refactor copy-before-write filter instead.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210824083856.17408-13-vsementsov@virtuozzo.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
This commit is contained in:
Vladimir Sementsov-Ogievskiy 2021-08-24 11:38:34 +03:00 committed by Hanna Reitz
parent 451532311a
commit 3c1e63277e

View File

@ -43,7 +43,7 @@ static coroutine_fn int cbw_co_preadv(
BlockDriverState *bs, uint64_t offset, uint64_t bytes, BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags) QEMUIOVector *qiov, int flags)
{ {
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags); return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
} }
static coroutine_fn int cbw_do_copy_before_write(BlockDriverState *bs, static coroutine_fn int cbw_do_copy_before_write(BlockDriverState *bs,
@ -71,7 +71,7 @@ static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs,
return ret; return ret;
} }
return bdrv_co_pdiscard(bs->backing, offset, bytes); return bdrv_co_pdiscard(bs->file, offset, bytes);
} }
static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
@ -82,7 +82,7 @@ static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
return ret; return ret;
} }
return bdrv_co_pwrite_zeroes(bs->backing, offset, bytes, flags); return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
} }
static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs, static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
@ -95,29 +95,22 @@ static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
return ret; return ret;
} }
return bdrv_co_pwritev(bs->backing, offset, bytes, qiov, flags); return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
} }
static int coroutine_fn cbw_co_flush(BlockDriverState *bs) static int coroutine_fn cbw_co_flush(BlockDriverState *bs)
{ {
if (!bs->backing) { if (!bs->file) {
return 0; return 0;
} }
return bdrv_co_flush(bs->backing->bs); return bdrv_co_flush(bs->file->bs);
} }
static void cbw_refresh_filename(BlockDriverState *bs) static void cbw_refresh_filename(BlockDriverState *bs)
{ {
if (bs->backing == NULL) {
/*
* we can be here after failed bdrv_attach_child in
* bdrv_set_backing_hd
*/
return;
}
pstrcpy(bs->exact_filename, sizeof(bs->exact_filename), pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
bs->backing->bs->filename); bs->file->bs->filename);
} }
static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c, static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c,
@ -186,6 +179,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
top = bdrv_new_open_driver(&bdrv_cbw_filter, filter_node_name, top = bdrv_new_open_driver(&bdrv_cbw_filter, filter_node_name,
BDRV_O_RDWR, errp); BDRV_O_RDWR, errp);
if (!top) { if (!top) {
error_prepend(errp, "Cannot open driver: ");
return NULL; return NULL;
} }
@ -201,21 +195,32 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
state->target = bdrv_attach_child(top, target, "target", &child_of_bds, state->target = bdrv_attach_child(top, target, "target", &child_of_bds,
BDRV_CHILD_DATA, errp); BDRV_CHILD_DATA, errp);
if (!state->target) { if (!state->target) {
error_prepend(errp, "Cannot attach target child: ");
bdrv_unref(top);
return NULL;
}
bdrv_ref(source);
top->file = bdrv_attach_child(top, source, "file", &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
errp);
if (!top->file) {
error_prepend(errp, "Cannot attach file child: ");
bdrv_unref(top); bdrv_unref(top);
return NULL; return NULL;
} }
bdrv_drained_begin(source); bdrv_drained_begin(source);
ret = bdrv_append(top, source, errp); ret = bdrv_replace_node(source, top, errp);
if (ret < 0) { if (ret < 0) {
error_prepend(errp, "Cannot append copy-before-write filter: "); error_prepend(errp, "Cannot append copy-before-write filter: ");
goto fail; goto fail;
} }
appended = true; appended = true;
state->bcs = block_copy_state_new(top->backing, state->target, state->bcs = block_copy_state_new(top->file, state->target, false, compress,
false, compress, errp); errp);
if (!state->bcs) { if (!state->bcs) {
error_prepend(errp, "Cannot create block-copy-state: "); error_prepend(errp, "Cannot create block-copy-state: ");
goto fail; goto fail;