block: refactor bdrv_node_check_perm()

Now, bdrv_node_check_perm() is called only with fresh cumulative
permissions, so its actually "refresh_perm".

Move permission calculation to the function. Also, drop unreachable
error message and rewrite the remaining one to be more generic (as now
we don't know which node is added and which was already here).

Add also Virtuozzo copyright, as big work is done at this point.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210428151804.439460-37-vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Vladimir Sementsov-Ogievskiy 2021-04-28 18:18:04 +03:00 committed by Kevin Wolf
parent 2fe5ff56f1
commit c20555e15f
2 changed files with 12 additions and 28 deletions

38
block.c
View File

@ -2,6 +2,7 @@
* QEMU System Emulator block driver
*
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2020 Virtuozzo International GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -2270,22 +2271,18 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs,
}
/*
* Check whether permissions on this node can be changed in a way that
* @cumulative_perms and @cumulative_shared_perms are the new cumulative
* permissions of all its parents. This involves checking whether all necessary
* permission changes to child nodes can be performed.
*
* A call to this function must always be followed by a call to bdrv_set_perm()
* or bdrv_abort_perm_update().
* Refresh permissions in @bs subtree. The function is intended to be called
* after some graph modification that was done without permission update.
*/
static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
uint64_t cumulative_perms,
uint64_t cumulative_shared_perms,
Transaction *tran, Error **errp)
static int bdrv_node_refresh_perm(BlockDriverState *bs, BlockReopenQueue *q,
Transaction *tran, Error **errp)
{
BlockDriver *drv = bs->drv;
BdrvChild *c;
int ret;
uint64_t cumulative_perms, cumulative_shared_perms;
bdrv_get_cumulative_perm(bs, &cumulative_perms, &cumulative_shared_perms);
/* Write permissions never work with read-only images */
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
@ -2294,15 +2291,8 @@ static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
if (!bdrv_is_writable_after_reopen(bs, NULL)) {
error_setg(errp, "Block node is read-only");
} else {
uint64_t current_perms, current_shared;
bdrv_get_cumulative_perm(bs, &current_perms, &current_shared);
if (current_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) {
error_setg(errp, "Cannot make block node read-only, there is "
"a writer on it");
} else {
error_setg(errp, "Cannot make block node read-only and create "
"a writer on it");
}
error_setg(errp, "Read-only block node '%s' cannot support "
"read-write users", bdrv_get_node_name(bs));
}
return -EPERM;
@ -2358,7 +2348,6 @@ static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
Transaction *tran, Error **errp)
{
int ret;
uint64_t cumulative_perms, cumulative_shared_perms;
BlockDriverState *bs;
for ( ; list; list = list->next) {
@ -2368,12 +2357,7 @@ static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
return -EINVAL;
}
bdrv_get_cumulative_perm(bs, &cumulative_perms,
&cumulative_shared_perms);
ret = bdrv_node_check_perm(bs, q, cumulative_perms,
cumulative_shared_perms,
tran, errp);
ret = bdrv_node_refresh_perm(bs, q, tran, errp);
if (ret < 0) {
return ret;
}

View File

@ -905,7 +905,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
# We can't reopen hd1 to read-only, as block-stream requires it to be
# read-write
self.reopen(opts['backing'], {'read-only': True},
"Cannot make block node read-only, there is a writer on it")
"Read-only block node 'hd1' cannot support read-write users")
# We can't remove hd2 while the stream job is ongoing
opts['backing']['backing'] = None