]> git.proxmox.com Git - qemu.git/blobdiff - block/qcow2-snapshot.c
block: move include files to include/block/
[qemu.git] / block / qcow2-snapshot.c
index 7d3fde5a8acbbac570f13f70330274db9c7db4d0..eb8fcd55497ff6e5d11b038a01d6abf27b79bd56 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "qemu-common.h"
-#include "block_int.h"
+#include "block/block_int.h"
 #include "block/qcow2.h"
 
 typedef struct QEMU_PACKED QCowSnapshotHeader {
@@ -48,6 +48,7 @@ typedef struct QEMU_PACKED QCowSnapshotHeader {
 
 typedef struct QEMU_PACKED QCowSnapshotExtraData {
     uint64_t vm_state_size_large;
+    uint64_t disk_size;
 } QCowSnapshotExtraData;
 
 void qcow2_free_snapshots(BlockDriverState *bs)
@@ -117,6 +118,12 @@ int qcow2_read_snapshots(BlockDriverState *bs)
             sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large);
         }
 
+        if (extra_data_size >= 16) {
+            sn->disk_size = be64_to_cpu(extra.disk_size);
+        } else {
+            sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
+        }
+
         /* Read snapshot ID */
         sn->id_str = g_malloc(id_str_size + 1);
         ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size);
@@ -197,6 +204,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
 
         memset(&extra, 0, sizeof(extra));
         extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size);
+        extra.disk_size = cpu_to_be64(sn->disk_size);
 
         id_str_size = strlen(sn->id_str);
         name_size = strlen(sn->name);
@@ -323,13 +331,14 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 
     /* Check that the ID is unique */
     if (find_snapshot_by_id(bs, sn_info->id_str) >= 0) {
-        return -ENOENT;
+        return -EEXIST;
     }
 
     /* Populate sn with passed data */
     sn->id_str = g_strdup(sn_info->id_str);
     sn->name = g_strdup(sn_info->name);
 
+    sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
     sn->vm_state_size = sn_info->vm_state_size;
     sn->date_sec = sn_info->date_sec;
     sn->date_nsec = sn_info->date_nsec;
@@ -396,7 +405,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 #ifdef DEBUG_ALLOC
     {
       BdrvCheckResult result = {0};
-      qcow2_check_refcounts(bs, &result);
+      qcow2_check_refcounts(bs, &result, 0);
     }
 #endif
     return 0;
@@ -426,6 +435,13 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
     }
     sn = &s->snapshots[snapshot_index];
 
+    if (sn->disk_size != bs->total_sectors * BDRV_SECTOR_SIZE) {
+        error_report("qcow2: Loading snapshots with different disk "
+            "size is not implemented");
+        ret = -ENOTSUP;
+        goto fail;
+    }
+
     /*
      * Make sure that the current L1 table is big enough to contain the whole
      * L1 table of the snapshot. If the snapshot L1 table is smaller, the
@@ -506,7 +522,7 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
 #ifdef DEBUG_ALLOC
     {
         BdrvCheckResult result = {0};
-        qcow2_check_refcounts(bs, &result);
+        qcow2_check_refcounts(bs, &result, 0);
     }
 #endif
     return 0;
@@ -566,7 +582,7 @@ int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
 #ifdef DEBUG_ALLOC
     {
         BdrvCheckResult result = {0};
-        qcow2_check_refcounts(bs, &result);
+        qcow2_check_refcounts(bs, &result, 0);
     }
 #endif
     return 0;