use std::ffi::CString;
use std::os::unix::io::RawFd;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct IoUringConfig {
pub sq_depth: u32,
pub enable_direct_io: bool,
pub batch_threshold: usize,
}
impl Default for IoUringConfig {
fn default() -> Self {
Self {
sq_depth: 256,
enable_direct_io: false,
batch_threshold: 4,
}
}
}
pub struct IoUringStorageState {
fds: Vec<RawFd>,
}
impl IoUringStorageState {
pub fn open_files(
base_dir: &Path,
file_paths: &[PathBuf],
flags: libc::c_int,
) -> std::io::Result<Self> {
let mut fds = Vec::with_capacity(file_paths.len());
for path in file_paths {
let full = base_dir.join(path);
let c_path = CString::new(full.as_os_str().as_encoded_bytes())
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
let fd = unsafe { libc::open(c_path.as_ptr(), flags, 0o644) };
if fd < 0 {
for &opened_fd in &fds {
unsafe {
libc::close(opened_fd);
}
}
return Err(std::io::Error::last_os_error());
}
fds.push(fd);
}
Ok(Self { fds })
}
pub fn fd(&self, file_index: usize) -> RawFd {
self.fds[file_index]
}
#[must_use]
pub fn len(&self) -> usize {
self.fds.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.fds.is_empty()
}
}
impl Drop for IoUringStorageState {
fn drop(&mut self) {
for &fd in &self.fds {
unsafe {
libc::close(fd);
}
}
}
}