See the earlier commit "Add Extent64 arg type" for rationale in
supporting a new generator arg type. This patch adds the Rust
bindings for use of Extent64.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Tage, could you please review this patch? I'm about to commit my
64-bit extension patches, but had to rebase them on top of your Rust
patches that landed in the meantime. I'm new enough to Rust that I'm
not sure if I'm doing everything in the optimum manner, so I welcome
any insights you may offer.
This email is one of the two main patches I'm worried about, I'll
reply again with a link to a git repo and the diff to the generated
code after this patch plus minor tweaks to 9 and 10/25 are in place to
actually put this code to use (uncommenting extent64_callback and
actually defining the nbd_block_status_64 API is what makes the code
paths in this patch worth anything); plus the relevant changes to
patch to 11/25 that copies the language bindings unit tests I did for
all the other bindings to also work in Rust.
My thinking in this patch: the public libnbd crate should expose a
full-fledged Rust type NbdExport, while the low-level libnbd-sys code
needs an ffi interface that mirrors C's 'struct nbd_extent' from the
generated <libnbd.h>. Since my unit test passed (soon to be posted in
the next email), I assume I got things right, but I could be easily
doing something stupid that 'unsafe' let me blindly paper over.
---
generator/Rust.ml | 8 ++++++--
generator/RustSys.ml | 15 +++++++++++----
rust/src/types.rs | 6 ++++++
3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/generator/Rust.ml b/generator/Rust.ml
index b9c938e8..3babc1a5 100644
--- a/generator/Rust.ml
+++ b/generator/Rust.ml
@@ -108,6 +108,7 @@ let
| Path n
| Fd n
| Enum (n, _)
+ | Extent64 n
| Flags (n, _)
| SockAddrAndLen (n, _)
| BytesIn (n, _)
@@ -116,7 +117,6 @@ let
| BytesPersistOut (n, _)
| Closure { cbname = n } ->
n
- | Extent64 _ -> assert false (* only used in extent64_closure *)
(* Get the name of a rust optional argument. *)
let rust_optarg_name : optarg -> string = function
@@ -151,7 +151,7 @@ let
| BytesPersistIn _ -> "&'static [u8]"
| BytesPersistOut _ -> "&'static mut [u8]"
| Closure { cbargs } -> "impl " ^ rust_closure_trait cbargs
- | Extent64 _ -> assert false (* only used in extent64_closure *)
+ | Extent64 _ -> "NbdExtent"
(* Get the Rust closure trait for a callback, That is `Fn*(...) -> ...)`. *)
and rust_closure_trait ?(lifetime = Some "'static") cbargs : string =
@@ -232,6 +232,7 @@ let
| CBString _ -> [ "*const c_char" ]
| CBBytesIn _ -> [ "*const c_void"; "usize" ]
| CBArrayAndLen (UInt32 _, _) -> [ "*mut u32"; "usize" ]
+ | CBArrayAndLen (Extent64 _, _) -> [ "*mut nbd_extent"; "usize"
]
| CBArrayAndLen _ ->
failwith
"generator/Rust.ml: in ffi_cbarg_types: Unsupported type of array \
@@ -377,6 +378,8 @@ let
ffi_len_name
| CBArrayAndLen (UInt32 _, _), [ ffi_arr_name; ffi_len_name ] ->
pr "slice::from_raw_parts(%s, %s)" ffi_arr_name ffi_len_name
+ | CBArrayAndLen (Extent64 _, _), [ ffi_arr_name; ffi_len_name ] ->
+ pr "slice::from_raw_parts(%s as *const NbdExtent, %s)" ffi_arr_name
ffi_len_name
| CBArrayAndLen _, [ _; _ ] ->
failwith
"generator/Rust.ml: in ffi_cbargs_to_rust: Unsupported type of array \
@@ -553,6 +556,7 @@ let
pr "use std::path::PathBuf;\n";
pr "use std::ptr;\n";
pr "use std::slice;\n";
+ (* pr "use libnbd_sys::nbd_extent;\n"; uncomment for extent64_callback *)
pr "\n"
let generate_rust_bindings () =
diff --git a/generator/RustSys.ml b/generator/RustSys.ml
index be01ab8d..1025c699 100644
--- a/generator/RustSys.ml
+++ b/generator/RustSys.ml
@@ -39,7 +39,7 @@ let
| BytesIn (n1, n2) | BytesPersistIn (n1, n2) -> [ "*const c_void";
"usize" ]
| BytesOut (n1, n2) | BytesPersistOut (n1, n2) -> [ "*mut c_void";
"usize" ]
| Closure { cbname } -> [ sprintf "nbd_%s_callback" cbname ]
- | Extent64 _ -> assert false (* only used in extent64_closure *)
+ | Extent64 (_) -> [ "nbd_extent" ]
(** The type of an optional argument. *)
let optarg_type : optarg -> string = function
@@ -133,13 +133,20 @@ let
|> String.concat ", ")
(ret_type call.ret)
-(** Print a definition of the "nbd_handle" type. *)
-let print_nbd_handle () =
+(** Print a definition of "nbd_handle" and "nbd_extent" types. *)
+let print_types () =
pr "#[repr(C)]\n";
pr "#[derive(Debug, Clone, Copy)]\n";
pr "pub struct nbd_handle {\n";
pr " _unused: [u8; 0],\n";
pr "}\n";
+ pr "\n";
+ pr "#[repr(C)]\n";
+ pr "#[derive(Debug, Clone, Copy)]\n";
+ pr "pub struct nbd_extent {\n";
+ pr " length: u64,\n";
+ pr " flags: u64,\n";
+ pr "}\n";
pr "\n"
(** Print some more "extern definitions". *)
@@ -161,7 +168,7 @@ let
generate_header CStyle ~copyright:"Tage Johansson";
pr "\n";
print_imports ();
- print_nbd_handle ();
+ print_types ();
print_more_defs ();
all_closures |> List.iter print_closure_struct;
pr "extern \"C\" {\n";
diff --git a/rust/src/types.rs b/rust/src/types.rs
index eb2df060..6bce2888 100644
--- a/rust/src/types.rs
+++ b/rust/src/types.rs
@@ -16,3 +16,9 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
pub struct Cookie(pub(crate) u64);
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct NbdExtent {
+ pub length: u64,
+ pub flags: u64,
+}
--
2.41.0