Blame SOURCES/kvm-block-Activate-recursively-even-for-already-active-n.patch

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