On 8/12/19 11:08 AM, Richard W.M. Jones wrote:
Mechanical change: Wherever we call any closure with the LIBNBD_CALLBACK_FREE function, we also call nbd_internal_free_callback with the closure's user_data. This allows calls to associate a free callback with any closure via its user_data pointer. ---
+++ b/lib/aio.c @@ -43,6 +43,10 @@ nbd_internal_retire_and_free_command (struct nbd_handle *h, cmd->cb.completion (LIBNBD_CALLBACK_FREE, cmd->cb.user_data, NULL);
+ /* Free the closures if there's an associated free callback. */ + nbd_internal_free_callback (h, cmd->cb.fn_user_data);
This calls the fn_user_data callback too many times if it was already reached. Instead, you need: if (cmd->type == NBD_CMD_BLOCK_STATUS && cmd->cb.fn.extent) { cmd->cb.fn.extent (_FREE...); nbd_internal_free_callback (h, cmd->cb.fn_user_data); } else if (cmd->type == NBD_CMD_BLOCK_READ && cmd->cb.fn.chunk) { cmd->cb.fn.chunk (_FREE...); nbd_internal_free_callback (h, cmd->cb.fn_user_data); } -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org