Skip to content

Commit

Permalink
io-uring API updates. (#871)
Browse files Browse the repository at this point in the history
* io-uring API updates.

Add the `addr_len` field to `splice_fd_in_or_file_index_union`, define
the `io_uring_sync_cancel_reg` struct, and export the various flags
types used in the public API from the `io_uring` module so that users
don't need to enable "fs" or "net" themselves just to work with
`io_uring`.

* Make `Nsecs` be 64-bit on 32-bit x86 Linux.
  • Loading branch information
sunfishcode committed Oct 9, 2023
1 parent 0c22704 commit 112c268
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 28 deletions.
24 changes: 20 additions & 4 deletions src/backend/libc/fs/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -933,15 +933,23 @@ fn utimensat_old(
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_access.tv_nsec,
tv_nsec: times
.last_access
.tv_nsec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
},
c::timespec {
tv_sec: times
.last_modification
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_modification.tv_nsec,
tv_nsec: times
.last_modification
.tv_nsec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
},
];
unsafe {
Expand Down Expand Up @@ -1515,15 +1523,23 @@ fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> {
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_access.tv_nsec,
tv_nsec: times
.last_access
.tv_nsec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
},
c::timespec {
tv_sec: times
.last_modification
.tv_sec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
tv_nsec: times.last_modification.tv_nsec,
tv_nsec: times
.last_modification
.tv_nsec
.try_into()
.map_err(|_| io::Errno::OVERFLOW)?,
},
];

Expand Down
52 changes: 38 additions & 14 deletions src/io_uring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ use core::mem::MaybeUninit;
use core::ptr::{null_mut, write_bytes};
use linux_raw_sys::net;

// Export types used in io_uring APIs.
pub use crate::fs::{Advice, AtFlags, OFlags, RenameFlags, ResolveFlags, Statx};
pub use crate::net::{RecvFlags, SendFlags, SocketFlags};
pub use crate::timespec::Timespec;

mod sys {
pub(super) use linux_raw_sys::io_uring::*;
#[cfg(test)]
Expand Down Expand Up @@ -1062,20 +1067,20 @@ pub union op_flags_union {
pub sync_range_flags: u32,
/// `msg_flags` is split into `send_flags` and `recv_flags`.
#[doc(alias = "msg_flags")]
pub send_flags: crate::net::SendFlags,
pub send_flags: SendFlags,
/// `msg_flags` is split into `send_flags` and `recv_flags`.
#[doc(alias = "msg_flags")]
pub recv_flags: crate::net::RecvFlags,
pub recv_flags: RecvFlags,
pub timeout_flags: IoringTimeoutFlags,
pub accept_flags: crate::net::SocketFlags,
pub accept_flags: SocketFlags,
pub cancel_flags: IoringAsyncCancelFlags,
pub open_flags: crate::fs::OFlags,
pub statx_flags: crate::fs::AtFlags,
pub fadvise_advice: crate::fs::Advice,
pub open_flags: OFlags,
pub statx_flags: AtFlags,
pub fadvise_advice: Advice,
pub splice_flags: SpliceFlags,
pub rename_flags: crate::fs::RenameFlags,
pub unlink_flags: crate::fs::AtFlags,
pub hardlink_flags: crate::fs::AtFlags,
pub rename_flags: RenameFlags,
pub unlink_flags: AtFlags,
pub hardlink_flags: AtFlags,
pub msg_ring_flags: IoringMsgringFlags,
}

Expand All @@ -1087,12 +1092,33 @@ pub union buf_union {
pub buf_group: u16,
}

// TODO: Rename this to include `addr_len` when we have a semver bump?
#[allow(missing_docs)]
#[repr(C)]
#[derive(Copy, Clone)]
pub union splice_fd_in_or_file_index_union {
pub splice_fd_in: i32,
pub file_index: u32,
pub addr_len: addr_len_struct,
}

#[allow(missing_docs)]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct addr_len_struct {
pub addr_len: u16,
pub __pad3: [u16; 1],
}

#[allow(missing_docs)]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct io_uring_sync_cancel_reg {
pub addr: u64,
pub fd: i32,
pub flags: IoringAsyncCancelFlags,
pub timeout: Timespec,
pub pad: [u64; 4],
}

/// An io_uring Completion Queue Entry.
Expand Down Expand Up @@ -1269,16 +1295,12 @@ pub struct iovec {
#[derive(Debug, Copy, Clone, Default)]
pub struct open_how {
/// An [`OFlags`] value represented as a `u64`.
///
/// [`OFlags`]: crate::fs::OFlags
pub flags: u64,

/// A [`Mode`] value represented as a `u64`.
///
/// [`Mode`]: crate::fs::Mode
pub mode: u64,

pub resolve: crate::fs::ResolveFlags,
pub resolve: ResolveFlags,
}

#[allow(missing_docs)]
Expand Down Expand Up @@ -1377,6 +1399,7 @@ fn io_uring_layouts() {
check_renamed_type!(op_flags_union, io_uring_sqe__bindgen_ty_3);
check_renamed_type!(buf_union, io_uring_sqe__bindgen_ty_4);
check_renamed_type!(splice_fd_in_or_file_index_union, io_uring_sqe__bindgen_ty_5);
check_renamed_type!(addr_len_struct, io_uring_sqe__bindgen_ty_5__bindgen_ty_1);
check_renamed_type!(
register_or_sqe_op_or_sqe_flags_union,
io_uring_restriction__bindgen_ty_1
Expand Down Expand Up @@ -1460,4 +1483,5 @@ fn io_uring_layouts() {
check_struct!(open_how, flags, mode, resolve);
check_struct!(io_uring_buf_reg, ring_addr, ring_entries, bgid, pad, resv);
check_struct!(io_uring_buf, addr, len, bid, resv);
check_struct!(io_uring_sync_cancel_reg, addr, fd, flags, timeout, pad);
}
25 changes: 15 additions & 10 deletions src/timespec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! `Timespec` and related types, which are used by multiple public API
//! modules.

#[cfg(not(fix_y2038))]
use crate::backend::c;

/// `struct timespec`
Expand Down Expand Up @@ -28,18 +29,22 @@ pub type Secs = c::time_t;
#[cfg(fix_y2038)]
pub type Secs = i64;

/// A type for the `tv_nsec` field of [`Timespec`].
#[cfg(all(libc, target_arch = "x86_64", target_pointer_width = "32"))]
/// A type for the `tv_sec` field of [`Timespec`].
#[cfg(any(
fix_y2038,
linux_raw,
all(libc, target_arch = "x86_64", target_pointer_width = "32")
))]
pub type Nsecs = i64;

/// A type for the `tv_nsec` field of [`Timespec`].
#[cfg(all(libc, not(all(target_arch = "x86_64", target_pointer_width = "32"))))]
#[cfg(all(
not(fix_y2038),
libc,
not(all(target_arch = "x86_64", target_pointer_width = "32"))
))]
pub type Nsecs = c::c_long;

/// A type for the `tv_nsec` field of [`Timespec`].
#[cfg(linux_raw)]
pub type Nsecs = i64;

/// On 32-bit glibc platforms, `timespec` has anonymous padding fields, which
/// Rust doesn't support yet (see `unnamed_fields`), so we define our own
/// struct with explicit padding, with bidirectional `From` impls.
Expand All @@ -52,7 +57,7 @@ pub(crate) struct LibcTimespec {
#[cfg(target_endian = "big")]
padding: core::mem::MaybeUninit<u32>,

pub(crate) tv_nsec: Nsecs,
pub(crate) tv_nsec: i32,

#[cfg(target_endian = "little")]
padding: core::mem::MaybeUninit<u32>,
Expand All @@ -64,7 +69,7 @@ impl From<LibcTimespec> for Timespec {
fn from(t: LibcTimespec) -> Self {
Self {
tv_sec: t.tv_sec,
tv_nsec: t.tv_nsec,
tv_nsec: t.tv_nsec as _,
}
}
}
Expand All @@ -75,7 +80,7 @@ impl From<Timespec> for LibcTimespec {
fn from(t: Timespec) -> Self {
Self {
tv_sec: t.tv_sec,
tv_nsec: t.tv_nsec,
tv_nsec: t.tv_nsec as _,
padding: core::mem::MaybeUninit::uninit(),
}
}
Expand Down

0 comments on commit 112c268

Please sign in to comment.