block: Generalize should_update_child() rule
commitec9f10fe064f2abb9dc60a9fa580d8d0933f2acf
authorMax Reitz <mreitz@redhat.com>
Wed, 13 Jun 2018 18:18:15 +0000 (13 20:18 +0200)
committerMax Reitz <mreitz@redhat.com>
Mon, 18 Jun 2018 15:04:54 +0000 (18 17:04 +0200)
tree6aed9e6a2a2ff0996fab2ab76feb7685a3e4d2b4
parent138f9fffb809451ef80f5be4647558b72f2339ad
block: Generalize should_update_child() rule

Currently, bdrv_replace_node() refuses to create loops from one BDS to
itself if the BDS to be replaced is the backing node of the BDS to
replace it: Say there is a node A and a node B.  Replacing B by A means
making all references to B point to A.  If B is a child of A (i.e. A has
a reference to B), that would mean we would have to make this reference
point to A itself -- so we'd create a loop.

bdrv_replace_node() (through should_update_child()) refuses to do so if
B is the backing node of A.  There is no reason why we should create
loops if B is not the backing node of A, though.  The BDS graph should
never contain loops, so we should always refuse to create them.

If B is a child of A and B is to be replaced by A, we should simply
leave B in place there because it is the most sensible choice.

A more specific argument would be: Putting filter drivers into the BDS
graph is basically the same as appending an overlay to a backing chain.
But the main child BDS of a filter driver is not "backing" but "file",
so restricting the no-loop rule to backing nodes would fail here.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 20180613181823.13618-7-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
block.c