AMD NOR flash device support (initial patch by Jocelyn Mayer)
[qemu] / block-qcow.c
index 99c3832..e5b52fb 100644 (file)
@@ -23,7 +23,7 @@
  */
 #include "vl.h"
 #include "block_int.h"
-#include "zlib.h"
+#include <zlib.h>
 #include "aes.h"
 
 /**************************************************************/
@@ -80,8 +80,9 @@ static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
 static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
 {
     const QCowHeader *cow_header = (const void *)buf;
-
-    if (be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
+    
+    if (buf_size >= sizeof(QCowHeader) &&
+        be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
         be32_to_cpu(cow_header->version) == QCOW_VERSION) 
         return 100;
     else
@@ -551,15 +552,28 @@ static int qcow_create(const char *filename, int64_t total_size,
     header_size = sizeof(header);
     backing_filename_len = 0;
     if (backing_file) {
-        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 */
@@ -592,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;
@@ -661,6 +693,12 @@ int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static void qcow_flush(BlockDriverState *bs)
+{
+    BDRVQcowState *s = bs->opaque;
+    fsync(s->fd);
+}
+
 BlockDriver bdrv_qcow = {
     "qcow",
     sizeof(BDRVQcowState),
@@ -670,8 +708,10 @@ BlockDriver bdrv_qcow = {
     qcow_write,
     qcow_close,
     qcow_create,
+    qcow_flush,
     qcow_is_allocated,
     qcow_set_key,
+    qcow_make_empty
 };