From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:43137) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TYYhg-0003B5-Gy for qemu-devel@nongnu.org; Wed, 14 Nov 2012 03:52:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TYYhd-0007yC-EU for qemu-devel@nongnu.org; Wed, 14 Nov 2012 03:52:12 -0500 Received: from mail-ee0-f45.google.com ([74.125.83.45]:54718) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TYYhd-0007y3-7P for qemu-devel@nongnu.org; Wed, 14 Nov 2012 03:52:09 -0500 Received: by mail-ee0-f45.google.com with SMTP id d49so111313eek.4 for ; Wed, 14 Nov 2012 00:52:07 -0800 (PST) Sender: Paolo Bonzini Message-ID: <50A35BA7.7090900@redhat.com> Date: Wed, 14 Nov 2012 09:51:51 +0100 From: Paolo Bonzini MIME-Version: 1.0 References: <1352816095-14051-1-git-send-email-kwolf@redhat.com> <1352816095-14051-3-git-send-email-kwolf@redhat.com> <20121114083201.GA23826@stefanha-thinkpad.redhat.com> In-Reply-To: <20121114083201.GA23826@stefanha-thinkpad.redhat.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 2/2] block: Avoid second open for format probing List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Stefan Hajnoczi Cc: Kevin Wolf , qemu-devel@nongnu.org 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