Sophie

Sophie

distrib > Mandriva > 2009.0 > x86_64 > by-pkgid > 132cd009b832939558135d1f5aafae4a > files > 2

qemu-0.9.1-0.r5137.1.2mdv2009.0.src.rpm

# HG changeset patch
# User Bogdano Arendartchuk <debogdano@gmail.com>
# Date 1254762381 10800
# Branch the-newer-fix
# Node ID d364316d26c3823fb12ad13064a2f1fc9982472f
# Parent  c99c479d699a18ffcb644880567c8a8f076dfd3d
The newer fix, incomplete, as vl.c does not have block_put_buffer

diff -r c99c479d699a -r d364316d26c3 block-qcow2.c
--- a/block-qcow2.c	Thu Oct 01 19:48:46 2009 -0300
+++ b/block-qcow2.c	Mon Oct 05 14:06:21 2009 -0300
@@ -2596,6 +2596,31 @@ static void dump_refcounts(BlockDriverSt
 #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),
@@ -2621,4 +2646,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 -r c99c479d699a -r d364316d26c3 block.c
--- a/block.c	Thu Oct 01 19:48:46 2009 -0300
+++ b/block.c	Mon Oct 05 14:06:21 2009 -0300
@@ -315,6 +315,7 @@ int bdrv_file_open(BlockDriverState **pb
         bdrv_delete(bs);
         return ret;
     }
+    bs->growable = 1;
     *pbs = bs;
     return 0;
 }
@@ -506,6 +507,39 @@ int bdrv_commit(BlockDriverState *bs)
     return 0;
 }
 
+static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
+                                   size_t size)
+{
+    int64_t len;
+
+    if (!bdrv_is_inserted(bs))
+        return -ENOMEDIUM;
+
+    if (bs->growable)
+        return 0;
+
+    len = bdrv_getlength(bs);
+
+    if ((offset + size) > len)
+        return -EIO;
+
+    return 0;
+}
+
+static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
+                              int nb_sectors)
+{
+    int64_t offset;
+
+    /* Deal with byte accesses */
+    if (sector_num < 0)
+        offset = -sector_num;
+    else
+        offset = sector_num * 512;
+
+    return bdrv_check_byte_request(bs, offset, nb_sectors * 512);
+}
+
 /* return < 0 if error. See bdrv_write() for the return codes */
 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
               uint8_t *buf, int nb_sectors)
@@ -514,6 +548,8 @@ int bdrv_read(BlockDriverState *bs, int6
 
     if (!drv)
         return -ENOMEDIUM;
+    if (bdrv_check_request(bs, sector_num, nb_sectors))
+        return -EIO;
 
     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
             memcpy(buf, bs->boot_sector_data, 512);
@@ -555,6 +591,9 @@ int bdrv_write(BlockDriverState *bs, int
         return -ENOMEDIUM;
     if (bs->read_only)
         return -EACCES;
+    if (bdrv_check_request(bs, sector_num, nb_sectors))
+        return -EIO;
+
     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
         memcpy(bs->boot_sector_data, buf, 512);
     }
@@ -678,6 +717,9 @@ int bdrv_pread(BlockDriverState *bs, int
 
     if (!drv)
         return -ENOMEDIUM;
+    if (bdrv_check_byte_request(bs, offset, count1))
+        return -EIO;
+
     if (!drv->bdrv_pread)
         return bdrv_pread_em(bs, offset, buf1, count1);
     return drv->bdrv_pread(bs, offset, buf1, count1);
@@ -693,6 +735,8 @@ int bdrv_pwrite(BlockDriverState *bs, in
 
     if (!drv)
         return -ENOMEDIUM;
+    if (bdrv_check_byte_request(bs, offset, count1))
+        return -EIO;
     if (!drv->bdrv_pwrite)
         return bdrv_pwrite_em(bs, offset, buf1, count1);
     return drv->bdrv_pwrite(bs, offset, buf1, count1);
@@ -1002,6 +1046,26 @@ int bdrv_get_info(BlockDriverState *bs, 
     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 */
 
@@ -1134,6 +1198,8 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDri
 
     if (!drv)
         return NULL;
+    if (bdrv_check_request(bs, sector_num, nb_sectors))
+        return NULL;
 
     /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
@@ -1165,6 +1231,8 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDr
         return NULL;
     if (bs->read_only)
         return NULL;
+    if (bdrv_check_request(bs, sector_num, nb_sectors))
+        return NULL;
     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
         memcpy(bs->boot_sector_data, buf, 512);
     }
diff -r c99c479d699a -r d364316d26c3 block.h
--- a/block.h	Thu Oct 01 19:48:46 2009 -0300
+++ b/block.h	Mon Oct 05 14:06:21 2009 -0300
@@ -159,5 +159,10 @@ int path_is_absolute(const char *path);
 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
diff -r c99c479d699a -r d364316d26c3 block_int.h
--- a/block_int.h	Thu Oct 01 19:48:46 2009 -0300
+++ b/block_int.h	Mon Oct 05 14:06:21 2009 -0300
@@ -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);
@@ -124,6 +129,9 @@ struct BlockDriverState {
     uint64_t rd_ops;
     uint64_t wr_ops;
 
+    /* Whether the disk can expand beyond total_sectors */
+    int growable;
+
     /* NOTE: the following infos are only hints for real hardware
        drivers. They are not used by the block driver */
     int cyls, heads, secs, translation;