WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] tapdisk: Fix L1 table endianess of qcow i

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] tapdisk: Fix L1 table endianess of qcow images
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 27 Mar 2008 14:40:14 -0700
Delivery-date: Thu, 27 Mar 2008 14:40:21 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1206638017 0
# Node ID 17e30b91b9e2a6607d7b2a7db011ac2a4f11d1d1
# Parent  a819cf758b8cf5624214ba59bc0c13172b3c7f05
tapdisk: Fix L1 table endianess of qcow images

Fix tapdisk to use big endian L1 tables as used by qemu/ioemu. Old
tapdisk images with native endianess are automagically converted to
big endian when the image file is opened for the first time.

Signed-off-by: Kevin Wolf <kwolf@xxxxxxx>
---
 tools/blktap/drivers/block-qcow.c |   68 ++++++++++++++++++++++++++++++++------
 1 files changed, 59 insertions(+), 9 deletions(-)

diff -r a819cf758b8c -r 17e30b91b9e2 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Thu Mar 27 16:20:25 2008 +0000
+++ b/tools/blktap/drivers/block-qcow.c Thu Mar 27 17:13:37 2008 +0000
@@ -76,6 +76,7 @@
 
 #define QCOW_OFLAG_COMPRESSED (1LL << 63)
 #define SPARSE_FILE 0x01
+#define EXTHDR_L1_BIG_ENDIAN 0x02
 
 #ifndef O_BINARY
 #define O_BINARY 0
@@ -147,19 +148,30 @@ static int decompress_cluster(struct tdq
 
 static uint32_t gen_cksum(char *ptr, int len)
 {
+       int i;
        unsigned char *md;
        uint32_t ret;
 
        md = malloc(MD5_DIGEST_LENGTH);
 
        if(!md) return 0;
-
-       if (MD5((unsigned char *)ptr, len, md) != md) {
-               free(md);
-               return 0;
-       }
-
-       memcpy(&ret, md, sizeof(uint32_t));
+       
+       /* Convert L1 table to big endian */
+       for(i = 0; i < len / sizeof(uint64_t); i++) {
+               cpu_to_be64s(&((uint64_t*) ptr)[i]);
+       }
+
+       /* Generate checksum */
+       if (MD5((unsigned char *)ptr, len, md) != md)
+               ret = 0;
+       else
+               memcpy(&ret, md, sizeof(uint32_t));
+
+       /* Convert L1 table back to native endianess */
+       for(i = 0; i < len / sizeof(uint64_t); i++) {
+               be64_to_cpus(&((uint64_t*) ptr)[i]);
+       }
+
        free(md);
        return ret;
 }
@@ -354,7 +366,8 @@ static uint64_t get_cluster_offset(struc
                                    int n_start, int n_end)
 {
        int min_index, i, j, l1_index, l2_index, l2_sector, l1_sector;
-       char *tmp_ptr, *tmp_ptr2, *l2_ptr, *l1_ptr;
+       char *tmp_ptr2, *l2_ptr, *l1_ptr;
+       uint64_t *tmp_ptr;
        uint64_t l2_offset, *l2_table, cluster_offset, tmp;
        uint32_t min_count;
        int new_l2_table;
@@ -400,6 +413,11 @@ static uint64_t get_cluster_offset(struc
                        DPRINTF("ERROR allocating memory for L1 table\n");
                }
                memcpy(tmp_ptr, l1_ptr, 4096);
+
+               /* Convert block to write to big endian */
+               for(i = 0; i < 4096 / sizeof(uint64_t); i++) {
+                       cpu_to_be64s(&tmp_ptr[i]);
+               }
 
                /*
                 * Issue non-asynchronous L1 write.
@@ -777,7 +795,7 @@ int tdqcow_open (struct disk_driver *dd,
                goto fail;
 
        for(i = 0; i < s->l1_size; i++) {
-               //be64_to_cpus(&s->l1_table[i]);
+               be64_to_cpus(&s->l1_table[i]);
                //DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
                if (s->l1_table[i] > final_cluster)
                        final_cluster = s->l1_table[i];
@@ -810,6 +828,38 @@ int tdqcow_open (struct disk_driver *dd,
                be32_to_cpus(&exthdr->xmagic);
                if(exthdr->xmagic != XEN_MAGIC) 
                        goto end_xenhdr;
+    
+               /* Try to detect old tapdisk images. They have to be fixed 
because 
+                * they don't use big endian but native endianess for the L1 
table */
+               if ((exthdr->flags & EXTHDR_L1_BIG_ENDIAN) == 0) {
+
+                       /* 
+                          The image is broken. Fix it. The L1 table has 
already been 
+                          byte-swapped, so we can write it to the image file 
as it is
+                          currently in memory. Then swap it back to native 
endianess
+                          for operation.
+                        */
+
+                       DPRINTF("qcow: Converting image to big endian L1 
table\n");
+
+                       lseek(fd, s->l1_table_offset, SEEK_SET);
+                       if (write(fd, s->l1_table, l1_table_size) != 
l1_table_size) {
+                               DPRINTF("qcow: Failed to write new L1 table\n");
+                               goto fail;
+                       }
+
+                       for(i = 0;i < s->l1_size; i++) {
+                               cpu_to_be64s(&s->l1_table[i]);
+                       }
+
+                       /* Write the big endian flag to the extended header */
+                       exthdr->flags |= EXTHDR_L1_BIG_ENDIAN;
+
+                       if (write(fd, buf, 512) != 512) {
+                               DPRINTF("qcow: Failed to write extended 
header\n");
+                               goto fail;
+                       }
+               }
 
                /*Finally check the L1 table cksum*/
                be32_to_cpus(&exthdr->cksum);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] tapdisk: Fix L1 table endianess of qcow images, Xen patchbot-unstable <=