When retiring a command test for a free_callback associated with their buffer. If there is one call it. This allows language bindings to use this mechanism to automatically decrement a reference to the persistent buffer (note: this patch does not implement this). The vast majority of this change is simply passing around the handle so we have it when we call nbd_internal_free_callback in lib/aio.c. --- generator/states-reply.c | 2 +- generator/states.c | 2 +- lib/aio.c | 10 ++++++++-- lib/handle.c | 10 +++++----- lib/internal.h | 3 ++- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/generator/states-reply.c b/generator/states-reply.c index 09adfed..389317e 100644 --- a/generator/states-reply.c +++ b/generator/states-reply.c @@ -194,7 +194,7 @@ save_reply_state (struct nbd_handle *h) h->cmds_in_flight = cmd->next; cmd->next = NULL; if (retire) - nbd_internal_retire_and_free_command (cmd); + nbd_internal_retire_and_free_command (h, cmd); else { if (h->cmds_done_tail != NULL) h->cmds_done_tail = h->cmds_done_tail->next = cmd; diff --git a/generator/states.c b/generator/states.c index 9ed57ae..a11c1d1 100644 --- a/generator/states.c +++ b/generator/states.c @@ -142,7 +142,7 @@ void abort_commands (struct nbd_handle *h, if (cmd->error == 0) cmd->error = ENOTCONN; if (retire) - nbd_internal_retire_and_free_command (cmd); + nbd_internal_retire_and_free_command (h, cmd); else { cmd->next = NULL; if (h->cmds_done_tail) diff --git a/lib/aio.c b/lib/aio.c index c141de6..1d26be9 100644 --- a/lib/aio.c +++ b/lib/aio.c @@ -29,7 +29,8 @@ /* Internal function which retires and frees a command. */ void -nbd_internal_retire_and_free_command (struct command *cmd) +nbd_internal_retire_and_free_command (struct nbd_handle *h, + struct command *cmd) { /* Free the callbacks. */ if (cmd->type == NBD_CMD_BLOCK_STATUS && cmd->cb.fn.extent) @@ -42,6 +43,11 @@ nbd_internal_retire_and_free_command (struct command *cmd) cmd->cb.completion (LIBNBD_CALLBACK_FREE, cmd->cb.user_data, NULL); + /* Free the persistent buffer if there is one and if there's an + * associated free callback. + */ + nbd_internal_free_callback (h, cmd->data); + free (cmd); } @@ -109,7 +115,7 @@ nbd_unlocked_aio_command_completed (struct nbd_handle *h, else h->cmds_done = cmd->next; - nbd_internal_retire_and_free_command (cmd); + nbd_internal_retire_and_free_command (h, cmd); /* If the command was successful, return true. */ if (error == 0) diff --git a/lib/handle.c b/lib/handle.c index ae0d196..0f50e38 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -32,13 +32,13 @@ #include "internal.h" static void -free_cmd_list (struct command *list) +free_cmd_list (struct nbd_handle *h, struct command *list) { struct command *cmd, *cmd_next; for (cmd = list; cmd != NULL; cmd = cmd_next) { cmd_next = cmd->next; - nbd_internal_retire_and_free_command (cmd); + nbd_internal_retire_and_free_command (h, cmd); } } @@ -123,9 +123,9 @@ nbd_close (struct nbd_handle *h) free (m->name); free (m); } - free_cmd_list (h->cmds_to_issue); - free_cmd_list (h->cmds_in_flight); - free_cmd_list (h->cmds_done); + free_cmd_list (h, h->cmds_to_issue); + free_cmd_list (h, h->cmds_in_flight); + free_cmd_list (h, h->cmds_done); /* Any remaining free callbacks indicate an error. */ if (h->nr_free_callbacks != 0) diff --git a/lib/internal.h b/lib/internal.h index d8b0eed..42e6921 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -288,7 +288,8 @@ struct command { }; /* aio.c */ -extern void nbd_internal_retire_and_free_command (struct command *); +extern void nbd_internal_retire_and_free_command (struct nbd_handle *, + struct command *); /* crypto.c */ extern struct socket *nbd_internal_crypto_create_session (struct nbd_handle *, struct socket *oldsock); -- 2.22.0