Am 27.11.2020 um 15:45 hat Vladimir Sementsov-Ogievskiy geschrieben: > Split out no-perm part of bdrv_set_backing_hd() as a separate > transaction action. Note the in case of existing BdrvChild we reuse it, > not recreate, just to do less actions. > > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com>
> /* > * Sets the bs->backing link of a BDS. A new reference is created; callers > * which don't need their own reference any more must call bdrv_unref(). > */ > -void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, > - Error **errp) > +static int bdrv_set_backing_noperm(BlockDriverState *bs, > + BlockDriverState *backing_bs, > + GSList **tran, Error **errp) > { > - bool update_inherits_from = bdrv_chain_contains(bs, backing_hd) && > - bdrv_inherits_from_recursive(backing_hd, bs); > + int ret = 0; > + bool update_inherits_from = bdrv_chain_contains(bs, backing_bs) && > + bdrv_inherits_from_recursive(backing_bs, bs); > + GSList *attach_tran = NULL; > + BdrvSetBackingNoPermState *s; > > if (bdrv_is_backing_chain_frozen(bs, child_bs(bs->backing), errp)) { > - return; > + return -EPERM; > } > > - if (backing_hd) { > - bdrv_ref(backing_hd); > + if (bs->backing && backing_bs) { > + bdrv_replace_child_safe(bs->backing, backing_bs, tran); The old code with separate bdrv_unref_child() and then bdrv_attach_child() tried to make the AioContests of bs and backing_bs compatible by moving one of the nodes if necessary. bdrv_replace_child_safe() doesn't seem to do that, but it only asserts that both nodes are already in the same context. I see that iotest 245 doesn't crash, which I think it should if this were broken, but where does the switch happen now? Kevin