summaryrefslogtreecommitdiffstats
path: root/block.c
diff options
context:
space:
mode:
authorPeter Maydell2017-08-08 16:23:21 +0200
committerPeter Maydell2017-08-08 16:23:21 +0200
commit53b080fa83c35d22cc94c730346fb2c53138d786 (patch)
tree48064249926a702c1d7181e1406957573215acb7 /block.c
parentMerge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (diff)
parentblock/nfs: fix mutex assertion in nfs_file_close() (diff)
downloadqemu-53b080fa83c35d22cc94c730346fb2c53138d786.tar.gz
qemu-53b080fa83c35d22cc94c730346fb2c53138d786.tar.xz
qemu-53b080fa83c35d22cc94c730346fb2c53138d786.zip
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches for 2.10.0-rc2 # gpg: Signature made Tue 08 Aug 2017 14:56:15 BST # gpg: using RSA key 0x7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: block/nfs: fix mutex assertion in nfs_file_close() qemu-iotests: Test reopen between read-only and read-write qemu-io: Allow reopen read-write block: Set BDRV_O_ALLOW_RDWR during rw reopen block: Allow reopen rw without BDRV_O_ALLOW_RDWR block: Fix order in bdrv_replace_child() parallels: drop check that bdrv_truncate() is working parallels: respect error code of bdrv_getlength() in allocate_clusters() block: respect error code from bdrv_getlength in handle_aiocb_write_zeroes vmdk: Fix error handling/reporting of vmdk_check block/null: Remove 'filename' option block: drop bdrv_set_key from BlockDriver block/vhdx: check error return of bdrv_truncate() block/vhdx: check error return of bdrv_flush() block/vhdx: check for offset overflow to bdrv_truncate() block/vhdx: check error return of bdrv_getlength() quorum: Set sectors-count to 0 when reporting a flush error qemu-iotests/109: Fix lock race condition Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block.c')
-rw-r--r--block.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/block.c b/block.c
index ce9cce7b3c..3615a6809e 100644
--- a/block.c
+++ b/block.c
@@ -246,7 +246,8 @@ bool bdrv_is_writable(BlockDriverState *bs)
return !bdrv_is_read_only(bs) && !(bs->open_flags & BDRV_O_INACTIVE);
}
-int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
+int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
+ bool ignore_allow_rdw, Error **errp)
{
/* Do not set read_only if copy_on_read is enabled */
if (bs->copy_on_read && read_only) {
@@ -256,7 +257,9 @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
}
/* Do not clear read_only if it is prohibited */
- if (!read_only && !(bs->open_flags & BDRV_O_ALLOW_RDWR)) {
+ if (!read_only && !(bs->open_flags & BDRV_O_ALLOW_RDWR) &&
+ !ignore_allow_rdw)
+ {
error_setg(errp, "Node '%s' is read only",
bdrv_get_device_or_node_name(bs));
return -EPERM;
@@ -269,7 +272,7 @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
{
int ret = 0;
- ret = bdrv_can_set_read_only(bs, read_only, errp);
+ ret = bdrv_can_set_read_only(bs, read_only, false, errp);
if (ret < 0) {
return ret;
}
@@ -1933,6 +1936,8 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
BlockDriverState *old_bs = child->bs;
uint64_t perm, shared_perm;
+ bdrv_replace_child_noperm(child, new_bs);
+
if (old_bs) {
/* Update permissions for old node. This is guaranteed to succeed
* because we're just taking a parent away, so we're loosening
@@ -1942,8 +1947,6 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
bdrv_set_perm(old_bs, perm, shared_perm);
}
- bdrv_replace_child_noperm(child, new_bs);
-
if (new_bs) {
bdrv_get_cumulative_perm(new_bs, &perm, &shared_perm);
bdrv_set_perm(new_bs, perm, shared_perm);
@@ -2726,8 +2729,11 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
bdrv_join_options(bs, options, old_options);
QDECREF(old_options);
- /* bdrv_open() masks this flag out */
+ /* bdrv_open_inherit() sets and clears some additional flags internally */
flags &= ~BDRV_O_PROTOCOL;
+ if (flags & BDRV_O_RDWR) {
+ flags |= BDRV_O_ALLOW_RDWR;
+ }
QLIST_FOREACH(child, &bs->children, next) {
QDict *new_child_options;
@@ -2907,7 +2913,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
* to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is
* not set, or if the BDS still has copy_on_read enabled */
read_only = !(reopen_state->flags & BDRV_O_RDWR);
- ret = bdrv_can_set_read_only(reopen_state->bs, read_only, &local_err);
+ ret = bdrv_can_set_read_only(reopen_state->bs, read_only, true, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto error;