Users currently lack visibility into which block exports
are utilizing specific IOThreads. This patch integrates IOThread
referencing into the BlockExport lifecycle.
- Add iothreads array and holder_name to BlockExport struct.
- Use iothread_ref_and_get_aio_context during export creation.
- Implement proper cleanup in blk_exp_add fail path and blk_exp_delete_bh.
- Support both single and multi-iothread export configurations.
This ensures IOThread 'holders' status correctly reflects active block
exports for better debugging and resource tracking.
Signed-off-by: Zhang Chen <zhangckid@gmail.com>
---
block/export/export.c | 44 +++++++++++++++++++++++++++++++++---------
include/block/export.h | 6 ++++++
2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/block/export/export.c b/block/export/export.c
index b733f269f3..636633c324 100644
--- a/block/export/export.c
+++ b/block/export/export.c
@@ -15,7 +15,6 @@
#include "block/block.h"
#include "system/block-backend.h"
-#include "system/iothread.h"
#include "block/export.h"
#include "block/fuse.h"
#include "block/nbd.h"
@@ -85,6 +84,8 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
AioContext *ctx;
AioContext **multithread_ctxs = NULL;
size_t multithread_count = 0;
+ g_autofree IOThread **local_iothreads = NULL;
+ const char *holder_name = NULL;
uint64_t perm;
int ret;
@@ -139,7 +140,11 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
goto fail;
}
- new_ctx = iothread_get_aio_context(iothread);
+ holder_name = bdrv_get_node_name(bs);
+ new_ctx = iothread_ref_and_get_aio_context(iothread, holder_name);
+ multithread_count = 1;
+ local_iothreads = g_new0(IOThread *, 1);
+ local_iothreads[0] = iothread;
/* Ignore errors with fixed-iothread=false */
set_context_errp = fixed_iothread ? errp : NULL;
@@ -163,8 +168,10 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
return NULL;
}
+ local_iothreads = g_new0(IOThread *, multithread_count);
multithread_ctxs = g_new(AioContext *, multithread_count);
i = 0;
+ holder_name = bdrv_get_node_name(bs);
for (strList *e = iothread_list; e; e = e->next) {
IOThread *iothread = iothread_by_id(e->value);
@@ -172,7 +179,9 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
error_setg(errp, "iothread \"%s\" not found", e->value);
goto fail;
}
- multithread_ctxs[i++] = iothread_get_aio_context(iothread);
+ local_iothreads[i] = iothread;
+ multithread_ctxs[i++] = iothread_ref_and_get_aio_context(iothread,
+ holder_name);
}
assert(i == multithread_count);
}
@@ -225,12 +234,15 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
assert(drv->instance_size >= sizeof(BlockExport));
exp = g_malloc0(drv->instance_size);
*exp = (BlockExport) {
- .drv = drv,
- .refcount = 1,
- .user_owned = true,
- .id = g_strdup(export->id),
- .ctx = ctx,
- .blk = blk,
+ .drv = drv,
+ .refcount = 1,
+ .user_owned = true,
+ .id = g_strdup(export->id),
+ .ctx = ctx,
+ .blk = blk,
+ .iothreads = g_steal_pointer(&local_iothreads),
+ .iothread_count = multithread_count,
+ .iothread_holder_name = g_strdup(holder_name),
};
ret = drv->create(exp, export, multithread_ctxs, multithread_count, errp);
@@ -253,6 +265,13 @@ fail:
g_free(exp->id);
g_free(exp);
}
+ if (local_iothreads) {
+ for (size_t j = 0; j < multithread_count; j++) {
+ if (local_iothreads[j]) {
+ iothread_put_aio_context(local_iothreads[j], holder_name);
+ }
+ }
+ }
g_free(multithread_ctxs);
return NULL;
}
@@ -269,6 +288,13 @@ static void blk_exp_delete_bh(void *opaque)
BlockExport *exp = opaque;
assert(exp->refcount == 0);
+ if (exp->iothreads) {
+ for (size_t i = 0; i < exp->iothread_count; i++) {
+ iothread_put_aio_context(exp->iothreads[i],
+ exp->iothread_holder_name);
+ }
+ g_free(exp->iothreads);
+ }
QLIST_REMOVE(exp, next);
exp->drv->delete(exp);
blk_set_dev_ops(exp->blk, NULL, NULL);
diff --git a/include/block/export.h b/include/block/export.h
index ca45da928c..2bb98aae31 100644
--- a/include/block/export.h
+++ b/include/block/export.h
@@ -16,6 +16,7 @@
#include "qapi/qapi-types-block-export.h"
#include "qemu/queue.h"
+#include "system/iothread.h"
typedef struct BlockExport BlockExport;
@@ -89,6 +90,11 @@ struct BlockExport {
/* List entry for block_exports */
QLIST_ENTRY(BlockExport) next;
+
+ /* The iothreads list for block_exports */
+ IOThread **iothreads;
+ size_t iothread_count;
+ char *iothread_holder_name;
};
BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp);
--
2.49.0