[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 2/2] block: Avoid second open for format probing
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [PATCH 2/2] block: Avoid second open for format probing |
Date: |
Wed, 14 Nov 2012 09:51:51 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121016 Thunderbird/16.0.1 |
Il 14/11/2012 09:32, Stefan Hajnoczi ha scritto:
> On Tue, Nov 13, 2012 at 03:14:55PM +0100, Kevin Wolf wrote:
>> @@ -691,12 +685,15 @@ static int bdrv_open_common(BlockDriverState *bs,
>> const char *filename,
>>
>> /* Open the image, either directly or using a protocol */
>> if (drv->bdrv_file_open) {
>> + if (file != NULL) {
>> + bdrv_swap(file, bs);
>> + bdrv_delete(file);
>> + }
>> ret = drv->bdrv_file_open(bs, filename, open_flags);
>> } else {
> [...]
>> /* Open the image */
>> - ret = bdrv_open_common(bs, filename, flags, drv);
>> + ret = bdrv_open_common(bs, file, filename, flags, drv);
>> if (ret < 0) {
>> goto unlink_and_fail;
>> }
>> @@ -894,6 +895,9 @@ int bdrv_open(BlockDriverState *bs, const char
>> *filename, int flags,
>> return 0;
>>
>> unlink_and_fail:
>> + if (file != NULL) {
>> + bdrv_delete(file);
>> + }
>
> Not sure I understand this code path.
>
> We have a protocol (the driver implements .bdrv_file_open()) so we swap
> file and bs, then delete old bs. Then we call .bdrv_file_open() on the
> already open file BDS.
>
> Is it okay to call .bdrv_file_open() on an already open BDS?
I don't think so. But do the cases where this happen make sense? Can
we just fail if drv is not equal to bs->drv if we reach the "if
(drv->bdrv_file_open)" case? That would be for cases like "-drive
file=test.img,format=host_device" but how does that make sense?...
(Plus, it fails to stack the raw format on top).
So perhaps we could even assert(drv == bs->drv) if protocols had no
.format_name?
> Now if .bdrv_file_open() fails we will bdrv_delete() the already deleted
> file BDS. This is a double-free.
Right, always better to NULL out whatever you delete (which means
passing a BDS** to bdrv_open_common.
Paolo