|
|
4a2fec |
From 35806318c04a6d8450ed745d1921a07915c3cc16 Mon Sep 17 00:00:00 2001
|
|
|
4a2fec |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
4a2fec |
Date: Mon, 4 Dec 2017 12:10:03 +0100
|
|
|
4a2fec |
Subject: [PATCH 32/36] block: Base permissions on rw state after reopen
|
|
|
4a2fec |
|
|
|
4a2fec |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
4a2fec |
Message-id: <20171204121007.12964-5-kwolf@redhat.com>
|
|
|
4a2fec |
Patchwork-id: 78109
|
|
|
4a2fec |
O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 4/8] block: Base permissions on rw state after reopen
|
|
|
4a2fec |
Bugzilla: 1492178
|
|
|
4a2fec |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
4a2fec |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
4a2fec |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
4a2fec |
|
|
|
4a2fec |
When new permissions are calculated during bdrv_reopen(), they need to
|
|
|
4a2fec |
be based on the state of the graph as it will be after the reopen has
|
|
|
4a2fec |
completed, not on the current state of the involved nodes.
|
|
|
4a2fec |
|
|
|
4a2fec |
This patch makes bdrv_is_writable() optionally accept a BlockReopenQueue
|
|
|
4a2fec |
from which the new flags are taken. This is then used for determining
|
|
|
4a2fec |
the new bs->file permissions of format drivers as soon as we add the
|
|
|
4a2fec |
code to actually pass a non-NULL reopen queue to the .bdrv_child_perm
|
|
|
4a2fec |
callbacks.
|
|
|
4a2fec |
|
|
|
4a2fec |
While moving bdrv_is_writable(), make it static. It isn't used outside
|
|
|
4a2fec |
block.c.
|
|
|
4a2fec |
|
|
|
4a2fec |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
4a2fec |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
4a2fec |
(cherry picked from commit 148eb13c84cccd0eedd6e59f90e0151bd7bac9fa)
|
|
|
4a2fec |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
4a2fec |
---
|
|
|
4a2fec |
block.c | 52 ++++++++++++++++++++++++++++++++++++---------------
|
|
|
4a2fec |
include/block/block.h | 1 -
|
|
|
4a2fec |
2 files changed, 37 insertions(+), 16 deletions(-)
|
|
|
4a2fec |
|
|
|
4a2fec |
diff --git a/block.c b/block.c
|
|
|
4a2fec |
index 5ce773a..5cce274 100644
|
|
|
4a2fec |
--- a/block.c
|
|
|
4a2fec |
+++ b/block.c
|
|
|
4a2fec |
@@ -240,12 +240,6 @@ bool bdrv_is_read_only(BlockDriverState *bs)
|
|
|
4a2fec |
return bs->read_only;
|
|
|
4a2fec |
}
|
|
|
4a2fec |
|
|
|
4a2fec |
-/* Returns whether the image file can be written to right now */
|
|
|
4a2fec |
-bool bdrv_is_writable(BlockDriverState *bs)
|
|
|
4a2fec |
-{
|
|
|
4a2fec |
- return !bdrv_is_read_only(bs) && !(bs->open_flags & BDRV_O_INACTIVE);
|
|
|
4a2fec |
-}
|
|
|
4a2fec |
-
|
|
|
4a2fec |
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
|
|
|
4a2fec |
bool ignore_allow_rdw, Error **errp)
|
|
|
4a2fec |
{
|
|
|
4a2fec |
@@ -1535,6 +1529,41 @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
|
|
|
4a2fec |
static void bdrv_child_abort_perm_update(BdrvChild *c);
|
|
|
4a2fec |
static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared);
|
|
|
4a2fec |
|
|
|
4a2fec |
+typedef struct BlockReopenQueueEntry {
|
|
|
4a2fec |
+ bool prepared;
|
|
|
4a2fec |
+ BDRVReopenState state;
|
|
|
4a2fec |
+ QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry;
|
|
|
4a2fec |
+} BlockReopenQueueEntry;
|
|
|
4a2fec |
+
|
|
|
4a2fec |
+/*
|
|
|
4a2fec |
+ * Return the flags that @bs will have after the reopens in @q have
|
|
|
4a2fec |
+ * successfully completed. If @q is NULL (or @bs is not contained in @q),
|
|
|
4a2fec |
+ * return the current flags.
|
|
|
4a2fec |
+ */
|
|
|
4a2fec |
+static int bdrv_reopen_get_flags(BlockReopenQueue *q, BlockDriverState *bs)
|
|
|
4a2fec |
+{
|
|
|
4a2fec |
+ BlockReopenQueueEntry *entry;
|
|
|
4a2fec |
+
|
|
|
4a2fec |
+ if (q != NULL) {
|
|
|
4a2fec |
+ QSIMPLEQ_FOREACH(entry, q, entry) {
|
|
|
4a2fec |
+ if (entry->state.bs == bs) {
|
|
|
4a2fec |
+ return entry->state.flags;
|
|
|
4a2fec |
+ }
|
|
|
4a2fec |
+ }
|
|
|
4a2fec |
+ }
|
|
|
4a2fec |
+
|
|
|
4a2fec |
+ return bs->open_flags;
|
|
|
4a2fec |
+}
|
|
|
4a2fec |
+
|
|
|
4a2fec |
+/* Returns whether the image file can be written to after the reopen queue @q
|
|
|
4a2fec |
+ * has been successfully applied, or right now if @q is NULL. */
|
|
|
4a2fec |
+static bool bdrv_is_writable(BlockDriverState *bs, BlockReopenQueue *q)
|
|
|
4a2fec |
+{
|
|
|
4a2fec |
+ int flags = bdrv_reopen_get_flags(q, bs);
|
|
|
4a2fec |
+
|
|
|
4a2fec |
+ return (flags & (BDRV_O_RDWR | BDRV_O_INACTIVE)) == BDRV_O_RDWR;
|
|
|
4a2fec |
+}
|
|
|
4a2fec |
+
|
|
|
4a2fec |
static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
|
|
|
4a2fec |
BdrvChild *c, const BdrvChildRole *role,
|
|
|
4a2fec |
BlockReopenQueue *reopen_queue,
|
|
|
4a2fec |
@@ -1572,7 +1601,7 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
|
|
|
4a2fec |
|
|
|
4a2fec |
/* Write permissions never work with read-only images */
|
|
|
4a2fec |
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
|
|
|
4a2fec |
- !bdrv_is_writable(bs))
|
|
|
4a2fec |
+ !bdrv_is_writable(bs, q))
|
|
|
4a2fec |
{
|
|
|
4a2fec |
error_setg(errp, "Block node is read-only");
|
|
|
4a2fec |
return -EPERM;
|
|
|
4a2fec |
@@ -1862,8 +1891,7 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
|
|
|
4a2fec |
&perm, &shared);
|
|
|
4a2fec |
|
|
|
4a2fec |
/* Format drivers may touch metadata even if the guest doesn't write */
|
|
|
4a2fec |
- /* TODO Take flags from reopen_queue */
|
|
|
4a2fec |
- if (bdrv_is_writable(bs)) {
|
|
|
4a2fec |
+ if (bdrv_is_writable(bs, reopen_queue)) {
|
|
|
4a2fec |
perm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
|
|
|
4a2fec |
}
|
|
|
4a2fec |
|
|
|
4a2fec |
@@ -2641,12 +2669,6 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
|
|
|
4a2fec |
NULL, errp);
|
|
|
4a2fec |
}
|
|
|
4a2fec |
|
|
|
4a2fec |
-typedef struct BlockReopenQueueEntry {
|
|
|
4a2fec |
- bool prepared;
|
|
|
4a2fec |
- BDRVReopenState state;
|
|
|
4a2fec |
- QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry;
|
|
|
4a2fec |
-} BlockReopenQueueEntry;
|
|
|
4a2fec |
-
|
|
|
4a2fec |
/*
|
|
|
4a2fec |
* Adds a BlockDriverState to a simple queue for an atomic, transactional
|
|
|
4a2fec |
* reopen of multiple devices.
|
|
|
4a2fec |
diff --git a/include/block/block.h b/include/block/block.h
|
|
|
4a2fec |
index ab80195..4d0d2da 100644
|
|
|
4a2fec |
--- a/include/block/block.h
|
|
|
4a2fec |
+++ b/include/block/block.h
|
|
|
4a2fec |
@@ -435,7 +435,6 @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
|
|
|
4a2fec |
int64_t offset, int64_t bytes, int64_t *pnum);
|
|
|
4a2fec |
|
|
|
4a2fec |
bool bdrv_is_read_only(BlockDriverState *bs);
|
|
|
4a2fec |
-bool bdrv_is_writable(BlockDriverState *bs);
|
|
|
4a2fec |
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
|
|
|
4a2fec |
bool ignore_allow_rdw, Error **errp);
|
|
|
4a2fec |
int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
|
|
|
4a2fec |
--
|
|
|
4a2fec |
1.8.3.1
|
|
|
4a2fec |
|