mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-15 10:10:13 +00:00
handle read outside the backing file
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2093 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
1aacf3489b
commit
a946592212
@ -696,11 +696,26 @@ static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* handle reading after the end of the backing file */
|
||||||
|
static int backing_read1(BlockDriverState *bs,
|
||||||
|
int64_t sector_num, uint8_t *buf, int nb_sectors)
|
||||||
|
{
|
||||||
|
int n1;
|
||||||
|
if ((sector_num + nb_sectors) <= bs->total_sectors)
|
||||||
|
return nb_sectors;
|
||||||
|
if (sector_num >= bs->total_sectors)
|
||||||
|
n1 = 0;
|
||||||
|
else
|
||||||
|
n1 = bs->total_sectors - sector_num;
|
||||||
|
memset(buf + n1 * 512, 0, 512 * (nb_sectors - n1));
|
||||||
|
return n1;
|
||||||
|
}
|
||||||
|
|
||||||
static int qcow_read(BlockDriverState *bs, int64_t sector_num,
|
static int qcow_read(BlockDriverState *bs, int64_t sector_num,
|
||||||
uint8_t *buf, int nb_sectors)
|
uint8_t *buf, int nb_sectors)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int ret, index_in_cluster, n;
|
int ret, index_in_cluster, n, n1;
|
||||||
uint64_t cluster_offset;
|
uint64_t cluster_offset;
|
||||||
|
|
||||||
while (nb_sectors > 0) {
|
while (nb_sectors > 0) {
|
||||||
@ -712,9 +727,12 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
|
|||||||
if (!cluster_offset) {
|
if (!cluster_offset) {
|
||||||
if (bs->backing_hd) {
|
if (bs->backing_hd) {
|
||||||
/* read from the base image */
|
/* read from the base image */
|
||||||
ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
|
n1 = backing_read1(bs->backing_hd, sector_num, buf, n);
|
||||||
|
if (n1 > 0) {
|
||||||
|
ret = bdrv_read(bs->backing_hd, sector_num, buf, n1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
memset(buf, 0, 512 * n);
|
memset(buf, 0, 512 * n);
|
||||||
}
|
}
|
||||||
@ -815,7 +833,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
|
|||||||
BlockDriverState *bs = acb->bs;
|
BlockDriverState *bs = acb->bs;
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
QCowAIOCB *acb1 = acb->opaque;
|
QCowAIOCB *acb1 = acb->opaque;
|
||||||
int index_in_cluster;
|
int index_in_cluster, n1;
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fail:
|
fail:
|
||||||
@ -859,10 +877,16 @@ static void qcow_aio_read_cb(void *opaque, int ret)
|
|||||||
if (!acb1->cluster_offset) {
|
if (!acb1->cluster_offset) {
|
||||||
if (bs->backing_hd) {
|
if (bs->backing_hd) {
|
||||||
/* read from the base image */
|
/* read from the base image */
|
||||||
|
n1 = backing_read1(bs->backing_hd, acb1->sector_num,
|
||||||
|
acb1->buf, acb1->n);
|
||||||
|
if (n1 > 0) {
|
||||||
ret = bdrv_aio_read(acb1->backing_hd_aiocb, acb1->sector_num,
|
ret = bdrv_aio_read(acb1->backing_hd_aiocb, acb1->sector_num,
|
||||||
acb1->buf, acb1->n, qcow_aio_read_cb, acb);
|
acb1->buf, n1, qcow_aio_read_cb, acb);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
} else {
|
||||||
|
goto redo;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Note: in this case, no need to wait */
|
/* Note: in this case, no need to wait */
|
||||||
memset(acb1->buf, 0, 512 * acb1->n);
|
memset(acb1->buf, 0, 512 * acb1->n);
|
||||||
|
Loading…
Reference in New Issue
Block a user