From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:40914) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R1ZbH-00058l-PM for qemu-devel@nongnu.org; Thu, 08 Sep 2011 04:04:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R1ZbG-00058c-Mk for qemu-devel@nongnu.org; Thu, 08 Sep 2011 04:04:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:25694) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R1ZbG-00058Q-Fd for qemu-devel@nongnu.org; Thu, 08 Sep 2011 04:04:42 -0400 Message-ID: <4E6877CA.3030309@redhat.com> Date: Thu, 08 Sep 2011 10:07:38 +0200 From: Kevin Wolf MIME-Version: 1.0 References: In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] Suspicious code in qcow2. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Frediano Ziglio Cc: qemu-devel Am 07.09.2011 18:42, schrieb Frediano Ziglio: > Actually it does not cause problems but this code order seems a bit > wrong to me (block/qcow2-cluster.c) > > > QLIST_INSERT_HEAD(&s->cluster_allocs, m, next_in_flight); > > /* allocate a new cluster */ > > cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size); > if (cluster_offset < 0) { > ret = cluster_offset; > goto fail; > } > > /* save info needed for meta data update */ > m->offset = offset; > m->n_start = n_start; > m->nb_clusters = nb_clusters; > > > current metadata (m) get inserted in cluster allocation list with > nb_clusters set to 0. Loop on cluster_allocs "ignore" (wait for this > allocation or just skip it depending on dirty data in offset field) > this metadata. Currently all occur in a CoMutex so this does not cause > problems but in case qcow2_alloc_clusters unlock the mutex it can > occur to insert two overlapping updates into cluster_allocs. Perhaps a > better order would be > > > /* save info needed for meta data update */ > m->offset = offset; > m->n_start = n_start; > m->nb_clusters = nb_clusters; > > QLIST_INSERT_HEAD(&s->cluster_allocs, m, next_in_flight); > > /* allocate a new cluster */ > > cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size); > if (cluster_offset < 0) { > ret = cluster_offset; > goto fail; > } > > > (tested successfully with iotests suite) Yes, that makes sense. Once we run this code without holding the CoMutex, this becomes a real problem. Care to send a patch? Kevin