# 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;