@@ -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 = {
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 <xieyongji@bytedance.com> --- block/export/vduse-blk.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)