@@ -132,6 +132,8 @@ static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{
+ BDRVCopyBeforeWriteState *s = bs->opaque;
+
if (!(role & BDRV_CHILD_FILTERED)) {
/*
* Target child
@@ -142,7 +144,7 @@ static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c,
* only upfront.
*/
*nshared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
- *nperm = BLK_PERM_WRITE;
+ *nperm = s->fleecing ? BLK_PERM_WRITE_UNCHANGED : BLK_PERM_WRITE;
} else {
/* Source child */
bdrv_default_perms(bs, c, role, reopen_queue,
@@ -212,7 +214,14 @@ 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, bitmap, false, errp);
+ /*
+ * For fleecing scheme set parameter write_unchanged=true, as our
+ * copy-before-write operations will actually be write-unchanged. As well we
+ * take write-unchanged permission instead of write, which is important for
+ * backup with immutable_source=true to work as fleecing client.
+ */
+ s->bcs = block_copy_state_new(bs->file, s->target, bitmap,
+ is_fleecing_drv(unfiltered_target), errp);
if (!s->bcs) {
error_prepend(errp, "Cannot create block-copy-state: ");
return -EINVAL;
As announced in previous commit, we need use write-unchanged operations for fleecing, so that fleecing client may unshare writes if needed. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> --- block/copy-before-write.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)