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