Don't delete the export until all inflight I/Os completed. Otherwise, it might lead to a use-after-free.
Fixes: cc241b5505b2 ("vduse-blk: Implement vduse-blk export") Signed-off-by: Xie Yongji <xieyon...@bytedance.com> --- block/export/vduse-blk.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/block/export/vduse-blk.c b/block/export/vduse-blk.c index c3a89894ae..251d73c841 100644 --- a/block/export/vduse-blk.c +++ b/block/export/vduse-blk.c @@ -31,6 +31,7 @@ typedef struct VduseBlkExport { VduseDev *dev; uint16_t num_queues; char *recon_file; + unsigned int inflight; } VduseBlkExport; typedef struct VduseBlkReq { @@ -38,6 +39,18 @@ typedef struct VduseBlkReq { VduseVirtq *vq; } VduseBlkReq; +static void vduse_blk_inflight_inc(VduseBlkExport *vblk_exp) +{ + vblk_exp->inflight++; +} + +static void vduse_blk_inflight_dec(VduseBlkExport *vblk_exp) +{ + if (--vblk_exp->inflight == 0) { + aio_wait_kick(); + } +} + static void vduse_blk_req_complete(VduseBlkReq *req, size_t in_len) { vduse_queue_push(req->vq, &req->elem, in_len); @@ -68,10 +81,13 @@ static void coroutine_fn vduse_blk_virtio_process_req(void *opaque) } vduse_blk_req_complete(req, in_len); + vduse_blk_inflight_dec(vblk_exp); } static void vduse_blk_vq_handler(VduseDev *dev, VduseVirtq *vq) { + VduseBlkExport *vblk_exp = vduse_dev_get_priv(dev); + while (1) { VduseBlkReq *req; @@ -83,6 +99,8 @@ static void vduse_blk_vq_handler(VduseDev *dev, VduseVirtq *vq) Coroutine *co = qemu_coroutine_create(vduse_blk_virtio_process_req, req); + + vduse_blk_inflight_inc(vblk_exp); qemu_coroutine_enter(co); } } @@ -168,6 +186,8 @@ static void vduse_blk_detach_ctx(VduseBlkExport *vblk_exp) } aio_set_fd_handler(vblk_exp->export.ctx, vduse_dev_get_fd(vblk_exp->dev), true, NULL, NULL, NULL, NULL, NULL); + + AIO_WAIT_WHILE(vblk_exp->export.ctx, vblk_exp->inflight > 0); } @@ -332,7 +352,9 @@ static void vduse_blk_exp_request_shutdown(BlockExport *exp) { VduseBlkExport *vblk_exp = container_of(exp, VduseBlkExport, export); + aio_context_acquire(vblk_exp->export.ctx); vduse_blk_detach_ctx(vblk_exp); + aio_context_acquire(vblk_exp->export.ctx); } const BlockExportDriver blk_exp_vduse_blk = { -- 2.20.1