xen/ioemu-qcow2-multiblock-aio.patch

109 lines
3.9 KiB
Diff
Raw Normal View History

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,