bytecodealliance / rustix

Safe Rust bindings to POSIX-ish APIs
Other
1.48k stars 159 forks source link

Feature request: Export `io_uring_buf_ring` #1143

Open ryanseipp opened 2 months ago

ryanseipp commented 2 months ago

io_uring utilizes a struct called io_uring_buf_ring to register a ring buffer of io_uring_buf structs that contain a reference to slices of buffers that can be filled in certain operations. One operation that can utilize this is IoringOp::Recv with the IoringRecvFlags::MULTISHOT flag set. This can make for much more performant operations, especially for those using direct io, as the kernel can choose a buffer to utilize, allowing the application to have many more recv operations in flight than available buffers.

This struct was added to linux 5.19, and is defined here.

linux_raw_sys 0.4 exports this struct here, which contains an anonymous union and C flexible array member. libc does not export this type.

I see we hand-code structs instead of re-exporting them, seemingly because libc doesn't export those structs. So, I'm primarily looking for guidance on how to define the flexible array member. I'd be happy to contribute this struct if someone doesn't go for it first.

sunfishcode commented 2 months ago

First, this is cool, thanks for working on this!

Currently rustix's io_uring API uses zero-length arrays, such as here. That is simple, however, that's not ergonomic as it requires users to use .as_ptr() and unsafe code and manual pointer arithmetic to access the contents.

I think it might be better to add a type like bindgen's __IncompleteArrayField to rustix's public API, and then use that to describe the flexible arrays. It still requires unsafe code, but it encapsulates the pointer arithmetic. Does that sound reasonable?

ryanseipp commented 2 months ago

Adding an __IncompleteArrayField does sound reasonable to me. Don't think there's a way to avoid unsafe here, so providing a little more utility seems reasonable. I'll give this a go and see where we can get to.

Was going to ask about updating that cmd union member to use the new struct, but it seems we'd technically be reducing the type's API to one that's more restrictive, and would be a breaking change?