We're about to move calls to 'fstat' into the thread-pool to avoid blocking VCPU threads should the system call take too long.
To achieve that we first need to make sure none of its callers is holding the aio_context lock, otherwise yielding before scheduling the aiocb handler would result in a deadlock when the qemu_global_mutex is released and another thread tries to acquire the aio_context. Signed-off-by: Fabiano Rosas <faro...@suse.de> --- block/qapi.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/block/qapi.c b/block/qapi.c index ae6cd1c2ff..cd197abf1f 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -222,6 +222,26 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs, return 0; } +static int64_t bdrv_get_actual_size(BlockDriverState *bs) +{ + int64_t size; + AioContext *old_ctx = NULL; + + if (qemu_in_coroutine()) { + aio_context_release(bdrv_get_aio_context(bs)); + old_ctx = bdrv_co_enter(bs); + } + + size = bdrv_get_allocated_file_size(bs); + + if (qemu_in_coroutine() && old_ctx) { + bdrv_co_leave(bs, old_ctx); + aio_context_acquire(bdrv_get_aio_context(bs)); + } + + return size; +} + /** * Helper function for other query info functions. Store information about @bs * in @info, setting @errp on error. @@ -250,7 +270,7 @@ static void bdrv_do_query_node_info(BlockDriverState *bs, info->filename = g_strdup(bs->filename); info->format = g_strdup(bdrv_get_format_name(bs)); info->virtual_size = size; - info->actual_size = bdrv_get_allocated_file_size(bs); + info->actual_size = bdrv_get_actual_size(bs); info->has_actual_size = info->actual_size >= 0; if (bs->encrypted) { info->encrypted = true; -- 2.35.3