|
@@ -44,6 +44,7 @@ typedef struct BDRVCopyBeforeWriteState {
|
|
|
BdrvChild *target;
|
|
|
OnCbwError on_cbw_error;
|
|
|
uint32_t cbw_timeout_ns;
|
|
|
+ bool discard_source;
|
|
|
|
|
|
/*
|
|
|
* @lock: protects access to @access_bitmap, @done_bitmap and
|
|
@@ -357,6 +358,8 @@ cbw_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role,
|
|
|
uint64_t perm, uint64_t shared,
|
|
|
uint64_t *nperm, uint64_t *nshared)
|
|
|
{
|
|
|
+ BDRVCopyBeforeWriteState *s = bs->opaque;
|
|
|
+
|
|
|
if (!(role & BDRV_CHILD_FILTERED)) {
|
|
|
/*
|
|
|
* Target child
|
|
@@ -381,6 +384,10 @@ cbw_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role,
|
|
|
* start
|
|
|
*/
|
|
|
*nperm = *nperm | BLK_PERM_CONSISTENT_READ;
|
|
|
+ if (s->discard_source) {
|
|
|
+ *nperm = *nperm | BLK_PERM_WRITE;
|
|
|
+ }
|
|
|
+
|
|
|
*nshared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
|
|
|
}
|
|
|
}
|
|
@@ -468,7 +475,9 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
|
|
|
bs->file->bs->supported_zero_flags);
|
|
|
|
|
|
- s->bcs = block_copy_state_new(bs->file, s->target, bs, bitmap, errp);
|
|
|
+ s->discard_source = flags & BDRV_O_CBW_DISCARD_SOURCE;
|
|
|
+ s->bcs = block_copy_state_new(bs->file, s->target, bs, bitmap,
|
|
|
+ flags & BDRV_O_CBW_DISCARD_SOURCE, errp);
|
|
|
if (!s->bcs) {
|
|
|
error_prepend(errp, "Cannot create block-copy-state: ");
|
|
|
return -EINVAL;
|
|
@@ -535,12 +544,14 @@ static BlockDriver bdrv_cbw_filter = {
|
|
|
BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
|
|
|
BlockDriverState *target,
|
|
|
const char *filter_node_name,
|
|
|
+ bool discard_source,
|
|
|
BlockCopyState **bcs,
|
|
|
Error **errp)
|
|
|
{
|
|
|
BDRVCopyBeforeWriteState *state;
|
|
|
BlockDriverState *top;
|
|
|
QDict *opts;
|
|
|
+ int flags = BDRV_O_RDWR | (discard_source ? BDRV_O_CBW_DISCARD_SOURCE : 0);
|
|
|
|
|
|
assert(source->total_sectors == target->total_sectors);
|
|
|
GLOBAL_STATE_CODE();
|
|
@@ -553,7 +564,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
|
|
|
qdict_put_str(opts, "file", bdrv_get_node_name(source));
|
|
|
qdict_put_str(opts, "target", bdrv_get_node_name(target));
|
|
|
|
|
|
- top = bdrv_insert_node(source, opts, BDRV_O_RDWR, errp);
|
|
|
+ top = bdrv_insert_node(source, opts, flags, errp);
|
|
|
if (!top) {
|
|
|
return NULL;
|
|
|
}
|