• Kevin Wolf's avatar
    block: Don't inactivate children before parents · 9e37271f
    Kevin Wolf authored
    bdrv_child_cb_inactivate() asserts that parents are already inactive
    when children get inactivated. This precondition is necessary because
    parents could still issue requests in their inactivation code.
    When block nodes are created individually with -blockdev, all of them
    are monitor owned and will be returned by bdrv_next() in an undefined
    order (in practice, in the order of their creation, which is usually
    children before parents), which obviously fails the assertion:
    qemu: block.c:899: bdrv_child_cb_inactivate: Assertion `bs->open_flags & BDRV_O_INACTIVE' failed.
    This patch fixes the ordering by skipping nodes with still active
    parents in bdrv_inactivate_recurse() because we know that they will be
    covered by recursion when the last active parent becomes inactive.
    With the correct parents-before-children ordering, we also got rid of
    the reason why commit aad0b7a0 introduced two passes, so we can go
    back to a single-pass recursion. This is necessary so we can rely on the
    BDRV_O_INACTIVE flag to skip nodes with active parents (the flag used
    to be set only in pass 2, so we would always skip non-root nodes in
    pass 1 because all parents would still be considered active; setting the
    flag in pass 1 would mean, that we never skip anything in pass 2 because
    all parents are already considered inactive).
    Because of the change to single pass, this patch is best reviewed with
    whitespace changes ignored.
    Signed-off-by: 's avatarKevin Wolf <kwolf@redhat.com>
    Reviewed-by: 's avatarMax Reitz <mreitz@redhat.com>