yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
76daa3
From e6ae3c4666f35c30ac171e9994b5116d9594c8ce Mon Sep 17 00:00:00 2001
76daa3
From: Kevin Wolf <kwolf@redhat.com>
76daa3
Date: Wed, 31 May 2017 10:55:21 +0200
76daa3
Subject: [PATCH 03/13] mirror: Drop permissions on s->target on completion
76daa3
76daa3
RH-Author: Kevin Wolf <kwolf@redhat.com>
76daa3
Message-id: <1496228121-28770-2-git-send-email-kwolf@redhat.com>
76daa3
Patchwork-id: 75443
76daa3
O-Subject: [RHEL-7.4 qemu-kvm-rhev PATCH] mirror: Drop permissions on s->target on completion
76daa3
Bugzilla: 1456456
76daa3
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
76daa3
RH-Acked-by: Fam Zheng <famz@redhat.com>
76daa3
RH-Acked-by: Max Reitz <mreitz@redhat.com>
76daa3
RH-Acked-by: John Snow <jsnow@redhat.com>
76daa3
76daa3
This fixes an assertion failure that was triggered by qemu-iotests 129
76daa3
on some CI host, while the same test case didn't seem to fail on other
76daa3
hosts.
76daa3
76daa3
Essentially the problem is that the blk_unref(s->target) in
76daa3
mirror_exit() doesn't necessarily mean that the BlockBackend goes away
76daa3
immediately. It is possible that the job completion was triggered nested
76daa3
in mirror_drain(), which looks like this:
76daa3
76daa3
    BlockBackend *target = s->target;
76daa3
    blk_ref(target);
76daa3
    blk_drain(target);
76daa3
    blk_unref(target);
76daa3
76daa3
In this case, the write permissions for s->target are retained until
76daa3
after blk_drain(), which makes removing mirror_top_bs fail for the
76daa3
active commit case (can't have a writable backing file in the chain
76daa3
without the filter driver).
76daa3
76daa3
Explicitly dropping the permissions first means that the additional
76daa3
reference doesn't hurt and the job can complete successfully even if
76daa3
called from the nested blk_drain().
76daa3
76daa3
Cc: qemu-stable@nongnu.org
76daa3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
76daa3
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
76daa3
Reviewed-by: Max Reitz <mreitz@redhat.com>
76daa3
(cherry picked from commit 63c8ef289087a225d445319d047501d4fe593687)
76daa3
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
---
76daa3
 block/mirror.c | 7 ++++++-
76daa3
 1 file changed, 6 insertions(+), 1 deletion(-)
76daa3
76daa3
diff --git a/block/mirror.c b/block/mirror.c
76daa3
index 2173a2f..4e8f124 100644
76daa3
--- a/block/mirror.c
76daa3
+++ b/block/mirror.c
76daa3
@@ -514,7 +514,12 @@ static void mirror_exit(BlockJob *job, void *opaque)
76daa3
 
76daa3
     /* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
76daa3
      * inserting target_bs at s->to_replace, where we might not be able to get
76daa3
-     * these permissions. */
76daa3
+     * these permissions.
76daa3
+     *
76daa3
+     * Note that blk_unref() alone doesn't necessarily drop permissions because
76daa3
+     * we might be running nested inside mirror_drain(), which takes an extra
76daa3
+     * reference, so use an explicit blk_set_perm() first. */
76daa3
+    blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort);
76daa3
     blk_unref(s->target);
76daa3
     s->target = NULL;
76daa3
 
76daa3
-- 
76daa3
1.8.3.1
76daa3