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] Qcow driver code cleanup:

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Qcow driver code cleanup:
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 19 Dec 2006 17:15:06 -0800
Delivery-date: Tue, 19 Dec 2006 17:15:38 -0800
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 Julian Chesterfield <julian@xxxxxxxxxxxxx>
# Date 1166560976 0
# Node ID 08fa19392d75eae17d5e90cd38bec834afdf7f25
# Parent  057f7c4dbed1c75a3fbe446d346cee04cff31497
Qcow driver code cleanup:
- Remove global QCOW flags
- rename sparseness flag to -r fore 'reserve'
- Add ROUNDUP macro
- Check for qtruncate failures

Signed-off-by: Julian Chesterfield <julian@xxxxxxxxxxxxx>
---
 tools/blktap/drivers/block-qcow.c  |  130 ++++++++++++++++++++++++-------------
 tools/blktap/drivers/qcow-create.c |   26 ++++---
 2 files changed, 101 insertions(+), 55 deletions(-)

diff -r 057f7c4dbed1 -r 08fa19392d75 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Tue Dec 19 12:00:11 2006 +0000
+++ b/tools/blktap/drivers/block-qcow.c Tue Dec 19 20:42:56 2006 +0000
@@ -47,6 +47,11 @@
 #define ASSERT(_p) ((void)0)
 #endif
 
+#define ROUNDUP(l, s) \
+({ \
+    (uint64_t)( \
+        (l + (s - 1)) - ((l + (s - 1)) % s)); \
+})
 
 /******AIO DEFINES******/
 #define REQUEST_ASYNC_FD 1
@@ -76,9 +81,9 @@ struct pending_aio {
 
 #define QCOW_CRYPT_NONE 0x00
 #define QCOW_CRYPT_AES  0x01
-#define QCOW_SPARSE_FILE 0x02
 
 #define QCOW_OFLAG_COMPRESSED (1LL << 63)
+#define SPARSE_FILE 0x01
 
 #ifndef O_BINARY
 #define O_BINARY 0
@@ -418,8 +423,9 @@ static void encrypt_sectors(struct tdqco
 
 static int qtruncate(int fd, off_t length, int sparse)
 {
-       int current, ret, i; 
-       int sectors = length/DEFAULT_SECTOR_SIZE;
+       int ret, i; 
+       int current = 0, rem = 0;
+       int sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
        struct stat st;
        char buf[DEFAULT_SECTOR_SIZE];
 
@@ -429,22 +435,45 @@ static int qtruncate(int fd, off_t lengt
         */
        memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
        ret = fstat(fd, &st);
-       if((ret == -1) || S_ISBLK(st.st_mode))
+       if (ret == -1)
                return -1;
-
-       if(st.st_size < length) {
+       if (S_ISBLK(st.st_mode))
+               return 0;
+
+       current = (st.st_size + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
+       rem = st.st_size % DEFAULT_SECTOR_SIZE;
+
+       /* If we are extending this file, we write zeros to the end --
+        * this tries to ensure that the extents allocated wind up being
+        * contiguous on disk.
+        */
+       if(st.st_size < sectors * DEFAULT_SECTOR_SIZE) {
                /*We are extending the file*/
-               lseek(fd, 0, SEEK_END);
-               for (i = 0; i < sectors; i++ ) {
+               if (lseek(fd, 0, SEEK_END)==-1) {
+                       fprintf(stderr, 
+                               "Lseek EOF failed (%d), internal error\n",
+                               errno);
+                       return -1;
+               }
+               if (rem) {
+                       ret = write(fd, buf, rem);
+                       if (ret != rem)
+                               return -1;
+               }
+               for (i = current; i < sectors; i++ ) {
                        ret = write(fd, buf, DEFAULT_SECTOR_SIZE);
                        if (ret != DEFAULT_SECTOR_SIZE)
                                return -1;
                }
                
-       } else if(sparse && (st.st_size > length))
-               ftruncate(fd, length);
-
-       return 1;
+       } else if(sparse && (st.st_size > sectors * DEFAULT_SECTOR_SIZE))
+               if (ftruncate(fd, sectors * DEFAULT_SECTOR_SIZE)==-1) {
+                       fprintf(stderr,
+                               "Ftruncate failed (%d), internal error\n",
+                                errno);
+                       return -1;
+               }
+       return 0;
 }
 
 
@@ -497,7 +526,12 @@ static uint64_t get_cluster_offset(struc
                
                /*Truncate file for L2 table 
                 *(initialised to zero in case we crash)*/
-               qtruncate(s->fd, l2_offset + (s->l2_size * sizeof(uint64_t)), 
s->sparse);
+               if (qtruncate(s->fd, 
+                             l2_offset + (s->l2_size * sizeof(uint64_t)),
+                             s->sparse) != 0) {
+                       DPRINTF("ERROR truncating file\n");
+                       return 0;
+               }
                s->fd_end = l2_offset + (s->l2_size * sizeof(uint64_t));
 
                /*Update the L1 table entry on disk
@@ -564,8 +598,12 @@ cache_miss:
                                (s->l2_size * sizeof(uint64_t));
                        cluster_offset = (cluster_offset + s->cluster_size - 1)
                                & ~(s->cluster_size - 1);
-                       qtruncate(s->fd, cluster_offset + 
-                                 (s->cluster_size * s->l2_size), s->sparse);
+                       if (qtruncate(s->fd, cluster_offset + 
+                                 (s->cluster_size * s->l2_size), 
+                                     s->sparse) != 0) {
+                               DPRINTF("ERROR truncating file\n");
+                               return 0;
+                       }
                        s->fd_end = cluster_offset + 
                                (s->cluster_size * s->l2_size);
                        for (i = 0; i < s->l2_size; i++) {
@@ -623,8 +661,11 @@ found:
                                cluster_offset = 
                                        (cluster_offset + s->cluster_size - 1) 
                                        & ~(s->cluster_size - 1);
-                               qtruncate(s->fd, cluster_offset + 
-                                         s->cluster_size, s->sparse);
+                               if (qtruncate(s->fd, cluster_offset + 
+                                             s->cluster_size, s->sparse)!=0) {
+                                       DPRINTF("ERROR truncating file\n");
+                                       return 0;
+                               }
                                s->fd_end = (cluster_offset + s->cluster_size);
                                /* if encrypted, we must initialize the cluster
                                   content which won't be written */
@@ -909,15 +950,14 @@ int tdqcow_open (struct td_state *bs, co
 
                /*Finally check the L1 table cksum*/
                be32_to_cpus(&exthdr->cksum);
-               cksum = gen_cksum((char *)s->l1_table, s->l1_size * 
sizeof(uint64_t));
-               if(exthdr->cksum != cksum) {
+               cksum = gen_cksum((char *)s->l1_table, 
+                                 s->l1_size * sizeof(uint64_t));
+               if(exthdr->cksum != cksum)
                        goto end_xenhdr;
-               }
                        
                be32_to_cpus(&exthdr->min_cluster_alloc);
                be32_to_cpus(&exthdr->flags);
-               if (exthdr->flags & QCOW_SPARSE_FILE)
-                       s->sparse = 1;
+               s->sparse = (exthdr->flags & SPARSE_FILE);
                s->min_cluster_alloc = exthdr->min_cluster_alloc; 
        }
 
@@ -1210,10 +1250,10 @@ int tdqcow_do_callbacks(struct td_state 
 }
 
 int qcow_create(const char *filename, uint64_t total_size,
-                      const char *backing_file, int flags)
+                      const char *backing_file, int sparse)
 {
        int fd, header_size, backing_filename_len, l1_size, i;
-       int shift, length, adjust, ret = 0;
+       int shift, length, adjust, flags = 0, ret = 0;
        QCowHeader header;
        QCowHeader_ext exthdr;
        char backing_filename[1024], *ptr;
@@ -1305,11 +1345,7 @@ int qcow_create(const char *filename, ui
        DPRINTF("L1 Table offset: %d, size %d\n",
                header_size,
                (int)(l1_size * sizeof(uint64_t)));
-       if (flags & QCOW_CRYPT_AES) {
-               header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
-       } else {
-               header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
-       }
+       header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
 
        ptr = calloc(1, l1_size * sizeof(uint64_t));
        exthdr.cksum = cpu_to_be32(gen_cksum(ptr, l1_size * sizeof(uint64_t)));
@@ -1317,29 +1353,32 @@ int qcow_create(const char *filename, ui
        free(ptr);
 
        /*adjust file length to 4 KByte boundary*/
-       length = header_size + l1_size * sizeof(uint64_t);
-       if (length % 4096 > 0) {
-               length = ((length >> 12) + 1) << 12;
-               qtruncate(fd, length, 0);
-               DPRINTF("Adjusted filelength to %d for 4 "
-                       "Kbyte alignment\n",length);
-       }
-
-       if (!(flags & QCOW_SPARSE_FILE)) {
-               /*Filesize is length +  l1_size * (1 << s->l2_bits) + 
(size*512)*/
+       length = ROUNDUP(header_size + (l1_size * sizeof(uint64_t)),PAGE_SIZE);
+       if (qtruncate(fd, length, 0)!=0) {
+               DPRINTF("ERROR truncating file\n");
+               return -1;
+       }
+
+       if (sparse == 0) {
+               /*Filesize is length+l1_size*(1 << s->l2_bits)+(size*512)*/
                total_length = length + (l1_size * (1 << 9)) + (size * 512);
-               qtruncate(fd, total_length, 0);
+               if (qtruncate(fd, total_length, 0)!=0) {
+                        DPRINTF("ERROR truncating file\n");
+                        return -1;
+               }
                printf("File truncated to length %"PRIu64"\n",total_length);
-       }
+       } else
+               flags = SPARSE_FILE;
+
        exthdr.flags = cpu_to_be32(flags);
        
        /* write all the data */
        lseek(fd, 0, SEEK_SET);
        ret += write(fd, &header, sizeof(header));
        ret += write(fd, &exthdr, sizeof(exthdr));
-       if (backing_file) {
+       if (backing_file)
                ret += write(fd, backing_filename, backing_filename_len);
-       }
+
        lseek(fd, header_size, SEEK_SET);
        tmp = 0;
        for (i = 0;i < l1_size; i++) {
@@ -1360,7 +1399,10 @@ int qcow_make_empty(struct td_state *bs)
        lseek(s->fd, s->l1_table_offset, SEEK_SET);
        if (write(s->fd, s->l1_table, l1_length) < 0)
                return -1;
-       qtruncate(s->fd, s->l1_table_offset + l1_length, s->sparse);
+       if (qtruncate(s->fd, s->l1_table_offset + l1_length, s->sparse)!=0) {
+               DPRINTF("ERROR truncating file\n");
+               return -1;
+       }
 
        memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
        memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
diff -r 057f7c4dbed1 -r 08fa19392d75 tools/blktap/drivers/qcow-create.c
--- a/tools/blktap/drivers/qcow-create.c        Tue Dec 19 12:00:11 2006 +0000
+++ b/tools/blktap/drivers/qcow-create.c        Tue Dec 19 20:42:56 2006 +0000
@@ -47,15 +47,13 @@
 #define DFPRINTF(_f, _a...) ((void)0)
 #endif
 
-#define QCOW_NONSPARSE_FILE 0x00
-#define QCOW_SPARSE_FILE 0x02
 #define MAX_NAME_LEN 1000
 
 void help(void)
 {
        fprintf(stderr, "Qcow-utils: v1.0.0\n");
        fprintf(stderr, 
-               "usage: qcow-create [-h help] [-p reserve] <SIZE(MB)> 
<FILENAME> "
+               "usage: qcow-create [-h help] [-r reserve] <SIZE(MB)> 
<FILENAME> "
                "[<BACKING_FILENAME>]\n"); 
        exit(-1);
 }
@@ -63,12 +61,12 @@ int main(int argc, char *argv[])
 int main(int argc, char *argv[])
 {
        int ret = -1, c, backed = 0;
-       int flags =  QCOW_SPARSE_FILE;
+       int sparse =  1;
        uint64_t size;
        char filename[MAX_NAME_LEN], bfilename[MAX_NAME_LEN];
 
         for(;;) {
-                c = getopt(argc, argv, "hp");
+                c = getopt(argc, argv, "hr");
                 if (c == -1)
                         break;
                 switch(c) {
@@ -76,9 +74,12 @@ int main(int argc, char *argv[])
                         help();
                         exit(0);
                         break;
-                case 'p':
-                       flags = QCOW_NONSPARSE_FILE;
+                case 'r':
+                       sparse = 0;
                        break;
+               default:
+                       fprintf(stderr, "Unknown option\n");
+                       help();
                }
        }
 
@@ -96,6 +97,7 @@ int main(int argc, char *argv[])
        }
 
        if (optind != argc) {
+               /*Backing file argument*/
                backed = 1;
                if (snprintf(bfilename, MAX_NAME_LEN, "%s",argv[optind++]) >=
                        MAX_NAME_LEN) {
@@ -106,12 +108,14 @@ int main(int argc, char *argv[])
 
        DFPRINTF("Creating file size %llu, name %s\n",(long long unsigned)size, 
filename);
        if (!backed)
-               ret = qcow_create(filename,size,NULL,flags);
+               ret = qcow_create(filename,size,NULL,sparse);
        else
-               ret = qcow_create(filename,size,bfilename,flags);
+               ret = qcow_create(filename,size,bfilename,sparse);
 
-       if (ret < 0) DPRINTF("Unable to create QCOW file\n");
-       else DPRINTF("QCOW file successfully created\n");
+       if (ret < 0)
+               DPRINTF("Unable to create QCOW file\n");
+       else
+               DPRINTF("QCOW file successfully created\n");
 
        return 0;
 }

_______________________________________________
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] Qcow driver code cleanup:, Xen patchbot-unstable <=