The logic around **child is not obvious: this reference is used not only to return resulting child, but also to rollback NULL value on transaction abort. Let's document this.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- block.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/block.c b/block.c index 3fc87fbf90..1f89be6f97 100644 --- a/block.c +++ b/block.c @@ -2773,6 +2773,12 @@ static TransactionActionDrv bdrv_attach_child_common_drv = { /* * Common part of attaching bdrv child to bs or to blk or to job + * + * Resulting new child is returned through @child. + * At start *@child must be NULL. + * @child is saved to a new entry of @tran, so that *@child could be reverted to + * NULL on abort(). So referenced variable must live at least until transaction + * end. */ static int bdrv_attach_child_common(BlockDriverState *child_bs, const char *child_name, @@ -2847,6 +2853,10 @@ static int bdrv_attach_child_common(BlockDriverState *child_bs, return 0; } +/* + * Variable referenced by @child must live at least until transaction end. + * (see bdrv_attach_child_common() doc for details) + */ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs, BlockDriverState *child_bs, const char *child_name, -- 2.29.2