Factor out the cancellation submission part in iscsi_aio_cancel, which is all what is needed for .cancel_async.
The cb passed to iscsi_task_mgmt_abort_task_async, iscsi_abort_task_cb, will be called later, so for iscsi_bh_cb. In iscsi_bh_cb, acb->canceled is not set if canceled by .cancel_async, so the completion cb is also called. Signed-off-by: Fam Zheng <f...@redhat.com> --- block/iscsi.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 2c9cfc1..8b27a5c 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -121,6 +121,8 @@ iscsi_bh_cb(void *p) acb->buf = NULL; if (acb->canceled == 0) { + /* Either normally completed or cancelled by iscsi_aio_cancel_async, + * let's call the cb. */ acb->common.cb(acb->common.opaque, acb->status); } @@ -231,7 +233,7 @@ iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data, } static void -iscsi_aio_cancel(BlockDriverAIOCB *blockacb) +iscsi_aio_cancel_async(BlockDriverAIOCB *blockacb) { IscsiAIOCB *acb = (IscsiAIOCB *)blockacb; IscsiLun *iscsilun = acb->iscsilun; @@ -240,12 +242,21 @@ iscsi_aio_cancel(BlockDriverAIOCB *blockacb) return; } - acb->canceled = 1; - /* send a task mgmt call to the target to cancel the task on the target */ iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task, iscsi_abort_task_cb, acb); +} + +static void +iscsi_aio_cancel(BlockDriverAIOCB *blockacb) +{ + IscsiAIOCB *acb = (IscsiAIOCB *)blockacb; + IscsiLun *iscsilun = acb->iscsilun; + + iscsi_aio_cancel_async(blockacb); + + acb->canceled = 1; while (acb->status == -EINPROGRESS) { aio_poll(iscsilun->aio_context, true); } @@ -254,6 +265,7 @@ iscsi_aio_cancel(BlockDriverAIOCB *blockacb) static const AIOCBInfo iscsi_aiocb_info = { .aiocb_size = sizeof(IscsiAIOCB), .cancel = iscsi_aio_cancel, + .cancel_async = iscsi_aio_cancel_async, }; -- 2.0.3