Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add preadv & pwritev support #101

Merged
merged 13 commits into from
Oct 19, 2023
26 changes: 26 additions & 0 deletions compio-driver/src/iour/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ impl<T: IoBufMut> OpCode for ReadAt<T> {
}
}

impl<T: IoVectoredBufMut> OpCode for ReadVectoredAt<T> {
fn create_entry(mut self: Pin<&mut Self>) -> Entry {
self.slices = unsafe { self.buffer.as_io_slices_mut() };
opcode::Readv::new(
Fd(self.fd),
self.slices.as_ptr() as _,
self.slices.len() as _,
)
.offset(self.offset)
.build()
}
}

impl<T: IoBuf> OpCode for WriteAt<T> {
fn create_entry(self: Pin<&mut Self>) -> Entry {
let slice = self.buffer.as_slice();
Expand All @@ -33,6 +46,19 @@ impl<T: IoBuf> OpCode for WriteAt<T> {
}
}

impl<T: IoVectoredBuf> OpCode for WriteVectoredAt<T> {
fn create_entry(mut self: Pin<&mut Self>) -> Entry {
self.slices = unsafe { self.buffer.as_io_slices() };
opcode::Write::new(
Fd(self.fd),
self.slices.as_ptr() as _,
self.slices.len() as _,
)
.offset(self.offset)
.build()
}
}

impl OpCode for Sync {
fn create_entry(self: Pin<&mut Self>) -> Entry {
opcode::Fsync::new(Fd(self.fd))
Expand Down
27 changes: 13 additions & 14 deletions compio-driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,31 +66,30 @@ macro_rules! syscall {
#[macro_export]
#[doc(hidden)]
macro_rules! syscall {
($fn: ident ( $($arg: expr),* $(,)* ) ) => {{
#[allow(unused_unsafe)]
let res = unsafe { ::libc::$fn($($arg, )*) };
Berrysoft marked this conversation as resolved.
Show resolved Hide resolved
if res == -1 {
Err(::std::io::Error::last_os_error())
} else {
Ok(res)
}
}};
// The below branches are used by polling driver.
(break $fn: ident ( $($arg: expr),* $(,)* )) => {
match $crate::syscall!( $fn ( $($arg, )* )) {
(break $e:expr) => {
match $crate::syscall!($e) {
Ok(fd) => ::std::task::Poll::Ready(Ok(fd as usize)),
Err(e) if e.kind() == ::std::io::ErrorKind::WouldBlock || e.raw_os_error() == Some(::libc::EINPROGRESS)
=> ::std::task::Poll::Pending,
Err(e) => ::std::task::Poll::Ready(Err(e)),
}
};
($fn: ident ( $($arg: expr),* $(,)* ) or $f:ident($fd:expr)) => {
match $crate::syscall!( break $fn ( $($arg, )* )) {
($e:expr, $f:ident($fd:expr)) => {
match $crate::syscall!(break $e) {
::std::task::Poll::Pending => Ok($crate::Decision::$f($fd)),
::std::task::Poll::Ready(Ok(res)) => Ok($crate::Decision::Completed(res)),
::std::task::Poll::Ready(Err(e)) => Err(e),
}
};
($e:expr) => {{
#[allow(unused_unsafe)]
let res = unsafe { $e };
if res == -1 {
Err(::std::io::Error::last_os_error())
} else {
Ok(res)
}
}};
}

#[macro_export]
Expand Down
2 changes: 2 additions & 0 deletions compio-driver/src/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub use crate::sys::op::{
Accept, Recv, RecvFrom, RecvFromVectored, RecvVectored, Send, SendTo, SendToVectored,
SendVectored,
};
#[cfg(unix)]
pub use crate::sys::op::{ReadVectoredAt, WriteVectoredAt};
use crate::{sockaddr_storage, socklen_t, RawFd};

/// Trait to update the buffer length inside the [`BufResult`].
Expand Down
2 changes: 1 addition & 1 deletion compio-driver/src/poll/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ impl Driver {
pub fn attach(&mut self, fd: RawFd) -> io::Result<()> {
if cfg!(any(target_os = "linux", target_os = "android")) {
let mut stat = unsafe { std::mem::zeroed() };
syscall!(fstat(fd, &mut stat))?;
syscall!(libc::fstat(fd, &mut stat))?;
if matches!(stat.st_mode & libc::S_IFMT, libc::S_IFREG | libc::S_IFDIR) {
return Ok(());
}
Expand Down
Loading