use core::ffi::c_long;
use crate::ffi::{
self, IORING_ENTER_REGISTERED_RING, IORING_REGISTER_FILES2, IORING_REGISTER_FILES_UPDATE,
IORING_REGISTER_RING_FDS, SYS_IO_URING_REGISTER,
};
use crate::layout::{
IORING_RSRC_REGISTER_SPARSE, IoUringFilesUpdate, IoUringRsrcRegister, IoUringRsrcUpdate,
};
use crate::pbr::ProvidedBufRing;
use crate::ring::IoUring;
use std::io;
impl IoUring {
pub fn register_buf_ring(
&self,
entries: u16,
buf_size: u32,
bgid: u16,
) -> io::Result<ProvidedBufRing> {
ProvidedBufRing::new(self.ring_fd, entries, buf_size, bgid)
}
pub(crate) fn try_register_ring_fd(&mut self) {
let mut upd = IoUringRsrcUpdate {
offset: u32::MAX,
resv: 0,
data: self.ring_fd as u32 as u64,
};
let ret = unsafe {
ffi::syscall(
SYS_IO_URING_REGISTER,
self.ring_fd as c_long,
IORING_REGISTER_RING_FDS as c_long,
&mut upd as *mut _ as c_long,
1 as c_long,
)
};
if ret == 1 {
self.enter_ring = Some((upd.offset, IORING_ENTER_REGISTERED_RING));
}
}
pub fn register_files_sparse(&self, nr: u32) -> io::Result<()> {
let reg = IoUringRsrcRegister {
nr,
flags: IORING_RSRC_REGISTER_SPARSE,
..Default::default()
};
let ret = unsafe {
ffi::syscall(
SYS_IO_URING_REGISTER,
self.ring_fd as c_long,
IORING_REGISTER_FILES2 as c_long,
® as *const _ as c_long,
core::mem::size_of::<IoUringRsrcRegister>() as c_long,
)
};
if ret < 0 {
return Err(io::Error::last_os_error());
}
Ok(())
}
pub fn update_file_slot(&self, index: u32, fd: i32) -> io::Result<()> {
let fd_val: i32 = fd;
let upd = IoUringFilesUpdate {
offset: index,
resv: 0,
fds: (&fd_val as *const i32) as u64,
};
let ret = unsafe {
ffi::syscall(
SYS_IO_URING_REGISTER,
self.ring_fd as c_long,
IORING_REGISTER_FILES_UPDATE as c_long,
&upd as *const _ as c_long,
1 as c_long,
)
};
if ret < 0 {
return Err(io::Error::last_os_error());
}
Ok(())
}
}