[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 1/2] commit: reopen overlay_bs before base
From: |
Alberto Garcia |
Subject: |
[Qemu-stable] [PATCH 1/2] commit: reopen overlay_bs before base |
Date: |
Wed, 28 Oct 2015 15:43:49 +0200 |
'block-commit' needs write access to two different nodes of the chain:
- 'base', because that's where the data is written to.
- the overlay of 'top', because it needs to update the backing file
string to point to 'base' after the operation.
Both images have to be opened in read-write mode, and commit_start()
takes care of reopening them if necessary.
With the current implementation, however, when overlay_bs is reopened
in read-write mode it has the side effect of making 'base' read-only
again, eventually making 'block-commit' fail.
This needs to be fixed in bdrv_reopen(), but until we get to that it
can be worked around simply by swapping the order of base and
overlay_bs in the reopen queue.
In order to reproduce this bug, overlay_bs needs to be initially in
read-only mode. That is: the 'top' parameter of 'block-commit' cannot
be the active layer nor its immediate backing chain.
Signed-off-by: Alberto Garcia <address@hidden>
---
block/commit.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/block/commit.c b/block/commit.c
index 7312a5b..85a2604 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -235,14 +235,14 @@ void commit_start(BlockDriverState *bs, BlockDriverState
*base,
orig_overlay_flags = bdrv_get_flags(overlay_bs);
/* convert base & overlay_bs to r/w, if necessary */
- if (!(orig_base_flags & BDRV_O_RDWR)) {
- reopen_queue = bdrv_reopen_queue(reopen_queue, base,
- orig_base_flags | BDRV_O_RDWR);
- }
if (!(orig_overlay_flags & BDRV_O_RDWR)) {
reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs,
orig_overlay_flags | BDRV_O_RDWR);
}
+ if (!(orig_base_flags & BDRV_O_RDWR)) {
+ reopen_queue = bdrv_reopen_queue(reopen_queue, base,
+ orig_base_flags | BDRV_O_RDWR);
+ }
if (reopen_queue) {
bdrv_reopen_multiple(reopen_queue, &local_err);
if (local_err != NULL) {
--
2.6.1