qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC PATCH 01/41] block: Attach bs->file only during .b


From: Max Reitz
Subject: Re: [Qemu-devel] [RFC PATCH 01/41] block: Attach bs->file only during .bdrv_open()
Date: Wed, 15 Feb 2017 15:34:07 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0

On 13.02.2017 18:22, Kevin Wolf wrote:
> The way that attaching bs->file worked was a bit unusual in that it was
> the only child that would be attached to a node which is not opened yet.
> Because of this, the block layer couldn't know yet which permissions the
> driver would eventually need.
> 
> This patch moves the point where bs->file is attached to the beginning
> of the individual .bdrv_open() implementations, so drivers already know
> what they are going to do with the child. This is also more consistent
> with how driver-specific children work.

Can't say I'm convinced by this because I personally do consider
bs->file to be special. It's fine and maybe even good if it's not like
driver-specific children (or even bs->backing).

But the fact that it doesn't work with a good op blocker model is more
than compelling.

> bdrv_open() still needs its own BdrvChild to perform image probing, but
> instead of directly assigning this BdrvChild to the BDS, it becomes a
> temporary one and the node name is passed as an option to the drivers,
> so that they can simply use bdrv_open_child() to create another
> reference for their own use.
> 
> Signed-off-by: Kevin Wolf <address@hidden>
> ---
>  block.c                       | 34 +++++++++++++++++++++++-----------
>  block/bochs.c                 |  6 ++++++
>  block/cloop.c                 |  6 ++++++
>  block/crypto.c                |  6 ++++++
>  block/dmg.c                   |  6 ++++++
>  block/parallels.c             |  6 ++++++
>  block/qcow.c                  |  6 ++++++
>  block/qcow2.c                 | 18 +++++++++++++++---
>  block/qed.c                   | 18 +++++++++++++++---
>  block/raw-format.c            |  6 ++++++
>  block/replication.c           |  6 ++++++
>  block/vdi.c                   |  6 ++++++
>  block/vhdx.c                  |  6 ++++++
>  block/vmdk.c                  |  6 ++++++
>  block/vpc.c                   |  6 ++++++
>  tests/qemu-iotests/051.out    |  4 ++--
>  tests/qemu-iotests/051.pc.out |  4 ++--
>  17 files changed, 129 insertions(+), 21 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 743c349..0618f4b 100644
> --- a/block.c
> +++ b/block.c
> @@ -1103,13 +1103,6 @@ static int bdrv_open_common(BlockDriverState *bs, 
> BdrvChild *file,
>          assert(!drv->bdrv_needs_filename || filename != NULL);
>          ret = drv->bdrv_file_open(bs, options, open_flags, &local_err);
>      } else {
> -        if (file == NULL) {
> -            error_setg(errp, "Can't use '%s' as a block driver for the "
> -                       "protocol level", drv->format_name);
> -            ret = -EINVAL;
> -            goto free_and_fail;
> -        }

Interesting. I like that this explicit check becomes unnecessary. I'm
not sure whether I like how the error messages changes, but I can't say
that I was a fan of this one to begin with.

> -        bs->file = file;
>          ret = drv->bdrv_open(bs, options, open_flags, &local_err);
>      }
>  
> @@ -1145,7 +1138,6 @@ static int bdrv_open_common(BlockDriverState *bs, 
> BdrvChild *file,
>      return 0;
>  
>  free_and_fail:
> -    bs->file = NULL;
>      g_free(bs->opaque);
>      bs->opaque = NULL;
>      bs->drv = NULL;
> @@ -1368,7 +1360,18 @@ void bdrv_unref_child(BlockDriverState *parent, 
> BdrvChild *child)
>      }
>  
>      if (child->bs->inherits_from == parent) {
> -        child->bs->inherits_from = NULL;
> +        BdrvChild *c;
> +
> +        /* Remove inherits_from only when the last reference between parent 
> and
> +         * child->bs goes away. */
> +        QLIST_FOREACH(c, &parent->children, next) {
> +            if (c != child && c->bs == child->bs) {
> +                break;
> +            }
> +        }

That's pretty kaputt. I'm not sure if I like it.

(But I like the reason for this even less, see below.)

> +        if (c == NULL) {
> +            child->bs->inherits_from = NULL;
> +        }
>      }
>  
>      bdrv_root_unref_child(child);
> @@ -1789,13 +1792,19 @@ static BlockDriverState *bdrv_open_inherit(const char 
> *filename,
>          qdict_del(options, "backing");
>      }
>  
> -    /* Open image file without format layer */
> +    /* Open image file without format layer. This BdrvChild is only used for
> +     * probing, the block drivers will do their own bdrv_open_child() for the
> +     * same BDS, which is why we put the node name back into options. */
>      if ((flags & BDRV_O_PROTOCOL) == 0) {
>          file = bdrv_open_child(filename, options, "file", bs,
>                                 &child_file, true, &local_err);
>          if (local_err) {
>              goto fail;
>          }
> +        if (file != NULL) {
> +            qdict_put(options, "file",
> +                      qstring_from_str(bdrv_get_node_name(file->bs)));
> +        }

Verrry interesting. I would say "Well, I guess it works" but I can't say
I'm glad with how it requires multiple BdrvChild pointing to the same
BDS attached to the same parent. Not only that, but both children have
the same BdrvChild.name which I don't like at all. In my opinion, that
name is supposed to be a unique ID and I don't find the fact that it's
just temporary a very good excuse. Neither do I find "Well, they have
the same ID and point to the same BDS, so it doesn't really matter" very
compelling. (Worsened by the fact that the block driver can just choose
to attach some other BDS as its file, then both "file" children no
longer point to the same BDS.)

Actually, I'd be happier if you just invoked bdrv_ref() and
bdrv_unref_child() (or just bdrv_detach_child(), I don't think NULLing
inherits_from is important here) right after bdrv_open_child().

We want @file for probing and probing only. It should be independent of
@bs now. The only reason I'm not proposing using bdrv_open_inherit()
directly is because using bdrv_open_child() saves us from having to
extract the file's options. But I don't see why @file should be
connected to @bs after this point (until the block driver potentially
decides to re-attach it as bs->file, but bdrv_open_child() will handle
all of that).

Max

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]