OSDN Git Service

block: make bdrv_drop_intermediate() less wrong
authorVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Fri, 6 Nov 2020 12:42:37 +0000 (15:42 +0300)
committerMax Reitz <mreitz@redhat.com>
Mon, 9 Nov 2020 17:43:31 +0000 (18:43 +0100)
commitd669ed6ab028497d634e1f236c74a98725f9e45f
treeae6f938b7b431e6be13bd4aaa99c7d4db8e1b649
parent313274bbd4677f44631921ef4366f4ffc81cc5d5
block: make bdrv_drop_intermediate() less wrong

First, permission update loop tries to do iterations transactionally,
but the whole update is not transactional: nobody roll-back successful
loop iterations when some iteration fails.

Second, in the iteration we have nested permission update:
c->klass->update_filename may point to bdrv_child_cb_update_filename()
which calls bdrv_backing_update_filename(), which may do node reopen to
RW.

Permission update system is not prepared to nested updates, at least it
has intermediate permission-update state stored in BdrvChild
structures: has_backup_perm, backup_perm and backup_shared_perm.

So, let's first do bdrv_replace_node_common() (which is more
transactional than open-coded update in bdrv_drop_intermediate()) and
then call update_filename() in separate. We still do not rollback
changes in case of update_filename() failure but it's not much worse
than pre-patch behavior.

Note that bdrv_replace_node_common() does check for frozen children,
so corresponding check is dropped in bdrv_drop_intermediate().

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20201106124241.16950-4-vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
block.c