@@ -79,9 +79,8 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s,
ret = -EINVAL;
}
}
-
- laiocb->common.cb(laiocb->common.opaque, ret);
}
+ laiocb->common.cb(laiocb->common.opaque, ret);
qemu_aio_release(laiocb);
}
@@ -110,6 +109,22 @@ static void qemu_laio_completion_cb(EventNotifier *e)
}
}
+static void laio_cancel_async(BlockDriverAIOCB *blockacb)
+{
+ struct qemu_laiocb *laiocb = (struct qemu_laiocb *)blockacb;
+ struct io_event event;
+ int ret;
+
+ ret = io_cancel(laiocb->ctx->ctx, &laiocb->iocb, &event);
+ laiocb->ret = -ECANCELED;
+ if (!ret) {
+ /* iocb is not cancelled, cb will be called by the event loop later */
+ return;
+ }
+
+ laiocb->common.cb(laiocb->common.opaque, laiocb->ret);
+}
+
static void laio_cancel(BlockDriverAIOCB *blockacb)
{
struct qemu_laiocb *laiocb = (struct qemu_laiocb *)blockacb;
@@ -145,6 +160,7 @@ static void laio_cancel(BlockDriverAIOCB *blockacb)
static const AIOCBInfo laio_aiocb_info = {
.aiocb_size = sizeof(struct qemu_laiocb),
.cancel = laio_cancel,
+ .cancel_async = laio_cancel_async,
};
static void ioq_init(LaioQueue *io_q)
Just call io_cancel (2), if it fails, it means the request is not canceled, so the event loop will eventually call qemu_laio_process_completion. In qemu_laio_process_completion, change to call the cb unconditionally. It is required by .cancel_async, and also acceptable by .cancel. Signed-off-by: Fam Zheng <famz@redhat.com> --- block/linux-aio.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)