From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L4iex-0002sD-GP for qemu-devel@nongnu.org; Mon, 24 Nov 2008 16:07:55 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L4iew-0002qs-ML for qemu-devel@nongnu.org; Mon, 24 Nov 2008 16:07:55 -0500 Received: from [199.232.76.173] (port=41839 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L4iew-0002qa-Gv for qemu-devel@nongnu.org; Mon, 24 Nov 2008 16:07:54 -0500 Received: from mx2.redhat.com ([66.187.237.31]:48003) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1L4iev-0001cH-UK for qemu-devel@nongnu.org; Mon, 24 Nov 2008 16:07:54 -0500 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id mAOL7r6f018758 for ; Mon, 24 Nov 2008 16:07:53 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id mAOL7qC3014232 for ; Mon, 24 Nov 2008 16:07:52 -0500 Received: from dhcp-1-237.tlv.redhat.com (dhcp-1-237.tlv.redhat.com [10.35.1.237]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id mAOL7pGO010914 for ; Mon, 24 Nov 2008 16:07:52 -0500 Received: from dhcp-1-237.tlv.redhat.com (localhost [127.0.0.1]) by dhcp-1-237.tlv.redhat.com (Postfix) with ESMTP id BD64D18D48C for ; Mon, 24 Nov 2008 23:08:09 +0200 (IST) From: Gleb Natapov Date: Mon, 24 Nov 2008 23:08:07 +0200 Message-ID: <20081124210805.11128.64357.stgit@dhcp-1-237.tlv.redhat.com> In-Reply-To: <20081124210738.11128.19342.stgit@dhcp-1-237.tlv.redhat.com> References: <20081124210738.11128.19342.stgit@dhcp-1-237.tlv.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH v2 3/5] Write table offset and size in one syscall. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Otherwise if VM is killed between two writes data may be lost. But if offset and size fields are at the same disk block one write should update them both simultaneously. Signed-off-by: Gleb Natapov --- block-qcow2.c | 26 +++++++++----------------- 1 files changed, 9 insertions(+), 17 deletions(-) diff --git a/block-qcow2.c b/block-qcow2.c index f55a4e4..a65a10d 100644 --- a/block-qcow2.c +++ b/block-qcow2.c @@ -429,8 +429,7 @@ static int grow_l1_table(BlockDriverState *bs, int min_size) int new_l1_size, new_l1_size2, ret, i; uint64_t *new_l1_table; uint64_t new_l1_table_offset; - uint64_t data64; - uint32_t data32; + uint8_t data[12]; new_l1_size = s->l1_size; if (min_size <= new_l1_size) @@ -460,13 +459,10 @@ static int grow_l1_table(BlockDriverState *bs, int min_size) new_l1_table[i] = be64_to_cpu(new_l1_table[i]); /* set new table */ - data64 = cpu_to_be64(new_l1_table_offset); - if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_table_offset), - &data64, sizeof(data64)) != sizeof(data64)) - goto fail; - data32 = cpu_to_be32(new_l1_size); - if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), - &data32, sizeof(data32)) != sizeof(data32)) + cpu_to_be32w((uint32_t*)data, new_l1_size); + cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset); + if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data, + sizeof(data)) != sizeof(data)) goto fail; qemu_free(s->l1_table); free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t)); @@ -2281,8 +2277,7 @@ static int grow_refcount_table(BlockDriverState *bs, int min_size) int new_table_size, new_table_size2, refcount_table_clusters, i, ret; uint64_t *new_table; int64_t table_offset; - uint64_t data64; - uint32_t data32; + uint8_t data[12]; int old_table_size; int64_t old_table_offset; @@ -2321,13 +2316,10 @@ static int grow_refcount_table(BlockDriverState *bs, int min_size) for(i = 0; i < s->refcount_table_size; i++) be64_to_cpus(&new_table[i]); - data64 = cpu_to_be64(table_offset); + cpu_to_be64w((uint64_t*)data, table_offset); + cpu_to_be32w((uint32_t*)(data + 8), refcount_table_clusters); if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_offset), - &data64, sizeof(data64)) != sizeof(data64)) - goto fail; - data32 = cpu_to_be32(refcount_table_clusters); - if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_clusters), - &data32, sizeof(data32)) != sizeof(data32)) + data, sizeof(data)) != sizeof(data)) goto fail; qemu_free(s->refcount_table); old_table_offset = s->refcount_table_offset;