[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 21/64] block: Include filters when freezing backing chain
From: |
Kevin Wolf |
Subject: |
[PULL 21/64] block: Include filters when freezing backing chain |
Date: |
Mon, 7 Sep 2020 13:08:53 +0200 |
From: Max Reitz <mreitz@redhat.com>
In order to make filters work in backing chains, the associated
functions must be able to deal with them and freeze both COW and filter
child links.
While at it, add some comments that note which functions require their
caller to ensure that a given child link is not frozen, and how the
callers do so.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 60 +++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 39 insertions(+), 21 deletions(-)
diff --git a/block.c b/block.c
index e8d09d46ec..edef6273b8 100644
--- a/block.c
+++ b/block.c
@@ -2612,12 +2612,15 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
* If @new_bs is not NULL, bdrv_check_perm() must be called beforehand, as this
* function uses bdrv_set_perm() to update the permissions according to the new
* reference that @new_bs gets.
+ *
+ * Callers must ensure that child->frozen is false.
*/
static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
{
BlockDriverState *old_bs = child->bs;
uint64_t perm, shared_perm;
+ /* Asserts that child->frozen == false */
bdrv_replace_child_noperm(child, new_bs);
/*
@@ -2778,6 +2781,7 @@ static void bdrv_detach_child(BdrvChild *child)
g_free(child);
}
+/* Callers must ensure that child->frozen is false. */
void bdrv_root_unref_child(BdrvChild *child)
{
BlockDriverState *child_bs;
@@ -2815,6 +2819,7 @@ static void bdrv_unset_inherits_from(BlockDriverState
*root, BdrvChild *child)
}
}
+/* Callers must ensure that child->frozen is false. */
void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
{
if (child == NULL) {
@@ -2881,6 +2886,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs,
BlockDriverState *backing_hd,
}
if (bs->backing) {
+ /* Cannot be frozen, we checked that above */
bdrv_unref_child(bs, bs->backing);
bs->backing = NULL;
}
@@ -4387,6 +4393,7 @@ static void bdrv_close(BlockDriverState *bs)
if (bs->drv) {
if (bs->drv->bdrv_close) {
+ /* Must unfreeze all children, so bdrv_unref_child() works */
bs->drv->bdrv_close(bs);
}
bs->drv = NULL;
@@ -4762,20 +4769,22 @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs)
}
/*
- * Return true if at least one of the backing links between @bs and
- * @base is frozen. @errp is set if that's the case.
+ * Return true if at least one of the COW (backing) and filter links
+ * between @bs and @base is frozen. @errp is set if that's the case.
* @base must be reachable from @bs, or NULL.
*/
bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base,
Error **errp)
{
BlockDriverState *i;
+ BdrvChild *child;
- for (i = bs; i != base; i = backing_bs(i)) {
- if (i->backing && i->backing->frozen) {
+ for (i = bs; i != base; i = child_bs(child)) {
+ child = bdrv_filter_or_cow_child(i);
+
+ if (child && child->frozen) {
error_setg(errp, "Cannot change '%s' link from '%s' to '%s'",
- i->backing->name, i->node_name,
- backing_bs(i)->node_name);
+ child->name, i->node_name, child->bs->node_name);
return true;
}
}
@@ -4784,7 +4793,7 @@ bool bdrv_is_backing_chain_frozen(BlockDriverState *bs,
BlockDriverState *base,
}
/*
- * Freeze all backing links between @bs and @base.
+ * Freeze all COW (backing) and filter links between @bs and @base.
* If any of the links is already frozen the operation is aborted and
* none of the links are modified.
* @base must be reachable from @bs, or NULL.
@@ -4794,22 +4803,25 @@ int bdrv_freeze_backing_chain(BlockDriverState *bs,
BlockDriverState *base,
Error **errp)
{
BlockDriverState *i;
+ BdrvChild *child;
if (bdrv_is_backing_chain_frozen(bs, base, errp)) {
return -EPERM;
}
- for (i = bs; i != base; i = backing_bs(i)) {
- if (i->backing && backing_bs(i)->never_freeze) {
+ for (i = bs; i != base; i = child_bs(child)) {
+ child = bdrv_filter_or_cow_child(i);
+ if (child && child->bs->never_freeze) {
error_setg(errp, "Cannot freeze '%s' link to '%s'",
- i->backing->name, backing_bs(i)->node_name);
+ child->name, child->bs->node_name);
return -EPERM;
}
}
- for (i = bs; i != base; i = backing_bs(i)) {
- if (i->backing) {
- i->backing->frozen = true;
+ for (i = bs; i != base; i = child_bs(child)) {
+ child = bdrv_filter_or_cow_child(i);
+ if (child) {
+ child->frozen = true;
}
}
@@ -4817,18 +4829,21 @@ int bdrv_freeze_backing_chain(BlockDriverState *bs,
BlockDriverState *base,
}
/*
- * Unfreeze all backing links between @bs and @base. The caller must
- * ensure that all links are frozen before using this function.
+ * Unfreeze all COW (backing) and filter links between @bs and @base.
+ * The caller must ensure that all links are frozen before using this
+ * function.
* @base must be reachable from @bs, or NULL.
*/
void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base)
{
BlockDriverState *i;
+ BdrvChild *child;
- for (i = bs; i != base; i = backing_bs(i)) {
- if (i->backing) {
- assert(i->backing->frozen);
- i->backing->frozen = false;
+ for (i = bs; i != base; i = child_bs(child)) {
+ child = bdrv_filter_or_cow_child(i);
+ if (child) {
+ assert(child->frozen);
+ child->frozen = false;
}
}
}
@@ -4931,8 +4946,11 @@ int bdrv_drop_intermediate(BlockDriverState *top,
BlockDriverState *base,
}
}
- /* Do the actual switch in the in-memory graph.
- * Completes bdrv_check_update_perm() transaction internally. */
+ /*
+ * Do the actual switch in the in-memory graph.
+ * Completes bdrv_check_update_perm() transaction internally.
+ * c->frozen is false, we have checked that above.
+ */
bdrv_ref(base);
bdrv_replace_child(c, base);
bdrv_unref(top);
--
2.25.4
- [PULL 12/64] block/nvme: Simplify nvme_init_queue() arguments, (continued)
- [PULL 12/64] block/nvme: Simplify nvme_init_queue() arguments, Kevin Wolf, 2020/09/07
- [PULL 13/64] block/nvme: Replace BDRV_POLL_WHILE by AIO_WAIT_WHILE, Kevin Wolf, 2020/09/07
- [PULL 08/64] block/nvme: Rename local variable, Kevin Wolf, 2020/09/07
- [PULL 14/64] block/nvme: Simplify nvme_create_queue_pair() arguments, Kevin Wolf, 2020/09/07
- [PULL 15/64] block/nvme: Extract nvme_poll_queue(), Kevin Wolf, 2020/09/07
- [PULL 17/64] block: Add child access functions, Kevin Wolf, 2020/09/07
- [PULL 18/64] block: Add chain helper functions, Kevin Wolf, 2020/09/07
- [PULL 19/64] block: bdrv_cow_child() for bdrv_has_zero_init(), Kevin Wolf, 2020/09/07
- [PULL 16/64] block/nvme: Use an array of EventNotifier, Kevin Wolf, 2020/09/07
- [PULL 20/64] block: bdrv_set_backing_hd() is about bs->backing, Kevin Wolf, 2020/09/07
- [PULL 21/64] block: Include filters when freezing backing chain,
Kevin Wolf <=
- [PULL 23/64] block: Add bdrv_supports_compressed_writes(), Kevin Wolf, 2020/09/07
- [PULL 24/64] throttle: Support compressed writes, Kevin Wolf, 2020/09/07
- [PULL 26/64] block: Use bdrv_filter_(bs|child) where obvious, Kevin Wolf, 2020/09/07
- [PULL 22/64] block: Drop bdrv_is_encrypted(), Kevin Wolf, 2020/09/07
- [PULL 27/64] block: Use CAFs in block status functions, Kevin Wolf, 2020/09/07
- [PULL 25/64] copy-on-read: Support compressed writes, Kevin Wolf, 2020/09/07
- [PULL 28/64] stream: Deal with filters, Kevin Wolf, 2020/09/07
- [PULL 30/64] block: Use bdrv_cow_child() in bdrv_co_truncate(), Kevin Wolf, 2020/09/07
- [PULL 31/64] block: Re-evaluate backing file handling in reopen, Kevin Wolf, 2020/09/07
- [PULL 29/64] block: Use CAFs when working with backing chains, Kevin Wolf, 2020/09/07