From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L7bZk-0006iE-EV for qemu-devel@nongnu.org; Tue, 02 Dec 2008 15:10:28 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L7bZj-0006hn-SY for qemu-devel@nongnu.org; Tue, 02 Dec 2008 15:10:28 -0500 Received: from [199.232.76.173] (port=38719 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L7bZj-0006hj-PT for qemu-devel@nongnu.org; Tue, 02 Dec 2008 15:10:27 -0500 Received: from savannah.gnu.org ([199.232.41.3]:39271 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1L7bZj-0004ET-G4 for qemu-devel@nongnu.org; Tue, 02 Dec 2008 15:10:27 -0500 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1L7bZi-0004Y1-UD for qemu-devel@nongnu.org; Tue, 02 Dec 2008 20:10:27 +0000 Received: from aliguori by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1L7bZi-0004XZ-F2 for qemu-devel@nongnu.org; Tue, 02 Dec 2008 20:10:26 +0000 MIME-Version: 1.0 Errors-To: aliguori Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Anthony Liguori Message-Id: Date: Tue, 02 Dec 2008 20:10:26 +0000 Subject: [Qemu-devel] [5859] Write table offset and size in one syscall (Gleb Natapov) 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 Revision: 5859 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5859 Author: aliguori Date: 2008-12-02 20:10:14 +0000 (Tue, 02 Dec 2008) Log Message: ----------- Write table offset and size in one syscall (Gleb Natapov) 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 Signed-off-by: Anthony Liguori Modified Paths: -------------- trunk/block-qcow2.c Modified: trunk/block-qcow2.c =================================================================== --- trunk/block-qcow2.c 2008-12-02 20:08:04 UTC (rev 5858) +++ trunk/block-qcow2.c 2008-12-02 20:10:14 UTC (rev 5859) @@ -429,8 +429,7 @@ 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,14 +459,11 @@ 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)) + 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; - data32 = cpu_to_be32(new_l1_size); - if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), - &data32, sizeof(data32)) != sizeof(data32)) - goto fail; qemu_free(s->l1_table); free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t)); s->l1_table_offset = new_l1_table_offset; @@ -2281,8 +2277,7 @@ 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,14 +2316,11 @@ 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)) + data, sizeof(data)) != sizeof(data)) goto fail; - data32 = cpu_to_be32(refcount_table_clusters); - if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_clusters), - &data32, sizeof(data32)) != sizeof(data32)) - goto fail; qemu_free(s->refcount_table); old_table_offset = s->refcount_table_offset; old_table_size = s->refcount_table_size;