#![cfg(target_os = "linux")]
#![allow(async_fn_in_trait)]
pub mod fs;
pub mod metadata;
pub mod uring;
use metadata::Metadata;
use once_cell::sync::Lazy;
use std::fs::File as StdFile;
use std::io;
use std::os::fd::AsRawFd;
use tokio::fs::File as TokioFile;
use uring::ReadResult;
use uring::Uring;
use uring::UringCfg;
use uring::WriteResult;
pub use uring::DEFAULT_RING_SIZE;
static DEFAULT_URING: Lazy<Uring> =
Lazy::new(|| Uring::new(UringCfg::default()).expect("failed to initialize io_uring"));
pub fn default_uring() -> &'static Uring {
&DEFAULT_URING
}
pub trait UringFile: AsRawFd {
async fn ur_read_at(&self, offset: u64, len: u64) -> io::Result<ReadResult<Vec<u8>>>;
async fn ur_read_exact_at(&self, offset: u64, len: u64) -> io::Result<Vec<u8>>;
async fn ur_write_at(&self, offset: u64, data: Vec<u8>) -> io::Result<WriteResult<Vec<u8>>>;
async fn ur_write_all_at(&self, offset: u64, data: &[u8]) -> io::Result<()>;
async fn ur_sync(&self) -> io::Result<()>;
async fn ur_datasync(&self) -> io::Result<()>;
async fn ur_statx(&self) -> io::Result<Metadata>;
async fn ur_fallocate(&self, offset: u64, len: u64, mode: i32) -> io::Result<()>;
async fn ur_fadvise(&self, offset: u64, len: u64, advice: i32) -> io::Result<()>;
async fn ur_ftruncate(&self, len: u64) -> io::Result<()>;
}
impl UringFile for StdFile {
async fn ur_read_at(&self, offset: u64, len: u64) -> io::Result<ReadResult<Vec<u8>>> {
DEFAULT_URING.read_at(self, offset, len).await
}
async fn ur_read_exact_at(&self, offset: u64, len: u64) -> io::Result<Vec<u8>> {
DEFAULT_URING.read_exact_at(self, offset, len).await
}
async fn ur_write_at(&self, offset: u64, data: Vec<u8>) -> io::Result<WriteResult<Vec<u8>>> {
DEFAULT_URING.write_at(self, offset, data).await
}
async fn ur_write_all_at(&self, offset: u64, data: &[u8]) -> io::Result<()> {
DEFAULT_URING.write_all_at(self, offset, data).await
}
async fn ur_sync(&self) -> io::Result<()> {
DEFAULT_URING.sync(self).await
}
async fn ur_datasync(&self) -> io::Result<()> {
DEFAULT_URING.datasync(self).await
}
async fn ur_statx(&self) -> io::Result<Metadata> {
DEFAULT_URING.statx(self).await
}
async fn ur_fallocate(&self, offset: u64, len: u64, mode: i32) -> io::Result<()> {
DEFAULT_URING.fallocate(self, offset, len, mode).await
}
async fn ur_fadvise(&self, offset: u64, len: u64, advice: i32) -> io::Result<()> {
DEFAULT_URING.fadvise(self, offset, len, advice).await
}
async fn ur_ftruncate(&self, len: u64) -> io::Result<()> {
DEFAULT_URING.ftruncate(self, len).await
}
}
impl UringFile for TokioFile {
async fn ur_read_at(&self, offset: u64, len: u64) -> io::Result<ReadResult<Vec<u8>>> {
DEFAULT_URING.read_at(self, offset, len).await
}
async fn ur_read_exact_at(&self, offset: u64, len: u64) -> io::Result<Vec<u8>> {
DEFAULT_URING.read_exact_at(self, offset, len).await
}
async fn ur_write_at(&self, offset: u64, data: Vec<u8>) -> io::Result<WriteResult<Vec<u8>>> {
DEFAULT_URING.write_at(self, offset, data).await
}
async fn ur_write_all_at(&self, offset: u64, data: &[u8]) -> io::Result<()> {
DEFAULT_URING.write_all_at(self, offset, data).await
}
async fn ur_sync(&self) -> io::Result<()> {
DEFAULT_URING.sync(self).await
}
async fn ur_datasync(&self) -> io::Result<()> {
DEFAULT_URING.datasync(self).await
}
async fn ur_statx(&self) -> io::Result<Metadata> {
DEFAULT_URING.statx(self).await
}
async fn ur_fallocate(&self, offset: u64, len: u64, mode: i32) -> io::Result<()> {
DEFAULT_URING.fallocate(self, offset, len, mode).await
}
async fn ur_fadvise(&self, offset: u64, len: u64, advice: i32) -> io::Result<()> {
DEFAULT_URING.fadvise(self, offset, len, advice).await
}
async fn ur_ftruncate(&self, len: u64) -> io::Result<()> {
DEFAULT_URING.ftruncate(self, len).await
}
}