qcow_make_empty() support (Johannes Schindelin)
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 18 Dec 2005 18:28:15 +0000 (18:28 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 18 Dec 2005 18:28:15 +0000 (18:28 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1716 c046a42c-6fe2-441c-8c8c-71466251a162

block-qcow.c
block.c
block_int.h

index ca05be8..34026a4 100644 (file)
@@ -552,25 +552,28 @@ static int qcow_create(const char *filename, int64_t total_size,
     header_size = sizeof(header);
     backing_filename_len = 0;
     if (backing_file) {
-        const char *p;
-        /* XXX: this is a hack: we do not attempt to check for URL
-           like syntax */
-        p = strchr(backing_file, ':');
-        if (p && (p - backing_file) >= 2) {
-            /* URL like but exclude "c:" like filenames */
-            pstrcpy(backing_filename, sizeof(backing_filename),
-                    backing_file);
-        } else {
-            realpath(backing_file, backing_filename);
-            if (stat(backing_filename, &st) != 0) {
-                return -1;
-            }
-        }
+       if (strcmp(backing_file, "fat:")) {
+           const char *p;
+           /* XXX: this is a hack: we do not attempt to check for URL
+              like syntax */
+           p = strchr(backing_file, ':');
+           if (p && (p - backing_file) >= 2) {
+               /* URL like but exclude "c:" like filenames */
+               pstrcpy(backing_filename, sizeof(backing_filename),
+                       backing_file);
+           } else {
+               realpath(backing_file, backing_filename);
+               if (stat(backing_filename, &st) != 0) {
+                   return -1;
+               }
+           }
+           header.backing_file_offset = cpu_to_be64(header_size);
+           backing_filename_len = strlen(backing_filename);
+           header.backing_file_size = cpu_to_be32(backing_filename_len);
+           header_size += backing_filename_len;
+       } else
+           backing_file = NULL;
         header.mtime = cpu_to_be32(st.st_mtime);
-        header.backing_file_offset = cpu_to_be64(header_size);
-        backing_filename_len = strlen(backing_filename);
-        header.backing_file_size = cpu_to_be32(backing_filename_len);
-        header_size += backing_filename_len;
         header.cluster_bits = 9; /* 512 byte cluster to avoid copying
                                     unmodifyed sectors */
         header.l2_bits = 12; /* 32 KB L2 tables */
@@ -603,6 +606,24 @@ static int qcow_create(const char *filename, int64_t total_size,
     return 0;
 }
 
+int qcow_make_empty(BlockDriverState *bs)
+{
+    BDRVQcowState *s = bs->opaque;
+    uint32_t l1_length = s->l1_size * sizeof(uint64_t);
+
+    memset(s->l1_table, 0, l1_length);
+    lseek(s->fd, s->l1_table_offset, SEEK_SET);
+    if (write(s->fd, s->l1_table, l1_length) < 0)
+       return -1;
+    ftruncate(s->fd, s->l1_table_offset + l1_length);
+
+    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));
+    memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t));
+
+    return 0;
+}
+
 int qcow_get_cluster_size(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
@@ -683,6 +704,7 @@ BlockDriver bdrv_qcow = {
     qcow_create,
     qcow_is_allocated,
     qcow_set_key,
+    qcow_make_empty
 };
 
 
diff --git a/block.c b/block.c
index efd96e6..6924cee 100644 (file)
--- a/block.c
+++ b/block.c
@@ -150,13 +150,19 @@ int bdrv_create(BlockDriver *drv,
 }
 
 #ifdef _WIN32
-static void get_tmp_filename(char *filename, int size)
+void get_tmp_filename(char *filename, int size)
 {
+    char* p = strrchr(filename, '/');
+
+    if (p == NULL)
+       return;
+
     /* XXX: find a better function */
-    tmpnam(filename);
+    tmpnam(p);
+    *p = '/';
 }
 #else
-static void get_tmp_filename(char *filename, int size)
+void get_tmp_filename(char *filename, int size)
 {
     int fd;
     /* XXX: race condition possible */
@@ -394,6 +400,10 @@ int bdrv_commit(BlockDriverState *bs)
             i += n;
         }
     }
+
+    if (bs->drv->bdrv_make_empty)
+       return bs->drv->bdrv_make_empty(bs);
+
     return 0;
 }
 
index 03744f7..e303816 100644 (file)
@@ -39,6 +39,7 @@ struct BlockDriver {
     int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
                              int nb_sectors, int *pnum);
     int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
+    int (*bdrv_make_empty)(BlockDriverState *bs);
     struct BlockDriver *next;
 };
 
@@ -74,4 +75,6 @@ struct BlockDriverState {
     BlockDriverState *next;
 };
 
+void get_tmp_filename(char *filename, int size);
+
 #endif /* BLOCK_INT_H */