We can cancel I/O requests safely if they are not sent to the servers. Signed-off-by: MORITA Kazutaka <morita.kazut...@lab.ntt.co.jp> --- block/sheepdog.c | 37 +++++++++++++++++++++++++++++++++++++ 1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/block/sheepdog.c b/block/sheepdog.c index cedf806..ed98701 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -421,6 +421,43 @@ static void sd_finish_aiocb(SheepdogAIOCB *acb) static void sd_aio_cancel(BlockDriverAIOCB *blockacb) { SheepdogAIOCB *acb = (SheepdogAIOCB *)blockacb; + BDRVSheepdogState *s = blockacb->bs->opaque; + AIOReq *areq, *next, *oldest_send_req = NULL; + + if (acb->bh) { + /* + * sd_readv_writev_bh_cb() is not called yet, so we can + * release this safely + */ + qemu_bh_delete(acb->bh); + acb->bh = NULL; + qemu_aio_release(acb); + return; + } + + QLIST_FOREACH(areq, &s->outstanding_aio_head, outstanding_aio_siblings) { + if (areq->state == AIO_SEND_OBJREQ) { + oldest_send_req = areq; + } + } + + QLIST_FOREACH_SAFE(areq, &s->outstanding_aio_head, + outstanding_aio_siblings, next) { + if (areq->state == AIO_RECV_OBJREQ) { + continue; + } + if (areq->state == AIO_SEND_OBJREQ && areq == oldest_send_req) { + /* the oldest AIO_SEND_OBJREQ request could be being sent */ + continue; + } + free_aio_req(s, areq); + } + + if (QLIST_EMPTY(&acb->aioreq_head)) { + /* there is no outstanding request */ + qemu_aio_release(acb); + return; + } /* * Sheepdog cannot cancel the requests which are already sent to -- 1.5.6.5