[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Qcow driver code cleanup:



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.