109 lines
3.9 KiB
Diff
109 lines
3.9 KiB
Diff
Index: xen-3.3.1-testing/tools/ioemu-remote/block-qcow2.c
|
|
===================================================================
|
|
--- xen-3.3.1-testing.orig/tools/ioemu-remote/block-qcow2.c
|
|
+++ xen-3.3.1-testing/tools/ioemu-remote/block-qcow2.c
|
|
@@ -808,6 +808,8 @@ static void qcow_aio_read_cb(void *opaqu
|
|
BlockDriverState *bs = acb->common.bs;
|
|
BDRVQcowState *s = bs->opaque;
|
|
int index_in_cluster, n1;
|
|
+ uint64_t next;
|
|
+ int n;
|
|
|
|
acb->hd_aiocb = NULL;
|
|
if (ret < 0) {
|
|
@@ -846,11 +848,22 @@ static void qcow_aio_read_cb(void *opaqu
|
|
acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
|
|
0, 0, 0, 0);
|
|
index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
|
|
- acb->n = s->cluster_sectors - index_in_cluster;
|
|
- if (acb->n > acb->nb_sectors)
|
|
- acb->n = acb->nb_sectors;
|
|
|
|
if (!acb->cluster_offset) {
|
|
+ /* seek how many clusters we must read from the base image */
|
|
+ n = s->cluster_sectors;
|
|
+ while (n < acb->nb_sectors + index_in_cluster) {
|
|
+ next = get_cluster_offset(bs, (acb->sector_num + n) << 9,
|
|
+ 0, 0, 0, 0);
|
|
+ if (next)
|
|
+ break;
|
|
+ n += s->cluster_sectors;
|
|
+ }
|
|
+ n -= index_in_cluster;
|
|
+ if (n > acb->nb_sectors)
|
|
+ n = acb->nb_sectors;
|
|
+ acb->n = n;
|
|
+
|
|
if (bs->backing_hd) {
|
|
/* read from the base image */
|
|
n1 = backing_read1(bs->backing_hd, acb->sector_num,
|
|
@@ -869,6 +882,9 @@ static void qcow_aio_read_cb(void *opaqu
|
|
goto redo;
|
|
}
|
|
} else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
|
|
+ acb->n = s->cluster_sectors - index_in_cluster;
|
|
+ if (acb->n > acb->nb_sectors)
|
|
+ acb->n = acb->nb_sectors;
|
|
/* add AIO support for compressed blocks ? */
|
|
if (decompress_cluster(s, acb->cluster_offset) < 0)
|
|
goto fail;
|
|
@@ -880,6 +896,22 @@ static void qcow_aio_read_cb(void *opaqu
|
|
ret = -EIO;
|
|
goto fail;
|
|
}
|
|
+
|
|
+ /* seek how many clusters we can read */
|
|
+
|
|
+ n = s->cluster_sectors;
|
|
+ while (n < acb->nb_sectors + index_in_cluster) {
|
|
+ next = get_cluster_offset(bs, (acb->sector_num + n) << 9,
|
|
+ 0, 0, 0, 0);
|
|
+ if (next != acb->cluster_offset + (n << 9))
|
|
+ break;
|
|
+ n += s->cluster_sectors;
|
|
+ }
|
|
+ n -= index_in_cluster;
|
|
+ if (n > acb->nb_sectors)
|
|
+ n = acb->nb_sectors;
|
|
+ acb->n = n;
|
|
+
|
|
acb->hd_aiocb = bdrv_aio_read(s->hd,
|
|
(acb->cluster_offset >> 9) + index_in_cluster,
|
|
acb->buf, acb->n, qcow_aio_read_cb, acb);
|
|
@@ -928,6 +960,9 @@ static void qcow_aio_write_cb(void *opaq
|
|
int index_in_cluster;
|
|
uint64_t cluster_offset;
|
|
const uint8_t *src_buf;
|
|
+ uint64_t next;
|
|
+ int n;
|
|
+ int alloc;
|
|
|
|
acb->hd_aiocb = NULL;
|
|
|
|
@@ -972,6 +1007,25 @@ static void qcow_aio_write_cb(void *opaq
|
|
acb->n, 1, &s->aes_encrypt_key);
|
|
src_buf = acb->cluster_data;
|
|
} else {
|
|
+
|
|
+ /* seek how many clusters we can write */
|
|
+
|
|
+ n = s->cluster_sectors;
|
|
+ while(n < acb->nb_sectors + index_in_cluster) {
|
|
+ alloc = s->cluster_sectors;
|
|
+ if (n + alloc > acb->nb_sectors + index_in_cluster)
|
|
+ alloc = acb->nb_sectors + index_in_cluster - n;
|
|
+ next = get_cluster_offset(bs, (acb->sector_num + n) << 9,
|
|
+ 1, 0, 0, alloc);
|
|
+ if (next != cluster_offset + (n << 9))
|
|
+ break;
|
|
+ n += alloc;
|
|
+ }
|
|
+ n -= index_in_cluster;
|
|
+ if (n > acb->nb_sectors)
|
|
+ n = acb->nb_sectors;
|
|
+ acb->n = n;
|
|
+
|
|
src_buf = acb->buf;
|
|
}
|
|
acb->hd_aiocb = bdrv_aio_write(s->hd,
|