From: Klaus Jensen <k.jen...@samsung.com> When the DSM operation is cancelled asynchronously, we set iocb->ret to -ECANCELED. However, the callback function only checks the return value of the completed aio, which may have completed succesfully prior to the cancellation and thus the callback ends up continuing the dsm operation instead of bailing out. Fix this.
Signed-off-by: Klaus Jensen <k.jen...@samsung.com> --- hw/nvme/ctrl.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 9add74753fd8..5eee730ed0cf 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -2367,16 +2367,10 @@ static void nvme_dsm_md_cb(void *opaque, int ret) uint64_t slba; uint32_t nlb; - if (ret < 0) { - iocb->ret = ret; + if (ret < 0 || iocb->ret < 0 || !ns->lbaf.ms) { goto done; } - if (!ns->lbaf.ms) { - nvme_dsm_cb(iocb, 0); - return; - } - range = &iocb->range[iocb->idx - 1]; slba = le64_to_cpu(range->slba); nlb = le32_to_cpu(range->nlb); @@ -2389,7 +2383,6 @@ static void nvme_dsm_md_cb(void *opaque, int ret) ret = nvme_block_status_all(ns, slba, nlb, BDRV_BLOCK_ZERO); if (ret) { if (ret < 0) { - iocb->ret = ret; goto done; } @@ -2403,8 +2396,7 @@ static void nvme_dsm_md_cb(void *opaque, int ret) return; done: - iocb->aiocb = NULL; - qemu_bh_schedule(iocb->bh); + nvme_dsm_cb(iocb, ret); } static void nvme_dsm_cb(void *opaque, int ret) @@ -2420,6 +2412,8 @@ static void nvme_dsm_cb(void *opaque, int ret) if (ret < 0) { iocb->ret = ret; goto done; + } else if (iocb->ret < 0) { + goto done; } next: -- 2.36.1