Skip to content

Commit

Permalink
Revert "block: Let replace_child_tran keep indirect pointer"
Browse files Browse the repository at this point in the history
That's a preparation to previously reverted
"block: Let replace_child_noperm free children". Drop it too, we don't
need it for a new approach.

This reverts commit 82b54cf.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220726201134.924743-11-vsementsov@yandex-team.ru>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
Vladimir Sementsov-Ogievskiy authored and kevmw committed Oct 27, 2022
1 parent 4eba825 commit 0f0b1e2
Showing 1 changed file with 10 additions and 71 deletions.
81 changes: 10 additions & 71 deletions block.c
Expand Up @@ -2341,7 +2341,6 @@ static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm,

typedef struct BdrvReplaceChildState {
BdrvChild *child;
BdrvChild **childp;
BlockDriverState *old_bs;
} BdrvReplaceChildState;

Expand All @@ -2359,29 +2358,7 @@ static void bdrv_replace_child_abort(void *opaque)
BlockDriverState *new_bs = s->child->bs;

GLOBAL_STATE_CODE();
/*
* old_bs reference is transparently moved from @s to s->child.
*
* Pass &s->child here instead of s->childp, because:
* (1) s->old_bs must be non-NULL, so bdrv_replace_child_noperm() will not
* modify the BdrvChild * pointer we indirectly pass to it, i.e. it
* will not modify s->child. From that perspective, it does not matter
* whether we pass s->childp or &s->child.
* (TODO: Right now, bdrv_replace_child_noperm() never modifies that
* pointer anyway (though it will in the future), so at this point it
* absolutely does not matter whether we pass s->childp or &s->child.)
* (2) If new_bs is not NULL, s->childp will be NULL. We then cannot use
* it here.
* (3) If new_bs is NULL, *s->childp will have been NULLed by
* bdrv_replace_child_tran()'s bdrv_replace_child_noperm() call, and we
* must not pass a NULL *s->childp here.
* (TODO: In its current state, bdrv_replace_child_noperm() will not
* have NULLed *s->childp, so this does not apply yet. It will in the
* future.)
*
* So whether new_bs was NULL or not, we cannot pass s->childp here; and in
* any case, there is no reason to pass it anyway.
*/
/* old_bs reference is transparently moved from @s to @s->child */
bdrv_replace_child_noperm(&s->child, s->old_bs);
bdrv_unref(new_bs);
}
Expand All @@ -2398,32 +2375,22 @@ static TransactionActionDrv bdrv_replace_child_drv = {
* Note: real unref of old_bs is done only on commit.
*
* The function doesn't update permissions, caller is responsible for this.
*
* Note that if new_bs == NULL, @childp is stored in a state object attached
* to @tran, so that the old child can be reinstated in the abort handler.
* Therefore, if @new_bs can be NULL, @childp must stay valid until the
* transaction is committed or aborted.
*
* (TODO: The reinstating does not happen yet, but it will once
* bdrv_replace_child_noperm() NULLs *childp when new_bs is NULL.)
*/
static void bdrv_replace_child_tran(BdrvChild **childp,
BlockDriverState *new_bs,
static void bdrv_replace_child_tran(BdrvChild *child, BlockDriverState *new_bs,
Transaction *tran)
{
BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1);
*s = (BdrvReplaceChildState) {
.child = *childp,
.childp = new_bs == NULL ? childp : NULL,
.old_bs = (*childp)->bs,
.child = child,
.old_bs = child->bs,
};
tran_add(tran, &bdrv_replace_child_drv, s);

if (new_bs) {
bdrv_ref(new_bs);
}
bdrv_replace_child_noperm(childp, new_bs);
/* old_bs reference is transparently moved from *childp to @s */
bdrv_replace_child_noperm(&child, new_bs);
/* old_bs reference is transparently moved from @child to @s */
}

/*
Expand Down Expand Up @@ -5045,7 +5012,6 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)

typedef struct BdrvRemoveFilterOrCowChild {
BdrvChild *child;
BlockDriverState *bs;
bool is_backing;
} BdrvRemoveFilterOrCowChild;

Expand Down Expand Up @@ -5075,19 +5041,10 @@ static void bdrv_remove_filter_or_cow_child_commit(void *opaque)
bdrv_child_free(s->child);
}

static void bdrv_remove_filter_or_cow_child_clean(void *opaque)
{
BdrvRemoveFilterOrCowChild *s = opaque;

/* Drop the bs reference after the transaction is done */
bdrv_unref(s->bs);
g_free(s);
}

static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = {
.abort = bdrv_remove_filter_or_cow_child_abort,
.commit = bdrv_remove_filter_or_cow_child_commit,
.clean = bdrv_remove_filter_or_cow_child_clean,
.clean = g_free,
};

/*
Expand All @@ -5105,11 +5062,6 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
return;
}

/*
* Keep a reference to @bs so @childp will stay valid throughout the
* transaction (required by bdrv_replace_child_tran())
*/
bdrv_ref(bs);
if (child == bs->backing) {
childp = &bs->backing;
} else if (child == bs->file) {
Expand All @@ -5119,13 +5071,12 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
}

if (child->bs) {
bdrv_replace_child_tran(childp, NULL, tran);
bdrv_replace_child_tran(*childp, NULL, tran);
}

s = g_new(BdrvRemoveFilterOrCowChild, 1);
*s = (BdrvRemoveFilterOrCowChild) {
.child = child,
.bs = bs,
.is_backing = (childp == &bs->backing),
};
tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
Expand All @@ -5151,7 +5102,6 @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
{
BdrvChild *c, *next;

assert(to != NULL);
GLOBAL_STATE_CODE();

QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
Expand All @@ -5169,12 +5119,7 @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
c->name, from->node_name);
return -EPERM;
}

/*
* Passing a pointer to the local variable @c is fine here, because
* @to is not NULL, and so &c will not be attached to the transaction.
*/
bdrv_replace_child_tran(&c, to, tran);
bdrv_replace_child_tran(c, to, tran);
}

return 0;
Expand All @@ -5189,8 +5134,6 @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
*
* With @detach_subchain=true @to must be in a backing chain of @from. In this
* case backing link of the cow-parent of @to is removed.
*
* @to must not be NULL.
*/
static int bdrv_replace_node_common(BlockDriverState *from,
BlockDriverState *to,
Expand All @@ -5204,7 +5147,6 @@ static int bdrv_replace_node_common(BlockDriverState *from,
int ret;

GLOBAL_STATE_CODE();
assert(to != NULL);

if (detach_subchain) {
assert(bdrv_chain_contains(from, to));
Expand Down Expand Up @@ -5261,9 +5203,6 @@ static int bdrv_replace_node_common(BlockDriverState *from,
return ret;
}

/**
* Replace node @from by @to (where neither may be NULL).
*/
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
Error **errp)
{
Expand Down Expand Up @@ -5339,7 +5278,7 @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
bdrv_drained_begin(old_bs);
bdrv_drained_begin(new_bs);

bdrv_replace_child_tran(&child, new_bs, tran);
bdrv_replace_child_tran(child, new_bs, tran);

found = g_hash_table_new(NULL, NULL);
refresh_list = bdrv_topological_dfs(refresh_list, found, old_bs);
Expand Down

0 comments on commit 0f0b1e2

Please sign in to comment.