|
|
902636 |
From 0ef6691ce8964bb2bbd677756c4e594793ca3ad8 Mon Sep 17 00:00:00 2001
|
|
|
902636 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
902636 |
Date: Fri, 7 Feb 2020 11:24:01 +0000
|
|
|
902636 |
Subject: [PATCH 04/18] block: Activate recursively even for already active
|
|
|
902636 |
nodes
|
|
|
902636 |
|
|
|
902636 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
902636 |
Message-id: <20200207112404.25198-4-kwolf@redhat.com>
|
|
|
902636 |
Patchwork-id: 93749
|
|
|
902636 |
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 3/6] block: Activate recursively even for already active nodes
|
|
|
902636 |
Bugzilla: 1781637
|
|
|
902636 |
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
|
|
|
902636 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
902636 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
902636 |
|
|
|
902636 |
bdrv_invalidate_cache_all() assumes that all nodes in a given subtree
|
|
|
902636 |
are either active or inactive when it starts. Therefore, as soon as it
|
|
|
902636 |
arrives at an already active node, it stops.
|
|
|
902636 |
|
|
|
902636 |
However, this assumption is wrong. For example, it's possible to take a
|
|
|
902636 |
snapshot of an inactive node, which results in an active overlay over an
|
|
|
902636 |
inactive backing file. The active overlay is probably also the root node
|
|
|
902636 |
of an inactive BlockBackend (blk->disable_perm == true).
|
|
|
902636 |
|
|
|
902636 |
In this case, bdrv_invalidate_cache_all() does not need to do anything
|
|
|
902636 |
to activate the overlay node, but it still needs to recurse into the
|
|
|
902636 |
children and the parents to make sure that after returning success,
|
|
|
902636 |
really everything is activated.
|
|
|
902636 |
|
|
|
902636 |
Cc: qemu-stable@nongnu.org
|
|
|
902636 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
902636 |
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
|
|
902636 |
(cherry picked from commit 7bb4941ace471fc7dd6ded4749b95b9622baa6ed)
|
|
|
902636 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
902636 |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
902636 |
---
|
|
|
902636 |
block.c | 50 ++++++++++++++++++++++++--------------------------
|
|
|
902636 |
1 file changed, 24 insertions(+), 26 deletions(-)
|
|
|
902636 |
|
|
|
902636 |
diff --git a/block.c b/block.c
|
|
|
902636 |
index 473eb6e..2e5e8b6 100644
|
|
|
902636 |
--- a/block.c
|
|
|
902636 |
+++ b/block.c
|
|
|
902636 |
@@ -5335,10 +5335,6 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
|
|
|
902636 |
return;
|
|
|
902636 |
}
|
|
|
902636 |
|
|
|
902636 |
- if (!(bs->open_flags & BDRV_O_INACTIVE)) {
|
|
|
902636 |
- return;
|
|
|
902636 |
- }
|
|
|
902636 |
-
|
|
|
902636 |
QLIST_FOREACH(child, &bs->children, next) {
|
|
|
902636 |
bdrv_co_invalidate_cache(child->bs, &local_err);
|
|
|
902636 |
if (local_err) {
|
|
|
902636 |
@@ -5360,34 +5356,36 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
|
|
|
902636 |
* just keep the extended permissions for the next time that an activation
|
|
|
902636 |
* of the image is tried.
|
|
|
902636 |
*/
|
|
|
902636 |
- bs->open_flags &= ~BDRV_O_INACTIVE;
|
|
|
902636 |
- bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
|
|
|
902636 |
- ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &local_err);
|
|
|
902636 |
- if (ret < 0) {
|
|
|
902636 |
- bs->open_flags |= BDRV_O_INACTIVE;
|
|
|
902636 |
- error_propagate(errp, local_err);
|
|
|
902636 |
- return;
|
|
|
902636 |
- }
|
|
|
902636 |
- bdrv_set_perm(bs, perm, shared_perm);
|
|
|
902636 |
-
|
|
|
902636 |
- if (bs->drv->bdrv_co_invalidate_cache) {
|
|
|
902636 |
- bs->drv->bdrv_co_invalidate_cache(bs, &local_err);
|
|
|
902636 |
- if (local_err) {
|
|
|
902636 |
+ if (bs->open_flags & BDRV_O_INACTIVE) {
|
|
|
902636 |
+ bs->open_flags &= ~BDRV_O_INACTIVE;
|
|
|
902636 |
+ bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
|
|
|
902636 |
+ ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &local_err);
|
|
|
902636 |
+ if (ret < 0) {
|
|
|
902636 |
bs->open_flags |= BDRV_O_INACTIVE;
|
|
|
902636 |
error_propagate(errp, local_err);
|
|
|
902636 |
return;
|
|
|
902636 |
}
|
|
|
902636 |
- }
|
|
|
902636 |
+ bdrv_set_perm(bs, perm, shared_perm);
|
|
|
902636 |
|
|
|
902636 |
- FOR_EACH_DIRTY_BITMAP(bs, bm) {
|
|
|
902636 |
- bdrv_dirty_bitmap_skip_store(bm, false);
|
|
|
902636 |
- }
|
|
|
902636 |
+ if (bs->drv->bdrv_co_invalidate_cache) {
|
|
|
902636 |
+ bs->drv->bdrv_co_invalidate_cache(bs, &local_err);
|
|
|
902636 |
+ if (local_err) {
|
|
|
902636 |
+ bs->open_flags |= BDRV_O_INACTIVE;
|
|
|
902636 |
+ error_propagate(errp, local_err);
|
|
|
902636 |
+ return;
|
|
|
902636 |
+ }
|
|
|
902636 |
+ }
|
|
|
902636 |
|
|
|
902636 |
- ret = refresh_total_sectors(bs, bs->total_sectors);
|
|
|
902636 |
- if (ret < 0) {
|
|
|
902636 |
- bs->open_flags |= BDRV_O_INACTIVE;
|
|
|
902636 |
- error_setg_errno(errp, -ret, "Could not refresh total sector count");
|
|
|
902636 |
- return;
|
|
|
902636 |
+ FOR_EACH_DIRTY_BITMAP(bs, bm) {
|
|
|
902636 |
+ bdrv_dirty_bitmap_skip_store(bm, false);
|
|
|
902636 |
+ }
|
|
|
902636 |
+
|
|
|
902636 |
+ ret = refresh_total_sectors(bs, bs->total_sectors);
|
|
|
902636 |
+ if (ret < 0) {
|
|
|
902636 |
+ bs->open_flags |= BDRV_O_INACTIVE;
|
|
|
902636 |
+ error_setg_errno(errp, -ret, "Could not refresh total sector count");
|
|
|
902636 |
+ return;
|
|
|
902636 |
+ }
|
|
|
902636 |
}
|
|
|
902636 |
|
|
|
902636 |
QLIST_FOREACH(parent, &bs->parents, next_parent) {
|
|
|
902636 |
--
|
|
|
902636 |
1.8.3.1
|
|
|
902636 |
|