aboutsummaryrefslogtreecommitdiff
path: root/block.c
diff options
context:
space:
mode:
authorVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>2021-06-01 10:52:13 +0300
committerKevin Wolf <kwolf@redhat.com>2021-06-02 14:23:20 +0200
commitf8d2ad7881cde73508f9adeb28c7e033b0903ca8 (patch)
treed57e52f9baacd8529a43110e03f8c2ddda37e241 /block.c
parentfa95e9fbab2c19fc07ba82988b1690f8a6ff171b (diff)
block: document child argument of bdrv_attach_child_common()
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. So, let's add documentation and some assertions. While being here, drop extra declaration of bdrv_attach_child_noperm(). Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-Id: <20210601075218.79249-2-vsementsov@virtuozzo.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r--block.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/block.c b/block.c
index 84cb7212f7..c0fd363605 100644
--- a/block.c
+++ b/block.c
@@ -84,14 +84,6 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
static void bdrv_replace_child_noperm(BdrvChild *child,
BlockDriverState *new_bs);
-static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
- BlockDriverState *child_bs,
- const char *child_name,
- const BdrvChildClass *child_class,
- BdrvChildRole child_role,
- BdrvChild **child,
- Transaction *tran,
- Error **errp);
static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs,
Transaction *tran);
@@ -2759,6 +2751,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,
@@ -2833,6 +2831,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,
@@ -2915,7 +2917,6 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
child_role, perm, shared_perm, opaque,
&child, tran, errp);
if (ret < 0) {
- assert(child == NULL);
goto out;
}
@@ -2923,6 +2924,9 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
out:
tran_finalize(tran, ret);
+ /* child is unset on failure by bdrv_attach_child_common_abort() */
+ assert((ret < 0) == !child);
+
bdrv_unref(child_bs);
return child;
}
@@ -2962,6 +2966,8 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
out:
tran_finalize(tran, ret);
+ /* child is unset on failure by bdrv_attach_child_common_abort() */
+ assert((ret < 0) == !child);
bdrv_unref(child_bs);