The definition of functions that take a callback is changed so that
the callback and user_data are combined into a single structure, eg:
int64_t nbd_aio_pread (struct nbd_handle *h,
void *buf, size_t count, uint64_t offset,
- int (*completion_callback) (/*..*/), void *user_data,
+ nbd_completion_callback completion_callback,
uint32_t flags);
Several nbd_*_callback structures are defined. The one corresponding
to the example above is:
typedef struct {
void *user_data;
int (*callback) (unsigned valid_flag, void *user_data, int *error);
} nbd_completion_callback;
The nbd_aio_pread function can now be called using:
nbd_aio_pread (nbd, buf, sizeof buf, offset,
(nbd_completion_callback) { .callback = my_fn,
.user_data = my_data },
0);
Note that the whole structure is passed by value not by reference.
For OClosure only, a NULL callback can be passed using this macro:
nbd_aio_pread (nbd, buf, sizeof buf, offset,
NBD_NULL_CALLBACK(completion), 0);
---
docs/libnbd.pod | 27 ++++++---
examples/batched-read-write.c | 5 +-
examples/glib-main-loop.c | 6 +-
examples/strict-structured-reads.c | 3 +-
examples/threaded-reads-and-writes.c | 6 +-
generator/generator | 89 ++++++++++++++--------------
generator/states-reply-simple.c | 13 ++--
generator/states-reply-structured.c | 64 ++++++++++----------
generator/states-reply.c | 8 +--
generator/states.c | 8 +--
interop/dirty-bitmap.c | 11 +++-
interop/structured-read.c | 9 ++-
lib/aio.c | 21 ++++---
lib/debug.c | 16 ++---
lib/internal.h | 3 -
lib/rw.c | 60 ++++++++-----------
tests/aio-parallel-load.c | 6 +-
tests/aio-parallel.c | 6 +-
tests/closure-lifetimes.c | 14 +++--
tests/errors.c | 9 ++-
tests/meta-base-allocation.c | 11 +++-
tests/oldstyle.c | 6 +-
tests/server-death.c | 7 ++-
23 files changed, 226 insertions(+), 182 deletions(-)
diff --git a/docs/libnbd.pod b/docs/libnbd.pod
index b38def0..9177825 100644
--- a/docs/libnbd.pod
+++ b/docs/libnbd.pod
@@ -598,14 +598,25 @@ will use your login name):
=head1 CALLBACKS
-Some libnbd calls take function pointers (eg.
-C<nbd_set_debug_callback>, C<nbd_aio_pread>). Libnbd can call these
-functions while processing.
-
-Callbacks have an opaque C<void *user_data> pointer. This is passed
-as the second parameter to the callback. The opaque pointer is only
-used from the C API, since in other languages you can use closures to
-achieve the same outcome.
+Some libnbd calls take callbacks (eg. C<nbd_set_debug_callback>,
+C<nbd_aio_pread>). Libnbd can call these functions while processing.
+
+In the C API these libnbd calls take a structure which contains the
+function pointer and an optional opaque C<void *user_data> pointer:
+
+ nbd_aio_pread (nbd, buf, sizeof buf, offset,
+ (nbd_completion_callback) { .callback = my_fn,
+ .user_data = my_data },
+ 0);
+
+If you don't want the callback, either set C<.callback> to C<NULL> or
+use the equivalent macro C<NBD_NULL_CALLBACK()> defined in C<libnbd.h>:
+
+ nbd_aio_pread (nbd, buf, sizeof buf, offset,
+ NBD_NULL_CALLBACK(completion), 0);
+
+From other languages the structure and opaque pointer are not needed
+because you can use closures to achieve the same effect.
=head2 Callback lifetimes
diff --git a/examples/batched-read-write.c b/examples/batched-read-write.c
index 378c2e0..a6063af 100644
--- a/examples/batched-read-write.c
+++ b/examples/batched-read-write.c
@@ -53,12 +53,13 @@ try_deadlock (void *arg)
/* Issue commands. */
cookies[0] = nbd_aio_pread (nbd, in, packetsize, 0,
- NULL, NULL, 0);
+ NBD_NULL_CALLBACK(completion), 0);
if (cookies[0] == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
goto error;
}
- cookies[1] = nbd_aio_pwrite (nbd, out, packetsize, packetsize, NULL, NULL, 0);
+ cookies[1] = nbd_aio_pwrite (nbd, out, packetsize, packetsize,
+ NBD_NULL_CALLBACK(completion), 0);
if (cookies[1] == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
goto error;
diff --git a/examples/glib-main-loop.c b/examples/glib-main-loop.c
index 7b4d215..a8e8ceb 100644
--- a/examples/glib-main-loop.c
+++ b/examples/glib-main-loop.c
@@ -384,7 +384,8 @@ read_data (gpointer user_data)
if (nbd_aio_pread (gssrc->nbd, buffers[i].data,
BUFFER_SIZE, buffers[i].offset,
- finished_read, &buffers[i], 0) == -1) {
+ (nbd_completion_callback) { .callback = finished_read, .user_data =
&buffers[i] },
+ 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
@@ -428,7 +429,8 @@ write_data (gpointer user_data)
buffer->state = BUFFER_WRITING;
if (nbd_aio_pwrite (gsdest->nbd, buffer->data,
BUFFER_SIZE, buffer->offset,
- finished_write, buffer, 0) == -1) {
+ (nbd_completion_callback) { .callback = finished_write, .user_data
= buffer },
+ 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
diff --git a/examples/strict-structured-reads.c b/examples/strict-structured-reads.c
index 4bc63b8..d7c3e1b 100644
--- a/examples/strict-structured-reads.c
+++ b/examples/strict-structured-reads.c
@@ -236,7 +236,8 @@ main (int argc, char *argv[])
*d = (struct data) { .offset = offset, .count = maxsize, .flags = flags,
.remaining = r, };
if (nbd_aio_pread_structured (nbd, buf, sizeof buf, offset,
- read_chunk, d, read_verify, d,
+ (nbd_chunk_callback) { .callback = read_chunk,
.user_data = d },
+ (nbd_completion_callback) { .callback = read_verify,
.user_data = d },
flags) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
diff --git a/examples/threaded-reads-and-writes.c b/examples/threaded-reads-and-writes.c
index 7626a02..6ae1dd2 100644
--- a/examples/threaded-reads-and-writes.c
+++ b/examples/threaded-reads-and-writes.c
@@ -252,9 +252,11 @@ start_thread (void *arg)
offset = rand () % (exportsize - size);
cmd = rand () & 1;
if (cmd == 0)
- cookie = nbd_aio_pwrite (nbd, buf, size, offset, NULL, NULL, 0);
+ cookie = nbd_aio_pwrite (nbd, buf, size, offset,
+ NBD_NULL_CALLBACK(completion), 0);
else
- cookie = nbd_aio_pread (nbd, buf, size, offset, NULL, NULL, 0);
+ cookie = nbd_aio_pread (nbd, buf, size, offset,
+ NBD_NULL_CALLBACK(completion), 0);
if (cookie == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
goto error;
diff --git a/generator/generator b/generator/generator
index 4d3d7ad..ea32929 100755
--- a/generator/generator
+++ b/generator/generator
@@ -3226,10 +3226,7 @@ let rec print_arg_list ?(handle = false) ?(types = true) args
optargs =
pr "%s" len
| Closure { cbname; cbargs } ->
if types then pr "nbd_%s_callback " cbname;
- pr "%s_callback" cbname;
- pr ", ";
- if types then pr "void *";
- pr "%s_user_data" cbname
+ pr "%s_callback" cbname
| Enum (n, _) ->
if types then pr "int ";
pr "%s" n
@@ -3271,10 +3268,7 @@ let rec print_arg_list ?(handle = false) ?(types = true) args
optargs =
match optarg with
| OClosure { cbname; cbargs } ->
if types then pr "nbd_%s_callback " cbname;
- pr "%s_callback" cbname;
- pr ", ";
- if types then pr "void *";
- pr "%s_user_data" cbname
+ pr "%s_callback" cbname
| OFlags (n, _) ->
if types then pr "uint32_t ";
pr "%s" n
@@ -3337,14 +3331,19 @@ let print_cbarg_list ?(valid_flag = true) ?(types = true) cbargs
=
) cbargs;
pr ")"
-(* Callback typedefs in <libnbd.h> *)
-let print_closure_typedefs () =
+(* Callback structs/typedefs in <libnbd.h> *)
+let print_closure_structs () =
List.iter (
fun { cbname; cbargs } ->
- pr "typedef int (*nbd_%s_callback) " cbname;
+ pr "typedef struct {\n";
+ pr " void *user_data;\n";
+ pr " int (*callback) ";
print_cbarg_list cbargs;
pr ";\n";
+ pr "} nbd_%s_callback;\n" cbname;
+ pr "\n";
) all_closures;
+ pr "#define NBD_NULL_CALLBACK(name) ((nbd_## name ##_callback) { .callback = NULL
})\n";
pr "\n"
let print_extern_and_define name args optargs ret =
@@ -3434,7 +3433,7 @@ let generate_include_libnbd_h () =
pr "extern int nbd_get_errno (void);\n";
pr "#define LIBNBD_HAVE_NBD_GET_ERRNO 1\n";
pr "\n";
- print_closure_typedefs ();
+ print_closure_structs ();
List.iter (
fun (name, { args; optargs; ret }) ->
print_extern_and_define name args optargs ret
@@ -3566,7 +3565,7 @@ let generate_lib_api_c () =
let value = match errcode with
| Some value -> value
| None -> assert false in
- pr " if (%s_callback == NULL) {\n" cbname;
+ pr " if (%s_callback.callback == NULL) {\n" cbname;
pr " set_error (EFAULT, \"%%s cannot be NULL\",
\"%s\");\n" cbname;
pr " ret = %s;\n" value;
pr " goto out;\n";
@@ -3678,7 +3677,8 @@ let generate_lib_api_c () =
) args;
List.iter (
function
- | OClosure { cbname } -> pr ", %s_callback ? \"<fun>\" :
\"NULL\"" cbname
+ | OClosure { cbname } ->
+ pr ", %s_callback.callback ? \"<fun>\" :
\"NULL\"" cbname
| OFlags (n, _) -> pr ", %s" n
) optargs;
pr ");\n"
@@ -4156,7 +4156,8 @@ let print_python_binding name { args; optargs; ret; may_set_error }
=
n;
pr " struct py_aio_buffer *%s_buf;\n" n
| Closure { cbname } ->
- pr " PyObject *%s_user_data;\n" cbname
+ pr " nbd_%s_callback %s = { .callback = %s_wrapper };\n"
+ cbname cbname cbname
| Enum (n, _) -> pr " int %s;\n" n
| Flags (n, _) ->
pr " uint32_t %s_u32;\n" n;
@@ -4188,7 +4189,8 @@ let print_python_binding name { args; optargs; ret; may_set_error }
=
List.iter (
function
| OClosure { cbname } ->
- pr " PyObject *%s_user_data;\n" cbname
+ pr " nbd_%s_callback %s = { .callback = %s_wrapper };\n"
+ cbname cbname cbname
| OFlags (n, _) ->
pr " uint32_t %s_u32;\n" n;
pr " unsigned int %s; /* really uint32_t */\n" n
@@ -4231,7 +4233,7 @@ let print_python_binding name { args; optargs; ret; may_set_error }
=
| BytesIn (n, _) | BytesPersistIn (n, _)
| BytesPersistOut (n, _) -> pr ", &%s" n
| BytesOut (_, count) -> pr ", &%s" count
- | Closure { cbname } -> pr ", &%s_user_data" cbname
+ | Closure { cbname } -> pr ", &%s.user_data" cbname
| Enum (n, _) -> pr ", &%s" n
| Flags (n, _) -> pr ", &%s" n
| Int n -> pr ", &%s" n
@@ -4246,7 +4248,7 @@ let print_python_binding name { args; optargs; ret; may_set_error }
=
) args;
List.iter (
function
- | OClosure { cbname } -> pr ", &%s_user_data" cbname
+ | OClosure { cbname } -> pr ", &%s.user_data" cbname
| OFlags (n, _) -> pr ", &%s" n
) optargs;
pr "))\n";
@@ -4263,8 +4265,8 @@ let print_python_binding name { args; optargs; ret; may_set_error }
=
pr " %s_buf = nbd_internal_py_get_aio_buffer (%s);\n" n n
| Closure { cbname } ->
pr " /* Increment refcount since pointer may be saved by libnbd.
*/\n";
- pr " Py_INCREF (%s_user_data);\n" cbname;
- pr " if (!PyCallable_Check (%s_user_data)) {\n" cbname;
+ pr " Py_INCREF (%s.user_data);\n" cbname;
+ pr " if (!PyCallable_Check (%s.user_data)) {\n" cbname;
pr " PyErr_SetString (PyExc_TypeError,\n";
pr " \"callback parameter %s is not
callable\");\n" cbname;
pr " return NULL;\n";
@@ -4289,15 +4291,17 @@ let print_python_binding name { args; optargs; ret; may_set_error
} =
List.iter (
function
| OClosure { cbname } ->
- pr " if (%s_user_data != Py_None) {\n" cbname;
+ pr " if (%s.user_data != Py_None) {\n" cbname;
pr " /* Increment refcount since pointer may be saved by libnbd.
*/\n";
- pr " Py_INCREF (%s_user_data);\n" cbname;
- pr " if (!PyCallable_Check (%s_user_data)) {\n" cbname;
+ pr " Py_INCREF (%s.user_data);\n" cbname;
+ pr " if (!PyCallable_Check (%s.user_data)) {\n" cbname;
pr " PyErr_SetString (PyExc_TypeError,\n";
pr " \"callback parameter %s is not
callable\");\n" cbname;
pr " return NULL;\n";
pr " }\n";
- pr " }\n"
+ pr " }\n";
+ pr " else\n";
+ pr " %s.callback = NULL; /* we're not going to call it */\n"
cbname
| OFlags (n, _) -> pr " %s_u32 = %s;\n" n n
) optargs;
@@ -4310,9 +4314,7 @@ let print_python_binding name { args; optargs; ret; may_set_error }
=
| BytesOut (n, count) -> pr ", %s, %s" n count
| BytesPersistIn (n, _)
| BytesPersistOut (n, _) -> pr ", %s_buf->data, %s_buf->len" n n
- | Closure { cbname } ->
- pr ", %s_wrapper" cbname;
- pr ", %s_user_data" cbname
+ | Closure { cbname } -> pr ", %s" cbname
| Enum (n, _) -> pr ", %s" n
| Flags (n, _) -> pr ", %s_u32" n
| Int n -> pr ", %s" n
@@ -4327,9 +4329,7 @@ let print_python_binding name { args; optargs; ret; may_set_error }
=
) args;
List.iter (
function
- | OClosure { cbname } ->
- pr ", %s_user_data != Py_None ? %s_wrapper : NULL" cbname cbname;
- pr ", %s_user_data != Py_None ? %s_user_data : NULL" cbname cbname
+ | OClosure { cbname } -> pr ", %s" cbname
| OFlags (n, _) -> pr ", %s_u32" n
) optargs;
pr ");\n";
@@ -5125,17 +5125,18 @@ let print_ocaml_binding (name, { args; optargs; ret }) =
List.iter (
function
| OClosure { cbname } ->
- pr " const void *%s_callback = NULL;\n" cbname;
- pr " value *%s_user_data = NULL;\n" cbname;
+ pr " nbd_%s_callback %s_callback = {0};\n" cbname cbname;
pr " if (%sv != Val_int (0)) { /* Some closure */\n" cbname;
pr " /* The function may save a reference to the closure, so we\n";
pr " * must treat it as a possible GC root.\n";
pr " */\n";
- pr " %s_user_data = malloc (sizeof (value));\n" cbname;
- pr " if (%s_user_data == NULL) caml_raise_out_of_memory ();\n"
cbname;
- pr " *%s_user_data = Field (%sv, 0);\n" cbname cbname;
- pr " caml_register_generational_global_root (%s_user_data);\n"
cbname;
- pr " %s_callback = %s_wrapper;\n" cbname cbname;
+ pr " %s_callback.user_data = malloc (sizeof (value));\n" cbname;
+ pr " if (%s_callback.user_data == NULL)\n" cbname;
+ pr " caml_raise_out_of_memory ();\n";
+ pr " *(value *)%s_callback.user_data = Field (%sv, 0);\n"
+ cbname cbname;
+ pr " caml_register_generational_global_root
(%s_callback.user_data);\n" cbname;
+ pr " %s_callback.callback = %s_wrapper;\n" cbname cbname;
pr " }\n";
| OFlags (n, { flag_prefix }) ->
pr " uint32_t %s;\n" n;
@@ -5168,12 +5169,14 @@ let print_ocaml_binding (name, { args; optargs; ret }) =
pr " /* The function may save a reference to the closure, so we\n";
pr " * must treat it as a possible GC root.\n";
pr " */\n";
- pr " value *%s_user_data;\n" cbname;
- pr " %s_user_data = malloc (sizeof (value));\n" cbname;
- pr " if (%s_user_data == NULL) caml_raise_out_of_memory ();\n" cbname;
- pr " *%s_user_data = %sv;\n" cbname cbname;
- pr " caml_register_generational_global_root (%s_user_data);\n" cbname;
- pr " const void *%s_callback = %s_wrapper;\n" cbname cbname
+ pr " nbd_%s_callback %s_callback = { .callback = %s_wrapper };\n"
+ cbname cbname cbname;
+ pr " %s_callback.user_data = malloc (sizeof (value));\n" cbname;
+ pr " if (%s_callback.user_data == NULL) caml_raise_out_of_memory
();\n"
+ cbname;
+ pr " *(value *)%s_callback.user_data = %sv;\n" cbname cbname;
+ pr " caml_register_generational_global_root
(%s_callback.user_data);\n"
+ cbname
| Enum (n, { enum_prefix }) ->
pr " int %s = %s_val (%sv);\n" n enum_prefix n
| Flags (n, { flag_prefix }) ->
diff --git a/generator/states-reply-simple.c b/generator/states-reply-simple.c
index 9b249ab..f1d3c62 100644
--- a/generator/states-reply-simple.c
+++ b/generator/states-reply-simple.c
@@ -60,16 +60,17 @@
case 0:
/* guaranteed by START */
assert (cmd);
- if (cmd->cb.fn.chunk) {
+ if (cmd->cb.fn.chunk.callback) {
int error = 0;
assert (cmd->error == 0);
- if (cmd->cb.fn.chunk (LIBNBD_CALLBACK_VALID|LIBNBD_CALLBACK_FREE,
- cmd->cb.fn_user_data,
- cmd->data, cmd->count,
- cmd->offset, LIBNBD_READ_DATA, &error) == -1)
+ if (cmd->cb.fn.chunk.callback (LIBNBD_CALLBACK_VALID|LIBNBD_CALLBACK_FREE,
+ cmd->cb.fn.chunk.user_data,
+ cmd->data, cmd->count,
+ cmd->offset, LIBNBD_READ_DATA,
+ &error) == -1)
cmd->error = error ? error : EPROTO;
- cmd->cb.fn.chunk = NULL; /* because we've freed it */
+ cmd->cb.fn.chunk.callback = NULL; /* because we've freed it */
}
SET_NEXT_STATE (%^FINISH_COMMAND);
diff --git a/generator/states-reply-structured.c b/generator/states-reply-structured.c
index cdd9f10..92d6b5f 100644
--- a/generator/states-reply-structured.c
+++ b/generator/states-reply-structured.c
@@ -168,7 +168,7 @@ valid_flags (struct nbd_handle *h)
set_error (0, "invalid length in NBD_REPLY_TYPE_BLOCK_STATUS");
return 0;
}
- if (cmd->cb.fn.extent == NULL) {
+ if (cmd->cb.fn.extent.callback == NULL) {
SET_NEXT_STATE (%.DEAD);
set_error (0, "not expecting NBD_REPLY_TYPE_BLOCK_STATUS here");
return 0;
@@ -304,7 +304,7 @@ valid_flags (struct nbd_handle *h)
offset, cmd->offset, cmd->count);
return 0;
}
- if (cmd->type == NBD_CMD_READ && cmd->cb.fn.chunk) {
+ if (cmd->type == NBD_CMD_READ && cmd->cb.fn.chunk.callback) {
int scratch = error;
unsigned valid = valid_flags (h);
@@ -312,13 +312,14 @@ valid_flags (struct nbd_handle *h)
* current error rather than any earlier one. If the callback fails
* without setting errno, then use the server's error below.
*/
- if (cmd->cb.fn.chunk (valid, cmd->cb.fn_user_data,
- cmd->data + (offset - cmd->offset),
- 0, offset, LIBNBD_READ_ERROR, &scratch) == -1)
+ if (cmd->cb.fn.chunk.callback (valid, cmd->cb.fn.chunk.user_data,
+ cmd->data + (offset - cmd->offset),
+ 0, offset, LIBNBD_READ_ERROR,
+ &scratch) == -1)
if (cmd->error == 0)
cmd->error = scratch;
if (valid & LIBNBD_CALLBACK_FREE)
- cmd->cb.fn.chunk = NULL; /* because we've freed it */
+ cmd->cb.fn.chunk.callback = NULL; /* because we've freed it */
}
}
@@ -398,18 +399,18 @@ valid_flags (struct nbd_handle *h)
offset = be64toh (h->sbuf.sr.payload.offset_data.offset);
assert (cmd); /* guaranteed by CHECK */
- if (cmd->cb.fn.chunk) {
+ if (cmd->cb.fn.chunk.callback) {
int error = cmd->error;
unsigned valid = valid_flags (h);
- if (cmd->cb.fn.chunk (valid, cmd->cb.fn_user_data,
- cmd->data + (offset - cmd->offset),
- length - sizeof offset, offset,
- LIBNBD_READ_DATA, &error) == -1)
+ if (cmd->cb.fn.chunk.callback (valid, cmd->cb.fn.chunk.user_data,
+ cmd->data + (offset - cmd->offset),
+ length - sizeof offset, offset,
+ LIBNBD_READ_DATA, &error) == -1)
if (cmd->error == 0)
cmd->error = error ? error : EPROTO;
if (valid & LIBNBD_CALLBACK_FREE)
- cmd->cb.fn.chunk = NULL; /* because we've freed it */
+ cmd->cb.fn.chunk.callback = NULL; /* because we've freed it */
}
SET_NEXT_STATE (%FINISH);
@@ -463,18 +464,18 @@ valid_flags (struct nbd_handle *h)
* them as an extension, and this works even when length == 0.
*/
memset (cmd->data + offset, 0, length);
- if (cmd->cb.fn.chunk) {
+ if (cmd->cb.fn.chunk.callback) {
int error = cmd->error;
unsigned valid = valid_flags (h);
- if (cmd->cb.fn.chunk (valid, cmd->cb.fn_user_data,
- cmd->data + offset, length,
- cmd->offset + offset,
- LIBNBD_READ_HOLE, &error) == -1)
+ if (cmd->cb.fn.chunk.callback (valid, cmd->cb.fn.chunk.user_data,
+ cmd->data + offset, length,
+ cmd->offset + offset,
+ LIBNBD_READ_HOLE, &error) == -1)
if (cmd->error == 0)
cmd->error = error ? error : EPROTO;
if (valid & LIBNBD_CALLBACK_FREE)
- cmd->cb.fn.chunk = NULL; /* because we've freed it */
+ cmd->cb.fn.chunk.callback = NULL; /* because we've freed it */
}
SET_NEXT_STATE(%FINISH);
@@ -499,7 +500,7 @@ valid_flags (struct nbd_handle *h)
assert (cmd); /* guaranteed by CHECK */
assert (cmd->type == NBD_CMD_BLOCK_STATUS);
- assert (cmd->cb.fn.extent);
+ assert (cmd->cb.fn.extent.callback);
assert (h->bs_entries);
assert (length >= 12);
@@ -522,13 +523,14 @@ valid_flags (struct nbd_handle *h)
int error = cmd->error;
unsigned valid = valid_flags (h);
- if (cmd->cb.fn.extent (valid, cmd->cb.fn_user_data,
- meta_context->name, cmd->offset,
- &h->bs_entries[1], (length-4) / 4, &error) ==
-1)
+ if (cmd->cb.fn.extent.callback (valid, cmd->cb.fn.extent.user_data,
+ meta_context->name, cmd->offset,
+ &h->bs_entries[1], (length-4) / 4,
+ &error) == -1)
if (cmd->error == 0)
cmd->error = error ? error : EPROTO;
if (valid & LIBNBD_CALLBACK_FREE)
- cmd->cb.fn.extent = NULL; /* because we've freed it */
+ cmd->cb.fn.extent.callback = NULL; /* because we've freed it */
}
else
/* Emit a debug message, but ignore it. */
@@ -545,13 +547,15 @@ valid_flags (struct nbd_handle *h)
flags = be16toh (h->sbuf.sr.structured_reply.flags);
if (flags & NBD_REPLY_FLAG_DONE) {
- if (cmd->type == NBD_CMD_BLOCK_STATUS && cmd->cb.fn.extent)
- cmd->cb.fn.extent (LIBNBD_CALLBACK_FREE, cmd->cb.fn_user_data,
- NULL, 0, NULL, 0, NULL);
- if (cmd->type == NBD_CMD_READ && cmd->cb.fn.chunk)
- cmd->cb.fn.chunk (LIBNBD_CALLBACK_FREE, cmd->cb.fn_user_data,
- NULL, 0, 0, 0, NULL);
- cmd->cb.fn.chunk = NULL;
+ if (cmd->type == NBD_CMD_BLOCK_STATUS && cmd->cb.fn.extent.callback)
+ cmd->cb.fn.extent.callback (LIBNBD_CALLBACK_FREE,
+ cmd->cb.fn.extent.user_data,
+ NULL, 0, NULL, 0, NULL);
+ if (cmd->type == NBD_CMD_READ && cmd->cb.fn.chunk.callback)
+ cmd->cb.fn.chunk.callback (LIBNBD_CALLBACK_FREE,
+ cmd->cb.fn.chunk.user_data,
+ NULL, 0, 0, 0, NULL);
+ cmd->cb.fn.chunk.callback = NULL;
SET_NEXT_STATE (%^FINISH_COMMAND);
}
else {
diff --git a/generator/states-reply.c b/generator/states-reply.c
index 09adfed..e6b479a 100644
--- a/generator/states-reply.c
+++ b/generator/states-reply.c
@@ -168,14 +168,14 @@ save_reply_state (struct nbd_handle *h)
retire = cmd->type == NBD_CMD_DISC;
/* Notify the user */
- if (cmd->cb.completion) {
+ if (cmd->cb.completion.callback) {
int error = cmd->error;
int r;
assert (cmd->type != NBD_CMD_DISC);
- r = cmd->cb.completion (LIBNBD_CALLBACK_VALID|LIBNBD_CALLBACK_FREE,
- cmd->cb.user_data, &error);
- cmd->cb.completion = NULL; /* because we've freed it */
+ r = cmd->cb.completion.callback (LIBNBD_CALLBACK_VALID|LIBNBD_CALLBACK_FREE,
+ cmd->cb.completion.user_data, &error);
+ cmd->cb.completion.callback = NULL; /* because we've freed it */
switch (r) {
case -1:
if (error)
diff --git a/generator/states.c b/generator/states.c
index 9ed57ae..22b0304 100644
--- a/generator/states.c
+++ b/generator/states.c
@@ -121,14 +121,14 @@ void abort_commands (struct nbd_handle *h,
bool retire = cmd->type == NBD_CMD_DISC;
next = cmd->next;
- if (cmd->cb.completion) {
+ if (cmd->cb.completion.callback) {
int error = cmd->error ? cmd->error : ENOTCONN;
int r;
assert (cmd->type != NBD_CMD_DISC);
- r = cmd->cb.completion (LIBNBD_CALLBACK_VALID|LIBNBD_CALLBACK_FREE,
- cmd->cb.user_data, &error);
- cmd->cb.completion = NULL; /* because we've freed it */
+ r = cmd->cb.completion.callback (LIBNBD_CALLBACK_VALID|LIBNBD_CALLBACK_FREE,
+ cmd->cb.completion.user_data, &error);
+ cmd->cb.completion.callback = NULL; /* because we've freed it */
switch (r) {
case -1:
if (error)
diff --git a/interop/dirty-bitmap.c b/interop/dirty-bitmap.c
index aca0564..5a22adc 100644
--- a/interop/dirty-bitmap.c
+++ b/interop/dirty-bitmap.c
@@ -140,14 +140,17 @@ main (int argc, char *argv[])
}
data = (struct data) { .count = 2, };
- if (nbd_block_status (nbd, exportsize, 0, cb, &data, 0) == -1) {
+ if (nbd_block_status (nbd, exportsize, 0,
+ (nbd_extent_callback) { .callback = cb, .user_data = &data
},
+ 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
assert (data.seen_base && data.seen_dirty);
data = (struct data) { .req_one = true, .count = 2, };
- if (nbd_block_status (nbd, exportsize, 0, cb, &data,
+ if (nbd_block_status (nbd, exportsize, 0,
+ (nbd_extent_callback) { .callback = cb, .user_data = &data
},
LIBNBD_CMD_FLAG_REQ_ONE) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
@@ -156,7 +159,9 @@ main (int argc, char *argv[])
/* Trigger a failed callback, to prove connection stays up. */
data = (struct data) { .count = 2, .fail = true, };
- if (nbd_block_status (nbd, exportsize, 0, cb, &data, 0) != -1) {
+ if (nbd_block_status (nbd, exportsize, 0,
+ (nbd_extent_callback) { .callback = cb, .user_data = &data
},
+ 0) != -1) {
fprintf (stderr, "unexpected block status success\n");
exit (EXIT_FAILURE);
}
diff --git a/interop/structured-read.c b/interop/structured-read.c
index 0b189d1..31aadbe 100644
--- a/interop/structured-read.c
+++ b/interop/structured-read.c
@@ -147,7 +147,8 @@ main (int argc, char *argv[])
memset (rbuf, 2, sizeof rbuf);
data = (struct data) { .count = 2, };
- if (nbd_pread_structured (nbd, rbuf, sizeof rbuf, 2048, read_cb, &data,
+ if (nbd_pread_structured (nbd, rbuf, sizeof rbuf, 2048,
+ (nbd_chunk_callback) { .callback = read_cb, .user_data =
&data },
0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
@@ -157,7 +158,8 @@ main (int argc, char *argv[])
/* Repeat with DF flag. */
memset (rbuf, 2, sizeof rbuf);
data = (struct data) { .df = true, .count = 1, };
- if (nbd_pread_structured (nbd, rbuf, sizeof rbuf, 2048, read_cb, &data,
+ if (nbd_pread_structured (nbd, rbuf, sizeof rbuf, 2048,
+ (nbd_chunk_callback) { .callback = read_cb, .user_data =
&data },
LIBNBD_CMD_FLAG_DF) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
@@ -170,7 +172,8 @@ main (int argc, char *argv[])
*/
memset (rbuf, 2, sizeof rbuf);
data = (struct data) { .count = 2, .fail = true, };
- if (nbd_pread_structured (nbd, rbuf, sizeof rbuf, 2048, read_cb, &data,
+ if (nbd_pread_structured (nbd, rbuf, sizeof rbuf, 2048,
+ (nbd_chunk_callback) { .callback = read_cb, .user_data =
&data },
0) != -1) {
fprintf (stderr, "unexpected pread callback success\n");
exit (EXIT_FAILURE);
diff --git a/lib/aio.c b/lib/aio.c
index c141de6..5017ee6 100644
--- a/lib/aio.c
+++ b/lib/aio.c
@@ -32,15 +32,18 @@ void
nbd_internal_retire_and_free_command (struct command *cmd)
{
/* Free the callbacks. */
- if (cmd->type == NBD_CMD_BLOCK_STATUS && cmd->cb.fn.extent)
- cmd->cb.fn.extent (LIBNBD_CALLBACK_FREE, cmd->cb.fn_user_data,
- NULL, 0, NULL, 0, NULL);
- if (cmd->type == NBD_CMD_READ && cmd->cb.fn.chunk)
- cmd->cb.fn.chunk (LIBNBD_CALLBACK_FREE, cmd->cb.fn_user_data,
- NULL, 0, 0, 0, NULL);
- if (cmd->cb.completion)
- cmd->cb.completion (LIBNBD_CALLBACK_FREE, cmd->cb.user_data,
- NULL);
+ if (cmd->type == NBD_CMD_BLOCK_STATUS && cmd->cb.fn.extent.callback)
+ cmd->cb.fn.extent.callback (LIBNBD_CALLBACK_FREE,
+ cmd->cb.fn.extent.user_data,
+ NULL, 0, NULL, 0, NULL);
+ if (cmd->type == NBD_CMD_READ && cmd->cb.fn.chunk.callback)
+ cmd->cb.fn.chunk.callback (LIBNBD_CALLBACK_FREE,
+ cmd->cb.fn.chunk.user_data,
+ NULL, 0, 0, 0, NULL);
+ if (cmd->cb.completion.callback)
+ cmd->cb.completion.callback (LIBNBD_CALLBACK_FREE,
+ cmd->cb.completion.user_data,
+ NULL);
free (cmd);
}
diff --git a/lib/debug.c b/lib/debug.c
index c1decb2..7753394 100644
--- a/lib/debug.c
+++ b/lib/debug.c
@@ -41,23 +41,22 @@ nbd_unlocked_get_debug (struct nbd_handle *h)
int
nbd_unlocked_clear_debug_callback (struct nbd_handle *h)
{
- if (h->debug_callback)
+ if (h->debug_callback.callback)
/* ignore return value */
- h->debug_callback (LIBNBD_CALLBACK_FREE, h->debug_data, NULL, NULL);
- h->debug_callback = NULL;
- h->debug_data = NULL;
+ h->debug_callback.callback (LIBNBD_CALLBACK_FREE,
+ h->debug_callback.user_data, NULL, NULL);
+ h->debug_callback.callback = NULL;
return 0;
}
int
nbd_unlocked_set_debug_callback (struct nbd_handle *h,
- nbd_debug_callback debug_callback, void *data)
+ nbd_debug_callback debug_callback)
{
/* This can't fail at the moment - see implementation above. */
nbd_unlocked_clear_debug_callback (h);
h->debug_callback = debug_callback;
- h->debug_data = data;
return 0;
}
@@ -87,9 +86,10 @@ nbd_internal_debug (struct nbd_handle *h, const char *fs, ...)
if (r == -1)
goto out;
- if (h->debug_callback)
+ if (h->debug_callback.callback)
/* ignore return value */
- h->debug_callback (LIBNBD_CALLBACK_VALID, h->debug_data, context, msg);
+ h->debug_callback.callback (LIBNBD_CALLBACK_VALID,
+ h->debug_callback.user_data, context, msg);
else
fprintf (stderr, "libnbd: debug: %s: %s: %s\n",
h->hname, context ? : "unknown", msg);
diff --git a/lib/internal.h b/lib/internal.h
index 301b798..5996a4f 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -85,7 +85,6 @@ struct nbd_handle {
/* For debugging. */
bool debug;
nbd_debug_callback debug_callback;
- void *debug_data;
/* State machine.
*
@@ -257,9 +256,7 @@ struct command_cb {
nbd_extent_callback extent;
nbd_chunk_callback chunk;
} fn;
- void *fn_user_data; /* associated with one of the fn callbacks above */
nbd_completion_callback completion;
- void *user_data; /* associated with the completion callback */
};
struct command {
diff --git a/lib/rw.c b/lib/rw.c
index dbd4e8c..9881701 100644
--- a/lib/rw.c
+++ b/lib/rw.c
@@ -49,7 +49,8 @@ nbd_unlocked_pread (struct nbd_handle *h, void *buf,
{
int64_t cookie;
- cookie = nbd_unlocked_aio_pread (h, buf, count, offset, NULL, NULL, flags);
+ cookie = nbd_unlocked_aio_pread (h, buf, count, offset,
+ NBD_NULL_CALLBACK(completion), flags);
if (cookie == -1)
return -1;
@@ -60,14 +61,15 @@ nbd_unlocked_pread (struct nbd_handle *h, void *buf,
int
nbd_unlocked_pread_structured (struct nbd_handle *h, void *buf,
size_t count, uint64_t offset,
- nbd_chunk_callback chunk, void *user_data,
+ nbd_chunk_callback chunk,
uint32_t flags)
{
int64_t cookie;
cookie = nbd_unlocked_aio_pread_structured (h, buf, count, offset,
- chunk, user_data,
- NULL, NULL, flags);
+ chunk,
+ NBD_NULL_CALLBACK(completion),
+ flags);
if (cookie == -1)
return -1;
@@ -81,7 +83,8 @@ nbd_unlocked_pwrite (struct nbd_handle *h, const void *buf,
{
int64_t cookie;
- cookie = nbd_unlocked_aio_pwrite (h, buf, count, offset, NULL, NULL, flags);
+ cookie = nbd_unlocked_aio_pwrite (h, buf, count, offset,
+ NBD_NULL_CALLBACK(completion), flags);
if (cookie == -1)
return -1;
@@ -94,7 +97,7 @@ nbd_unlocked_flush (struct nbd_handle *h, uint32_t flags)
{
int64_t cookie;
- cookie = nbd_unlocked_aio_flush (h, NULL, NULL, flags);
+ cookie = nbd_unlocked_aio_flush (h, NBD_NULL_CALLBACK(completion), flags);
if (cookie == -1)
return -1;
@@ -108,7 +111,8 @@ nbd_unlocked_trim (struct nbd_handle *h,
{
int64_t cookie;
- cookie = nbd_unlocked_aio_trim (h, count, offset, NULL, NULL, flags);
+ cookie = nbd_unlocked_aio_trim (h, count, offset,
+ NBD_NULL_CALLBACK(completion), flags);
if (cookie == -1)
return -1;
@@ -122,7 +126,8 @@ nbd_unlocked_cache (struct nbd_handle *h,
{
int64_t cookie;
- cookie = nbd_unlocked_aio_cache (h, count, offset, NULL, NULL, flags);
+ cookie = nbd_unlocked_aio_cache (h, count, offset,
+ NBD_NULL_CALLBACK(completion), flags);
if (cookie == -1)
return -1;
@@ -136,7 +141,8 @@ nbd_unlocked_zero (struct nbd_handle *h,
{
int64_t cookie;
- cookie = nbd_unlocked_aio_zero (h, count, offset, NULL, NULL, flags);
+ cookie = nbd_unlocked_aio_zero (h, count, offset,
+ NBD_NULL_CALLBACK(completion), flags);
if (cookie == -1)
return -1;
@@ -147,13 +153,13 @@ nbd_unlocked_zero (struct nbd_handle *h,
int
nbd_unlocked_block_status (struct nbd_handle *h,
uint64_t count, uint64_t offset,
- nbd_extent_callback extent, void *user_data,
+ nbd_extent_callback extent,
uint32_t flags)
{
int64_t cookie;
- cookie = nbd_unlocked_aio_block_status (h, count, offset, extent, user_data,
- NULL, NULL, flags);
+ cookie = nbd_unlocked_aio_block_status (h, count, offset, extent,
+ NBD_NULL_CALLBACK(completion), flags);
if (cookie == -1)
return -1;
@@ -257,10 +263,9 @@ int64_t
nbd_unlocked_aio_pread (struct nbd_handle *h, void *buf,
size_t count, uint64_t offset,
nbd_completion_callback completion,
- void *user_data,
uint32_t flags)
{
- struct command_cb cb = { .completion = completion, .user_data = user_data, };
+ struct command_cb cb = { .completion = completion };
/* We could silently accept flag DF, but it really only makes sense
* with callbacks, because otherwise there is no observable change
@@ -279,15 +284,11 @@ int64_t
nbd_unlocked_aio_pread_structured (struct nbd_handle *h, void *buf,
size_t count, uint64_t offset,
nbd_chunk_callback chunk,
- void *read_user_data,
nbd_completion_callback completion,
- void *callback_user_data,
uint32_t flags)
{
struct command_cb cb = { .fn.chunk = chunk,
- .fn_user_data = read_user_data,
- .completion = completion,
- .user_data = callback_user_data, };
+ .completion = completion };
if ((flags & ~LIBNBD_CMD_FLAG_DF) != 0) {
set_error (EINVAL, "invalid flag: %" PRIu32, flags);
@@ -308,10 +309,9 @@ int64_t
nbd_unlocked_aio_pwrite (struct nbd_handle *h, const void *buf,
size_t count, uint64_t offset,
nbd_completion_callback completion,
- void *user_data,
uint32_t flags)
{
- struct command_cb cb = { .completion = completion, .user_data = user_data, };
+ struct command_cb cb = { .completion = completion };
if (nbd_unlocked_is_read_only (h) == 1) {
set_error (EINVAL, "server does not support write operations");
@@ -336,10 +336,9 @@ nbd_unlocked_aio_pwrite (struct nbd_handle *h, const void *buf,
int64_t
nbd_unlocked_aio_flush (struct nbd_handle *h,
nbd_completion_callback completion,
- void *user_data,
uint32_t flags)
{
- struct command_cb cb = { .completion = completion, .user_data = user_data, };
+ struct command_cb cb = { .completion = completion };
if (nbd_unlocked_can_flush (h) != 1) {
set_error (EINVAL, "server does not support flush operations");
@@ -359,10 +358,9 @@ int64_t
nbd_unlocked_aio_trim (struct nbd_handle *h,
uint64_t count, uint64_t offset,
nbd_completion_callback completion,
- void *user_data,
uint32_t flags)
{
- struct command_cb cb = { .completion = completion, .user_data = user_data, };
+ struct command_cb cb = { .completion = completion };
if (nbd_unlocked_is_read_only (h) == 1) {
set_error (EINVAL, "server does not support write operations");
@@ -393,10 +391,9 @@ int64_t
nbd_unlocked_aio_cache (struct nbd_handle *h,
uint64_t count, uint64_t offset,
nbd_completion_callback completion,
- void *user_data,
uint32_t flags)
{
- struct command_cb cb = { .completion = completion, .user_data = user_data, };
+ struct command_cb cb = { .completion = completion };
/* Actually according to the NBD protocol document, servers do exist
* that support NBD_CMD_CACHE but don't advertise the
@@ -420,10 +417,9 @@ int64_t
nbd_unlocked_aio_zero (struct nbd_handle *h,
uint64_t count, uint64_t offset,
nbd_completion_callback completion,
- void *user_data,
uint32_t flags)
{
- struct command_cb cb = { .completion = completion, .user_data = user_data, };
+ struct command_cb cb = { .completion = completion };
if (nbd_unlocked_is_read_only (h) == 1) {
set_error (EINVAL, "server does not support write operations");
@@ -454,15 +450,11 @@ int64_t
nbd_unlocked_aio_block_status (struct nbd_handle *h,
uint64_t count, uint64_t offset,
nbd_extent_callback extent,
- void *extent_user_data,
nbd_completion_callback completion,
- void *callback_user_data,
uint32_t flags)
{
struct command_cb cb = { .fn.extent = extent,
- .fn_user_data = extent_user_data,
- .completion = completion,
- .user_data = callback_user_data };
+ .completion = completion };
if (!h->structured_replies) {
set_error (ENOTSUP, "server does not support structured replies");
diff --git a/tests/aio-parallel-load.c b/tests/aio-parallel-load.c
index 1f48324..0d67c36 100644
--- a/tests/aio-parallel-load.c
+++ b/tests/aio-parallel-load.c
@@ -255,11 +255,13 @@ start_thread (void *arg)
offset = rand () % (EXPORTSIZE - buf_size);
cmd = rand () & 1;
if (cmd == 0) {
- cookie = nbd_aio_pwrite (nbd, buf, buf_size, offset, NULL, NULL, 0);
+ cookie = nbd_aio_pwrite (nbd, buf, buf_size, offset,
+ NBD_NULL_CALLBACK(completion), 0);
status->bytes_sent += buf_size;
}
else {
- cookie = nbd_aio_pread (nbd, buf, buf_size, offset, NULL, NULL, 0);
+ cookie = nbd_aio_pread (nbd, buf, buf_size, offset,
+ NBD_NULL_CALLBACK(completion), 0);
status->bytes_received += buf_size;
}
if (cookie == -1) {
diff --git a/tests/aio-parallel.c b/tests/aio-parallel.c
index fb4d695..f6f13e6 100644
--- a/tests/aio-parallel.c
+++ b/tests/aio-parallel.c
@@ -271,12 +271,14 @@ start_thread (void *arg)
+ (rand () % (status->length[i] - BUFFERSIZE));
cmd = rand () & 1;
if (cmd == 0) {
- cookie = nbd_aio_pwrite (nbd, buf, BUFFERSIZE, offset, NULL, NULL, 0);
+ cookie = nbd_aio_pwrite (nbd, buf, BUFFERSIZE, offset,
+ NBD_NULL_CALLBACK(completion), 0);
status->bytes_sent += BUFFERSIZE;
memcpy (&ramdisk[offset], buf, BUFFERSIZE);
}
else {
- cookie = nbd_aio_pread (nbd, buf, BUFFERSIZE, offset, NULL, NULL, 0);
+ cookie = nbd_aio_pread (nbd, buf, BUFFERSIZE, offset,
+ NBD_NULL_CALLBACK(completion), 0);
status->bytes_received += BUFFERSIZE;
}
if (cookie == -1) {
diff --git a/tests/closure-lifetimes.c b/tests/closure-lifetimes.c
index 60809d4..e21a0e9 100644
--- a/tests/closure-lifetimes.c
+++ b/tests/closure-lifetimes.c
@@ -101,10 +101,10 @@ main (int argc, char *argv[])
nbd = nbd_create ();
if (nbd == NULL) NBD_ERROR;
- nbd_set_debug_callback (nbd, debug_fn, NULL);
+ nbd_set_debug_callback (nbd, (nbd_debug_callback) { .callback = debug_fn });
assert (debug_fn_free == 0);
- nbd_set_debug_callback (nbd, debug_fn, NULL);
+ nbd_set_debug_callback (nbd, (nbd_debug_callback) { .callback = debug_fn});
assert (debug_fn_free == 1);
debug_fn_free = 0;
@@ -117,8 +117,9 @@ main (int argc, char *argv[])
if (nbd_connect_command (nbd, nbdkit) == -1) NBD_ERROR;
cookie = nbd_aio_pread_structured (nbd, buf, sizeof buf, 0,
- read_cb, NULL,
- completion_cb, NULL, 0);
+ (nbd_chunk_callback) { .callback = read_cb },
+ (nbd_completion_callback) { .callback =
completion_cb },
+ 0);
if (cookie == -1) NBD_ERROR;
assert (read_cb_free == 0);
assert (completion_cb_free == 0);
@@ -144,8 +145,9 @@ main (int argc, char *argv[])
if (nbd_connect_command (nbd, nbdkit_delay) == -1) NBD_ERROR;
cookie = nbd_aio_pread_structured (nbd, buf, sizeof buf, 0,
- read_cb, NULL,
- completion_cb, NULL, 0);
+ (nbd_chunk_callback) { .callback = read_cb },
+ (nbd_completion_callback) { .callback =
completion_cb },
+ 0);
if (cookie == -1) NBD_ERROR;
nbd_kill_command (nbd, 0);
nbd_close (nbd);
diff --git a/tests/errors.c b/tests/errors.c
index e442738..21ec919 100644
--- a/tests/errors.c
+++ b/tests/errors.c
@@ -222,7 +222,8 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
check (ERANGE, "nbd_pread: ");
- if (nbd_aio_pwrite (nbd, buf, MAXSIZE, 0, NULL, NULL, 0) != -1) {
+ if (nbd_aio_pwrite (nbd, buf, MAXSIZE, 0,
+ NBD_NULL_CALLBACK(completion), 0) != -1) {
fprintf (stderr, "%s: test failed: "
"nbd_aio_pwrite did not fail with oversize request\n",
argv[0]);
@@ -245,11 +246,13 @@ main (int argc, char *argv[])
* command at a time and stalls on the first), then queue multiple
* disconnects.
*/
- if (nbd_aio_pwrite (nbd, buf, 2 * 1024 * 1024, 0, NULL, NULL, 0) == -1) {
+ if (nbd_aio_pwrite (nbd, buf, 2 * 1024 * 1024, 0,
+ NBD_NULL_CALLBACK(completion), 0) == -1) {
fprintf (stderr, "%s: %s\n", argv[0], nbd_get_error ());
exit (EXIT_FAILURE);
}
- if (nbd_aio_pwrite (nbd, buf, 2 * 1024 * 1024, 0, NULL, NULL, 0) == -1) {
+ if (nbd_aio_pwrite (nbd, buf, 2 * 1024 * 1024, 0,
+ NBD_NULL_CALLBACK(completion), 0) == -1) {
fprintf (stderr, "%s: %s\n", argv[0], nbd_get_error ());
exit (EXIT_FAILURE);
}
diff --git a/tests/meta-base-allocation.c b/tests/meta-base-allocation.c
index c36a77f..d4e331c 100644
--- a/tests/meta-base-allocation.c
+++ b/tests/meta-base-allocation.c
@@ -101,19 +101,24 @@ main (int argc, char *argv[])
/* Read the block status. */
id = 1;
- if (nbd_block_status (nbd, 65536, 0, check_extent, &id, 0) == -1) {
+ if (nbd_block_status (nbd, 65536, 0,
+ (nbd_extent_callback) { .callback = check_extent, .user_data =
&id },
+ 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
id = 2;
- if (nbd_block_status (nbd, 1024, 32768-512, check_extent, &id, 0) == -1) {
+ if (nbd_block_status (nbd, 1024, 32768-512,
+ (nbd_extent_callback) { .callback = check_extent, .user_data =
&id },
+ 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
id = 3;
- if (nbd_block_status (nbd, 1024, 32768-512, check_extent, &id,
+ if (nbd_block_status (nbd, 1024, 32768-512,
+ (nbd_extent_callback) { .callback = check_extent, .user_data =
&id },
LIBNBD_CMD_FLAG_REQ_ONE) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
diff --git a/tests/oldstyle.c b/tests/oldstyle.c
index afbda61..ff2ee97 100644
--- a/tests/oldstyle.c
+++ b/tests/oldstyle.c
@@ -131,7 +131,8 @@ main (int argc, char *argv[])
/* Test again for callback operation. */
memset (rbuf, 0, sizeof rbuf);
if (nbd_pread_structured (nbd, rbuf, sizeof rbuf, 2 * sizeof rbuf,
- pread_cb, &calls, 0) == -1) {
+ (nbd_chunk_callback) { .callback = pread_cb, .user_data =
&calls },
+ 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
@@ -147,7 +148,8 @@ main (int argc, char *argv[])
/* Also test that callback errors are reflected correctly. */
if (nbd_pread_structured (nbd, rbuf, sizeof rbuf, 2 * sizeof rbuf,
- pread_cb, &calls, 0) != -1) {
+ (nbd_chunk_callback) { .callback = pread_cb, .user_data =
&calls },
+ 0) != -1) {
fprintf (stderr, "%s: expected failure from callback\n", argv[0]);
exit (EXIT_FAILURE);
}
diff --git a/tests/server-death.c b/tests/server-death.c
index 1559753..f7684ac 100644
--- a/tests/server-death.c
+++ b/tests/server-death.c
@@ -77,12 +77,15 @@ main (int argc, char *argv[])
/* Issue a read and trim that should not complete yet. Set up the
* trim to auto-retire via callback.
*/
- if ((cookie = nbd_aio_pread (nbd, buf, sizeof buf, 0, NULL, NULL, 0)) == -1) {
+ if ((cookie = nbd_aio_pread (nbd, buf, sizeof buf, 0,
+ NBD_NULL_CALLBACK(completion), 0)) == -1) {
fprintf (stderr, "%s: test failed: nbd_aio_pread: %s\n", argv[0],
nbd_get_error ());
exit (EXIT_FAILURE);
}
- if (nbd_aio_trim (nbd, sizeof buf, 0, callback, NULL, 0) == -1) {
+ if (nbd_aio_trim (nbd, sizeof buf, 0,
+ (nbd_completion_callback) { .callback = callback },
+ 0) == -1) {
fprintf (stderr, "%s: test failed: nbd_aio_trim: %s\n", argv[0],
nbd_get_error ());
exit (EXIT_FAILURE);
--
2.22.0