]> xenbits.xen.org Git - xenclient/ioemu.git/commitdiff
Fix savevm after BDRV_FILE size enforcement
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 5 Apr 2009 21:07:26 +0000 (21:07 +0000)
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 5 Apr 2009 21:07:26 +0000 (21:07 +0000)
 We now enforce that you cannot write beyond the end of a non-growable file.
 qcow2 files are not growable but we rely on them being growable to do
 savevm/loadvm.  Temporarily allow them to be growable by introducing a new
 API specifically for savevm read/write operations.

Reported-by: malc
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@7005 c046a42c-6fe2-441c-8c8c-71466251a162

block-qcow2.c
block.c
block.h
block_int.h
savevm.c

index 9e69ddf0a007fb3857f389375ec664e915121fcf..1be909e5ca12c6d736efc1732327343af1cc6ddb 100644 (file)
@@ -2601,6 +2601,31 @@ static void dump_refcounts(BlockDriverState *bs)
 #endif
 #endif
 
+static int qcow_put_buffer(BlockDriverState *bs, const uint8_t *buf,
+                           int64_t pos, int size)
+{
+    int growable = bs->growable;
+
+    bs->growable = 1;
+    bdrv_pwrite(bs, pos, buf, size);
+    bs->growable = growable;
+
+    return size;
+}
+
+static int qcow_get_buffer(BlockDriverState *bs, uint8_t *buf,
+                           int64_t pos, int size)
+{
+    int growable = bs->growable;
+    int ret;
+
+    bs->growable = 1;
+    ret = bdrv_pread(bs, pos, buf, size);
+    bs->growable = growable;
+
+    return ret;
+}
+
 BlockDriver bdrv_qcow2 = {
     "qcow2",
     sizeof(BDRVQcowState),
@@ -2626,4 +2651,7 @@ BlockDriver bdrv_qcow2 = {
     .bdrv_snapshot_delete = qcow_snapshot_delete,
     .bdrv_snapshot_list = qcow_snapshot_list,
     .bdrv_get_info = qcow_get_info,
+
+    .bdrv_put_buffer    = qcow_put_buffer,
+    .bdrv_get_buffer    = qcow_get_buffer,
 };
diff --git a/block.c b/block.c
index bcd8431f1e72b282a3afb4692757e6af58a2895a..3f262fa590adad7582fd7c194005ea80d029b447 100644 (file)
--- a/block.c
+++ b/block.c
@@ -1181,6 +1181,26 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
     return drv->bdrv_get_info(bs, bdi);
 }
 
+int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv)
+        return -ENOMEDIUM;
+    if (!drv->bdrv_put_buffer)
+        return -ENOTSUP;
+    return drv->bdrv_put_buffer(bs, buf, pos, size);
+}
+
+int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv)
+        return -ENOMEDIUM;
+    if (!drv->bdrv_get_buffer)
+        return -ENOTSUP;
+    return drv->bdrv_get_buffer(bs, buf, pos, size);
+}
+
 /**************************************************************/
 /* handling of snapshots */
 
diff --git a/block.h b/block.h
index 702403f6c3f2a1f23d234332c4e4bae7ece3bfb9..979781a12e8f69fd72f21950e258f4a9f6aa5ae4 100644 (file)
--- a/block.h
+++ b/block.h
@@ -169,4 +169,9 @@ void path_combine(char *dest, int dest_size,
                   const char *base_path,
                   const char *filename);
 
+int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf,
+                    int64_t pos, int size);
+
+int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size);
+
 #endif
index 44eb280684d8474e57df81afbbda2da8d5b88604..c6af1c64dadd45e154592e0157414bd370b23599 100644 (file)
@@ -76,6 +76,11 @@ struct BlockDriver {
                               QEMUSnapshotInfo **psn_info);
     int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
 
+    int (*bdrv_put_buffer)(BlockDriverState *bs, const uint8_t *buf,
+                           int64_t pos, int size);
+    int (*bdrv_get_buffer)(BlockDriverState *bs, uint8_t *buf,
+                           int64_t pos, int size);
+
     /* removable device specific */
     int (*bdrv_is_inserted)(BlockDriverState *bs);
     int (*bdrv_media_changed)(BlockDriverState *bs);
index f2463e780ef028711cd321472ad974acdc883497..e1808c69d6089bd5555b521a9846d46ff5b8fac1 100644 (file)
--- a/savevm.c
+++ b/savevm.c
@@ -306,18 +306,18 @@ typedef struct QEMUFileBdrv
     int64_t base_offset;
 } QEMUFileBdrv;
 
-static int bdrv_put_buffer(void *opaque, const uint8_t *buf,
+static int block_put_buffer(void *opaque, const uint8_t *buf,
                            int64_t pos, int size)
 {
     QEMUFileBdrv *s = opaque;
-    bdrv_pwrite(s->bs, s->base_offset + pos, buf, size);
+    bdrv_put_buffer(s->bs, buf, s->base_offset + pos, size);
     return size;
 }
 
-static int bdrv_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
+static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
 {
     QEMUFileBdrv *s = opaque;
-    return bdrv_pread(s->bs, s->base_offset + pos, buf, size);
+    return bdrv_get_buffer(s->bs, buf, s->base_offset + pos, size);
 }
 
 static int bdrv_fclose(void *opaque)
@@ -337,9 +337,9 @@ static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_wr
     s->base_offset = offset;
 
     if (is_writable)
-        return qemu_fopen_ops(s, bdrv_put_buffer, NULL, bdrv_fclose, NULL);
+        return qemu_fopen_ops(s, block_put_buffer, NULL, bdrv_fclose, NULL);
 
-    return qemu_fopen_ops(s, NULL, bdrv_get_buffer, bdrv_fclose, NULL);
+    return qemu_fopen_ops(s, NULL, block_get_buffer, bdrv_fclose, NULL);
 }
 
 QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,