|
@@ -1596,13 +1596,24 @@ static int bdrv_reopen_get_flags(BlockReopenQueue *q, BlockDriverState *bs)
|
|
|
|
|
|
/* Returns whether the image file can be written to after the reopen queue @q
|
|
|
* has been successfully applied, or right now if @q is NULL. */
|
|
|
-static bool bdrv_is_writable(BlockDriverState *bs, BlockReopenQueue *q)
|
|
|
+static bool bdrv_is_writable_after_reopen(BlockDriverState *bs,
|
|
|
+ BlockReopenQueue *q)
|
|
|
{
|
|
|
int flags = bdrv_reopen_get_flags(q, bs);
|
|
|
|
|
|
return (flags & (BDRV_O_RDWR | BDRV_O_INACTIVE)) == BDRV_O_RDWR;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Return whether the BDS can be written to. This is not necessarily
|
|
|
+ * the same as !bdrv_is_read_only(bs), as inactivated images may not
|
|
|
+ * be written to but do not count as read-only images.
|
|
|
+ */
|
|
|
+bool bdrv_is_writable(BlockDriverState *bs)
|
|
|
+{
|
|
|
+ return bdrv_is_writable_after_reopen(bs, NULL);
|
|
|
+}
|
|
|
+
|
|
|
static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
|
|
|
BdrvChild *c, const BdrvChildRole *role,
|
|
|
BlockReopenQueue *reopen_queue,
|
|
@@ -1640,7 +1651,7 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
|
|
|
|
|
|
/* Write permissions never work with read-only images */
|
|
|
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
|
|
|
- !bdrv_is_writable(bs, q))
|
|
|
+ !bdrv_is_writable_after_reopen(bs, q))
|
|
|
{
|
|
|
error_setg(errp, "Block node is read-only");
|
|
|
return -EPERM;
|
|
@@ -1930,7 +1941,7 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
|
|
|
&perm, &shared);
|
|
|
|
|
|
/* Format drivers may touch metadata even if the guest doesn't write */
|
|
|
- if (bdrv_is_writable(bs, reopen_queue)) {
|
|
|
+ if (bdrv_is_writable_after_reopen(bs, reopen_queue)) {
|
|
|
perm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
|
|
|
}
|
|
|
|