qemu-devel
[Top][All Lists]
Advanced

[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



reply via email to

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