]> git.proxmox.com Git - mirror_qemu.git/blobdiff - block/win32-aio.c
include/block: Untangle inclusion loops
[mirror_qemu.git] / block / win32-aio.c
index 46a5db78cc3dc5a22c4eff0e7d09fb5fd55b4485..ee87d6048f3a9cbb1a728f00dcf699b6df3dbd2b 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "qemu-common.h"
+
+#include "qemu/osdep.h"
 #include "qemu/timer.h"
+#include "block/block-io.h"
 #include "block/block_int.h"
-#include "qemu/module.h"
-#include "qemu-common.h"
 #include "block/aio.h"
-#include "raw-aio.h"
+#include "block/raw-aio.h"
 #include "qemu/event_notifier.h"
+#include "qemu/iov.h"
+#include "qemu/memalign.h"
 #include <windows.h>
 #include <winioctl.h>
 
@@ -40,10 +42,11 @@ struct QEMUWin32AIOState {
     HANDLE hIOCP;
     EventNotifier e;
     int count;
+    AioContext *aio_ctx;
 };
 
 typedef struct QEMUWin32AIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     struct QEMUWin32AIOState *ctx;
     int nbytes;
     OVERLAPPED ov;
@@ -80,20 +83,13 @@ static void win32_aio_process_completion(QEMUWin32AIOState *s,
     if (!waiocb->is_linear) {
         if (ret == 0 && waiocb->is_read) {
             QEMUIOVector *qiov = waiocb->qiov;
-            char *p = waiocb->buf;
-            int i;
-
-            for (i = 0; i < qiov->niov; ++i) {
-                memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
-                p += qiov->iov[i].iov_len;
-            }
-            g_free(waiocb->buf);
+            iov_from_buf(qiov->iov, qiov->niov, 0, waiocb->buf, qiov->size);
         }
+        qemu_vfree(waiocb->buf);
     }
 
-
     waiocb->common.cb(waiocb->common.opaque, ret);
-    qemu_aio_release(waiocb);
+    qemu_aio_unref(waiocb);
 }
 
 static void win32_aio_completion_cb(EventNotifier *e)
@@ -111,55 +107,30 @@ static void win32_aio_completion_cb(EventNotifier *e)
     }
 }
 
-static int win32_aio_flush_cb(EventNotifier *e)
-{
-    QEMUWin32AIOState *s = container_of(e, QEMUWin32AIOState, e);
-
-    return (s->count > 0) ? 1 : 0;
-}
-
-static void win32_aio_cancel(BlockDriverAIOCB *blockacb)
-{
-    QEMUWin32AIOCB *waiocb = (QEMUWin32AIOCB *)blockacb;
-
-    /*
-     * CancelIoEx is only supported in Vista and newer.  For now, just
-     * wait for completion.
-     */
-    while (!HasOverlappedIoCompleted(&waiocb->ov)) {
-        qemu_aio_wait();
-    }
-}
-
 static const AIOCBInfo win32_aiocb_info = {
     .aiocb_size         = sizeof(QEMUWin32AIOCB),
-    .cancel             = win32_aio_cancel,
 };
 
-BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
+BlockAIOCB *win32_aio_submit(BlockDriverState *bs,
         QEMUWin32AIOState *aio, HANDLE hfile,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque, int type)
+        uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
+        BlockCompletionFunc *cb, void *opaque, int type)
 {
     struct QEMUWin32AIOCB *waiocb;
-    uint64_t offset = sector_num * 512;
     DWORD rc;
 
     waiocb = qemu_aio_get(&win32_aiocb_info, bs, cb, opaque);
-    waiocb->nbytes = nb_sectors * 512;
+    waiocb->nbytes = bytes;
     waiocb->qiov = qiov;
     waiocb->is_read = (type == QEMU_AIO_READ);
 
     if (qiov->niov > 1) {
-        waiocb->buf = qemu_blockalign(bs, qiov->size);
+        waiocb->buf = qemu_try_blockalign(bs, qiov->size);
+        if (waiocb->buf == NULL) {
+            goto out;
+        }
         if (type & QEMU_AIO_WRITE) {
-            char *p = waiocb->buf;
-            int i;
-
-            for (i = 0; i < qiov->niov; ++i) {
-                memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
-                p += qiov->iov[i].iov_len;
-            }
+            iov_to_buf(qiov->iov, qiov->niov, 0, waiocb->buf, qiov->size);
         }
         waiocb->is_linear = false;
     } else {
@@ -186,7 +157,8 @@ BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
 
 out_dec_count:
     aio->count--;
-    qemu_aio_release(waiocb);
+out:
+    qemu_aio_unref(waiocb);
     return NULL;
 }
 
@@ -199,6 +171,21 @@ int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile)
     }
 }
 
+void win32_aio_detach_aio_context(QEMUWin32AIOState *aio,
+                                  AioContext *old_context)
+{
+    aio_set_event_notifier(old_context, &aio->e, false, NULL, NULL, NULL);
+    aio->aio_ctx = NULL;
+}
+
+void win32_aio_attach_aio_context(QEMUWin32AIOState *aio,
+                                  AioContext *new_context)
+{
+    aio->aio_ctx = new_context;
+    aio_set_event_notifier(new_context, &aio->e, false,
+                           win32_aio_completion_cb, NULL, NULL);
+}
+
 QEMUWin32AIOState *win32_aio_init(void)
 {
     QEMUWin32AIOState *s;
@@ -213,9 +200,6 @@ QEMUWin32AIOState *win32_aio_init(void)
         goto out_close_efd;
     }
 
-    qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb,
-                                win32_aio_flush_cb);
-
     return s;
 
 out_close_efd:
@@ -224,3 +208,11 @@ out_free_state:
     g_free(s);
     return NULL;
 }
+
+void win32_aio_cleanup(QEMUWin32AIOState *aio)
+{
+    assert(!aio->aio_ctx);
+    CloseHandle(aio->hIOCP);
+    event_notifier_cleanup(&aio->e);
+    g_free(aio);
+}