bdrv_delete(bs);
return ret;
}
+ bs->growable = 1;
*pbs = bs;
return 0;
}
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)
if (!drv)
return -ENOMEDIUM;
+ if (bdrv_check_request(bs, sector_num, nb_sectors))
+ return -EIO;
if (drv->bdrv_pread) {
int ret, len;
return -ENOMEDIUM;
if (bs->read_only)
return -EACCES;
+ if (bdrv_check_request(bs, sector_num, nb_sectors))
+ return -EIO;
+
if (drv->bdrv_pwrite) {
int ret, len, count = 0;
len = nb_sectors * 512;
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);
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);
QEMUIOVector *iov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
{
+ if (bdrv_check_request(bs, sector_num, nb_sectors))
+ return NULL;
+
return bdrv_aio_rw_vector(bs, sector_num, iov, nb_sectors,
cb, opaque, 0);
}
QEMUIOVector *iov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
{
+ if (bdrv_check_request(bs, sector_num, nb_sectors))
+ return NULL;
+
return bdrv_aio_rw_vector(bs, sector_num, iov, nb_sectors,
cb, opaque, 1);
}
if (!drv)
return NULL;
+ if (bdrv_check_request(bs, sector_num, nb_sectors))
+ return NULL;
ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
return NULL;
if (bs->read_only)
return NULL;
+ if (bdrv_check_request(bs, sector_num, nb_sectors))
+ return NULL;
ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);