@@ -43,7 +43,7 @@ static coroutine_fn int cbw_co_preadv(
BlockDriverState *bs, uint64_t offset, uint64_t bytes,
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,
@@ -71,7 +71,7 @@ static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs,
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,
@@ -82,7 +82,7 @@ static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
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,
@@ -95,29 +95,22 @@ static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
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)
{
- if (!bs->backing) {
+ if (!bs->file) {
return 0;
}
- return bdrv_co_flush(bs->backing->bs);
+ return bdrv_co_flush(bs->file->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),
- bs->backing->bs->filename);
+ bs->file->bs->filename);
}
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,
BDRV_O_RDWR, errp);
if (!top) {
+ error_prepend(errp, "Cannot open driver: ");
return NULL;
}
@@ -201,21 +195,32 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
state->target = bdrv_attach_child(top, target, "target", &child_of_bds,
BDRV_CHILD_DATA, errp);
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);
return NULL;
}
bdrv_drained_begin(source);
- ret = bdrv_append(top, source, errp);
+ ret = bdrv_replace_node(source, top, errp);
if (ret < 0) {
error_prepend(errp, "Cannot append copy-before-write filter: ");
goto fail;
}
appended = true;
- state->bcs = block_copy_state_new(top->backing, state->target,
- false, compress, errp);
+ state->bcs = block_copy_state_new(top->file, state->target, false, compress,
+ errp);
if (!state->bcs) {
error_prepend(errp, "Cannot create block-copy-state: ");
goto fail;