summaryrefslogtreecommitdiff
path: root/block-raw.c
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-08-07 02:38:06 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-08-07 02:38:06 +0000
commitce1a14dc0d94cf85393356f56f197c5e8b6a7f60 (patch)
treeb7c395f3494275bdb05f8c7ce54740325d4ac9ae /block-raw.c
parent51d6bae7a8d7a359d79004c586be352cd924d75f (diff)
downloadqemu-ce1a14dc0d94cf85393356f56f197c5e8b6a7f60.tar.gz
Dynamically allocate AIO Completion Blocks.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2098 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'block-raw.c')
-rw-r--r--block-raw.c280
1 files changed, 139 insertions, 141 deletions
diff --git a/block-raw.c b/block-raw.c
index adb3d39add..a64564dc76 100644
--- a/block-raw.c
+++ b/block-raw.c
@@ -200,13 +200,13 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset,
/* Unix AOP using POSIX AIO */
typedef struct RawAIOCB {
+ BlockDriverAIOCB common;
struct aiocb aiocb;
- int busy; /* only used for debugging */
- BlockDriverAIOCB *next;
+ struct RawAIOCB *next;
} RawAIOCB;
static int aio_sig_num = SIGUSR2;
-static BlockDriverAIOCB *first_aio; /* AIO issued */
+static RawAIOCB *first_aio; /* AIO issued */
static int aio_initialized = 0;
static void aio_signal_handler(int signum)
@@ -249,8 +249,7 @@ void qemu_aio_init(void)
void qemu_aio_poll(void)
{
- BlockDriverAIOCB *acb, **pacb;
- RawAIOCB *acb1;
+ RawAIOCB *acb, **pacb;
int ret;
for(;;) {
@@ -259,17 +258,16 @@ void qemu_aio_poll(void)
acb = *pacb;
if (!acb)
goto the_end;
- acb1 = acb->opaque;
- ret = aio_error(&acb1->aiocb);
+ ret = aio_error(&acb->aiocb);
if (ret == ECANCELED) {
/* remove the request */
- acb1->busy = 0;
- *pacb = acb1->next;
+ *pacb = acb->next;
+ qemu_aio_release(acb);
} else if (ret != EINPROGRESS) {
/* end of aio */
if (ret == 0) {
- ret = aio_return(&acb1->aiocb);
- if (ret == acb1->aiocb.aio_nbytes)
+ ret = aio_return(&acb->aiocb);
+ if (ret == acb->aiocb.aio_nbytes)
ret = 0;
else
ret = -1;
@@ -277,13 +275,13 @@ void qemu_aio_poll(void)
ret = -ret;
}
/* remove the request */
- acb1->busy = 0;
- *pacb = acb1->next;
+ *pacb = acb->next;
/* call the callback */
- acb->cb(acb->cb_opaque, ret);
+ acb->common.cb(acb->common.opaque, ret);
+ qemu_aio_release(acb);
break;
} else {
- pacb = &acb1->next;
+ pacb = &acb->next;
}
}
}
@@ -324,70 +322,70 @@ void qemu_aio_wait_end(void)
sigprocmask(SIG_SETMASK, &wait_oset, NULL);
}
-static int raw_aio_new(BlockDriverAIOCB *acb)
+static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
+ int64_t sector_num, uint8_t *buf, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
{
- RawAIOCB *acb1;
- BDRVRawState *s = acb->bs->opaque;
-
- acb1 = qemu_mallocz(sizeof(RawAIOCB));
- if (!acb1)
- return -1;
- acb->opaque = acb1;
- acb1->aiocb.aio_fildes = s->fd;
- acb1->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
- acb1->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- return 0;
+ BDRVRawState *s = bs->opaque;
+ RawAIOCB *acb;
+
+ acb = qemu_aio_get(bs, cb, opaque);
+ if (!acb)
+ return NULL;
+ acb->aiocb.aio_fildes = s->fd;
+ acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
+ acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
+ acb->aiocb.aio_buf = buf;
+ acb->aiocb.aio_nbytes = nb_sectors * 512;
+ acb->aiocb.aio_offset = sector_num * 512;
+ acb->next = first_aio;
+ first_aio = acb;
+ return acb;
}
-static int raw_aio_read(BlockDriverAIOCB *acb, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
+static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
+ int64_t sector_num, uint8_t *buf, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
{
- RawAIOCB *acb1 = acb->opaque;
+ RawAIOCB *acb;
- assert(acb1->busy == 0);
- acb1->busy = 1;
- acb1->aiocb.aio_buf = buf;
- acb1->aiocb.aio_nbytes = nb_sectors * 512;
- acb1->aiocb.aio_offset = sector_num * 512;
- acb1->next = first_aio;
- first_aio = acb;
- if (aio_read(&acb1->aiocb) < 0) {
- acb1->busy = 0;
- return -errno;
+ acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
+ if (!acb)
+ return NULL;
+ if (aio_read(&acb->aiocb) < 0) {
+ qemu_aio_release(acb);
+ return NULL;
}
- return 0;
+ return &acb->common;
}
-static int raw_aio_write(BlockDriverAIOCB *acb, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
+static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
+ int64_t sector_num, const uint8_t *buf, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
{
- RawAIOCB *acb1 = acb->opaque;
+ RawAIOCB *acb;
- assert(acb1->busy == 0);
- acb1->busy = 1;
- acb1->aiocb.aio_buf = (uint8_t *)buf;
- acb1->aiocb.aio_nbytes = nb_sectors * 512;
- acb1->aiocb.aio_offset = sector_num * 512;
- acb1->next = first_aio;
- first_aio = acb;
- if (aio_write(&acb1->aiocb) < 0) {
- acb1->busy = 0;
- return -errno;
+ acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
+ if (!acb)
+ return NULL;
+ if (aio_write(&acb->aiocb) < 0) {
+ qemu_aio_release(acb);
+ return NULL;
}
- return 0;
+ return &acb->common;
}
-static void raw_aio_cancel(BlockDriverAIOCB *acb)
+static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
{
- RawAIOCB *acb1 = acb->opaque;
int ret;
- BlockDriverAIOCB **pacb;
+ RawAIOCB *acb = (RawAIOCB *)blockacb;
+ RawAIOCB **pacb;
- ret = aio_cancel(acb1->aiocb.aio_fildes, &acb1->aiocb);
+ ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
if (ret == AIO_NOTCANCELED) {
/* fail safe: if the aio could not be canceled, we wait for
it */
- while (aio_error(&acb1->aiocb) == EINPROGRESS);
+ while (aio_error(&acb->aiocb) == EINPROGRESS);
}
/* remove the callback from the queue */
@@ -396,22 +394,14 @@ static void raw_aio_cancel(BlockDriverAIOCB *acb)
if (*pacb == NULL) {
break;
} else if (*pacb == acb) {
- acb1->busy = 0;
- *pacb = acb1->next;
+ *pacb = acb->next;
+ qemu_aio_release(acb);
break;
}
- acb1 = (*pacb)->opaque;
- pacb = &acb1->next;
+ pacb = &acb->next;
}
}
-static void raw_aio_delete(BlockDriverAIOCB *acb)
-{
- RawAIOCB *acb1 = acb->opaque;
- raw_aio_cancel(acb);
- qemu_free(acb1);
-}
-
static void raw_close(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
@@ -508,11 +498,10 @@ BlockDriver bdrv_raw = {
raw_create,
raw_flush,
- .bdrv_aio_new = raw_aio_new,
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
.bdrv_aio_cancel = raw_aio_cancel,
- .bdrv_aio_delete = raw_aio_delete,
+ .aiocb_size = sizeof(RawAIOCB),
.protocol_name = "file",
.bdrv_pread = raw_pread,
.bdrv_pwrite = raw_pwrite,
@@ -530,6 +519,7 @@ typedef struct BDRVRawState {
} BDRVRawState;
typedef struct RawAIOCB {
+ BlockDriverAIOCB common;
HANDLE hEvent;
OVERLAPPED ov;
int count;
@@ -574,6 +564,7 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
{
BDRVRawState *s = bs->opaque;
int access_flags, create_flags;
+ DWORD overlapped;
if ((flags & BDRV_O_ACCESS) == O_RDWR) {
access_flags = GENERIC_READ | GENERIC_WRITE;
@@ -585,9 +576,14 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
} else {
create_flags = OPEN_EXISTING;
}
+#ifdef QEMU_TOOL
+ overlapped = 0;
+#else
+ overlapped = FILE_FLAG_OVERLAPPED;
+#endif
s->hfile = CreateFile(filename, access_flags,
FILE_SHARE_READ, NULL,
- create_flags, FILE_FLAG_OVERLAPPED, 0);
+ create_flags, overlapped, 0);
if (s->hfile == INVALID_HANDLE_VALUE)
return -1;
return 0;
@@ -637,104 +633,107 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset,
return ret_count;
}
-static int raw_aio_new(BlockDriverAIOCB *acb)
-{
- RawAIOCB *acb1;
-
- acb1 = qemu_mallocz(sizeof(RawAIOCB));
- if (!acb1)
- return -ENOMEM;
- acb->opaque = acb1;
- acb1->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!acb1->hEvent)
- return -ENOMEM;
- return 0;
-}
#ifndef QEMU_TOOL
static void raw_aio_cb(void *opaque)
{
- BlockDriverAIOCB *acb = opaque;
- BlockDriverState *bs = acb->bs;
+ RawAIOCB *acb = opaque;
+ BlockDriverState *bs = acb->common.bs;
BDRVRawState *s = bs->opaque;
- RawAIOCB *acb1 = acb->opaque;
DWORD ret_count;
int ret;
- ret = GetOverlappedResult(s->hfile, &acb1->ov, &ret_count, TRUE);
- if (!ret || ret_count != acb1->count) {
- acb->cb(acb->cb_opaque, -EIO);
+ ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
+ if (!ret || ret_count != acb->count) {
+ acb->common.cb(acb->common.opaque, -EIO);
} else {
- acb->cb(acb->cb_opaque, 0);
+ acb->common.cb(acb->common.opaque, 0);
}
}
#endif
-static int raw_aio_read(BlockDriverAIOCB *acb, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
+
+static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
+ int64_t sector_num, uint8_t *buf, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
{
- BlockDriverState *bs = acb->bs;
- BDRVRawState *s = bs->opaque;
- RawAIOCB *acb1 = acb->opaque;
- int ret;
+ RawAIOCB *acb;
int64_t offset;
- memset(&acb1->ov, 0, sizeof(acb1->ov));
+ acb = qemu_aio_get(bs, cb, opaque);
+ if (acb->hEvent) {
+ acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (!acb->hEvent) {
+ qemu_aio_release(acb);
+ return NULL;
+ }
+ }
+ memset(&acb->ov, 0, sizeof(acb->ov));
offset = sector_num * 512;
- acb1->ov.Offset = offset;
- acb1->ov.OffsetHigh = offset >> 32;
- acb1->ov.hEvent = acb1->hEvent;
- acb1->count = nb_sectors * 512;
+ acb->ov.Offset = offset;
+ acb->ov.OffsetHigh = offset >> 32;
+ acb->ov.hEvent = acb->hEvent;
+ acb->count = nb_sectors * 512;
#ifndef QEMU_TOOL
- qemu_add_wait_object(acb1->ov.hEvent, raw_aio_cb, acb);
+ qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
#endif
- ret = ReadFile(s->hfile, buf, acb1->count, NULL, &acb1->ov);
- if (!ret)
- return -EIO;
- return 0;
+ return acb;
}
-static int raw_aio_write(BlockDriverAIOCB *acb, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
+static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
+ int64_t sector_num, uint8_t *buf, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
{
- BlockDriverState *bs = acb->bs;
BDRVRawState *s = bs->opaque;
- RawAIOCB *acb1 = acb->opaque;
+ RawAIOCB *acb;
int ret;
- int64_t offset;
- memset(&acb1->ov, 0, sizeof(acb1->ov));
- offset = sector_num * 512;
- acb1->ov.Offset = offset;
- acb1->ov.OffsetHigh = offset >> 32;
- acb1->ov.hEvent = acb1->hEvent;
- acb1->count = nb_sectors * 512;
-#ifndef QEMU_TOOL
- qemu_add_wait_object(acb1->ov.hEvent, raw_aio_cb, acb);
+ acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
+ if (!acb)
+ return NULL;
+ ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
+ if (!ret) {
+ qemu_aio_release(acb);
+ return NULL;
+ }
+#ifdef QEMU_TOOL
+ qemu_aio_release(acb);
#endif
- ret = ReadFile(s->hfile, buf, acb1->count, NULL, &acb1->ov);
- if (!ret)
- return -EIO;
- return 0;
+ return (BlockDriverAIOCB *)acb;
}
-static void raw_aio_cancel(BlockDriverAIOCB *acb)
+static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
+ int64_t sector_num, uint8_t *buf, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
{
- BlockDriverState *bs = acb->bs;
BDRVRawState *s = bs->opaque;
-#ifndef QEMU_TOOL
- RawAIOCB *acb1 = acb->opaque;
+ RawAIOCB *acb;
+ int ret;
- qemu_del_wait_object(acb1->ov.hEvent, raw_aio_cb, acb);
+ acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
+ if (!acb)
+ return NULL;
+ ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
+ if (!ret) {
+ qemu_aio_release(acb);
+ return NULL;
+ }
+#ifdef QEMU_TOOL
+ qemu_aio_release(acb);
#endif
- /* XXX: if more than one async I/O it is not correct */
- CancelIo(s->hfile);
+ return (BlockDriverAIOCB *)acb;
}
-static void raw_aio_delete(BlockDriverAIOCB *acb)
+static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
{
- RawAIOCB *acb1 = acb->opaque;
- raw_aio_cancel(acb);
- CloseHandle(acb1->hEvent);
- qemu_free(acb1);
+#ifndef QEMU_TOOL
+ RawAIOCB *acb = (RawAIOCB *)blockacb;
+ BlockDriverState *bs = acb->common.bs;
+ BDRVRawState *s = bs->opaque;
+
+ qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
+ /* XXX: if more than one async I/O it is not correct */
+ CancelIo(s->hfile);
+ qemu_aio_release(acb);
+#endif
}
static void raw_flush(BlockDriverState *bs)
@@ -823,11 +822,10 @@ BlockDriver bdrv_raw = {
raw_flush,
#if 0
- .bdrv_aio_new = raw_aio_new,
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
.bdrv_aio_cancel = raw_aio_cancel,
- .bdrv_aio_delete = raw_aio_delete,
+ .aiocb_size = sizeof(RawAIOCB);
#endif
.protocol_name = "file",
.bdrv_pread = raw_pread,