Skip to content

Commit

Permalink
vendor IoBuf/IoBufMut from tokio-uring (#24)
Browse files Browse the repository at this point in the history
In the draft PR for [`open_at`
support](#21) we
need an `OpenOptions` struct. Sadly we can't re-use the one from
`tokio-uring` because it doesn't have a public API for the conversion of
OpenOptions into the relevant libc flags.

We created [a PR asking for such an
API](neondatabase/tokio-uring#1), but, in the
meantime, let's unblock ourselves by vendoring the pieces of
`tokio-uring` that we need, and cusotmize them as needed.

This PR starts that effort by vendoring the `IoBuf`/`IoBufMut` traits as
well as `tokio-uring`'s approach to support slice-like operations.
Support for `OpenOptions` will follow as part of [the PR that adds
`open_at` support on top of this
PR](#25).

The files that reproduce the `tokio-uring` LICENSE text at the top are
copied from `tokio-uring.git:d5e90539bd6d1c518e848298564a098c300866bc`.
Files without it were written by myself.

To make `cargo test` pass, I had to remove the examples in the doc
comments.
  • Loading branch information
problame authored Nov 22, 2023
1 parent 8e20144 commit 91d67e2
Show file tree
Hide file tree
Showing 20 changed files with 718 additions and 11 deletions.
11 changes: 9 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
members = [
"tokio-epoll-uring",
"benchmark",
"uring-common",
]
3 changes: 1 addition & 2 deletions tokio-epoll-uring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ license = "MIT OR Apache-2.0"

[dependencies]
futures = "0.3.28"
io-uring = "0.6.0"
once_cell = "1.18.0"
scopeguard = "1.1.0"
thiserror = "1.0.44"
tokio = { version = "1.29.1", features = ["io-std", "full"] }
tokio-uring = "0.4.0"
tokio-util = "0.7.8"
tracing = "0.1.37"
uring-common = { path = "../uring-common" }

[dev-dependencies]
tokio = { version = "1.29.1", features = ["full"] }
Expand Down
2 changes: 1 addition & 1 deletion tokio-epoll-uring/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub use system::lifecycle::thread_local::{thread_local_system, Handle};
pub use system::lifecycle::System;
pub use system::submission::op_fut::Error as SystemError;

pub use tokio_uring::buf::{IoBuf, IoBufMut};
pub use uring_common::buf::{IoBuf, IoBufMut};

pub(crate) mod util;

Expand Down
2 changes: 2 additions & 0 deletions tokio-epoll-uring/src/ops/nop.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use uring_common::io_uring;

use crate::system::submission::op_fut::Op;

pub struct Nop {}
Expand Down
10 changes: 6 additions & 4 deletions tokio-epoll-uring/src/ops/read.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
use std::os::fd::{AsRawFd, OwnedFd};

use uring_common::{buf::IoBufMut, io_uring};

use crate::system::submission::op_fut::Op;

pub struct ReadOp<B>
where
B: tokio_uring::buf::IoBufMut + Send,
B: IoBufMut + Send,
{
pub(crate) file: OwnedFd,
pub(crate) offset: u64,
pub(crate) buf: B,
}

impl<B> crate::sealed::Sealed for ReadOp<B> where B: tokio_uring::buf::IoBufMut + Send {}
impl<B> crate::sealed::Sealed for ReadOp<B> where B: IoBufMut + Send {}

impl<B> Op for ReadOp<B>
where
B: tokio_uring::buf::IoBufMut + Send,
B: IoBufMut + Send,
{
type Resources = (OwnedFd, B);
type Success = usize;
Expand Down Expand Up @@ -43,7 +45,7 @@ where
let res = if res < 0 {
Err(std::io::Error::from_raw_os_error(-res))
} else {
unsafe { tokio_uring::buf::IoBufMut::set_init(&mut self.buf, res as usize) };
unsafe { IoBufMut::set_init(&mut self.buf, res as usize) };
Ok(res as usize)
};
((self.file, self.buf), res)
Expand Down
1 change: 1 addition & 0 deletions tokio-epoll-uring/src/system/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
use io_uring::CompletionQueue;
use tokio::sync::{self, broadcast, mpsc, oneshot};
use tracing::{debug, info, info_span, trace, Instrument};
use uring_common::io_uring;

use crate::{system::submission::SubmitSideInner, util::oneshot_nonconsuming};

Expand Down
1 change: 1 addition & 0 deletions tokio-epoll-uring/src/system/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod handle;
pub mod thread_local;

use io_uring::{CompletionQueue, SubmissionQueue, Submitter};
use uring_common::io_uring;

use crate::{
system::{completion::ShutdownRequestImpl, RING_SIZE},
Expand Down
2 changes: 1 addition & 1 deletion tokio-epoll-uring/src/system/lifecycle/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use futures::FutureExt;
use std::{os::fd::OwnedFd, task::ready};
use tokio_uring::buf::IoBufMut;
use uring_common::buf::IoBufMut;

use crate::{
ops::read::ReadOp,
Expand Down
1 change: 1 addition & 0 deletions tokio-epoll-uring/src/system/slots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use std::{

use tokio::sync::oneshot;
use tracing::{debug, trace};
use uring_common::io_uring;

use crate::system::submission::op_fut::Error;

Expand Down
1 change: 1 addition & 0 deletions tokio-epoll-uring/src/system/submission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
};

use io_uring::{SubmissionQueue, Submitter};
use uring_common::io_uring;

use super::{
completion::CompletionSide,
Expand Down
2 changes: 2 additions & 0 deletions tokio-epoll-uring/src/system/submission/op_fut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub trait Op: crate::sealed::Sealed + Sized + Send + 'static {
fn make_sqe(&mut self) -> io_uring::squeue::Entry;
}

use uring_common::io_uring;

use crate::system::{
completion::ProcessCompletionsCause,
slots::{self, SlotHandle},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::sync::{Arc, RwLock};

use futures::Future;
use uring_common::buf::IoBufMut;

use crate::SystemError;
use crate::{System, SystemHandle};
Expand Down Expand Up @@ -42,7 +43,7 @@ impl SharedSystemHandle {
.initiate_shutdown()
}

pub fn read<B: tokio_uring::buf::IoBufMut + Send>(
pub fn read<B: IoBufMut + Send>(
&self,
file: std::os::fd::OwnedFd,
offset: u64,
Expand Down
10 changes: 10 additions & 0 deletions uring-common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "uring-common"
version = "0.1.0"
edition = "2021"
description = "a subset of types from the `tokio-uring` crate"
license = "MIT" # the same as tokio-uring at the time we forked it

[dependencies]
libc = "0.2.80"
io-uring = "0.6.0"
60 changes: 60 additions & 0 deletions uring-common/src/buf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2021 Carl Lerche
//
// Permission is hereby granted, free of charge, to any
// person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the
// Software without restriction, including without
// limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice
// shall be included in all copies or substantial portions
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
//
// Based on tokio-uring.git:d5e90539bd6d1c518e848298564a098c300866bc

//! Utilities for working with buffers.
//!
//! `io-uring` APIs require passing ownership of buffers to the runtime. The
//! crate defines [`IoBuf`] and [`IoBufMut`] traits which are implemented by buffer
//! types that respect the `io-uring` contract.
// pub mod fixed;

mod io_buf;
pub use io_buf::IoBuf;

mod io_buf_mut;
pub use io_buf_mut::IoBufMut;

mod slice;
pub use slice::Slice;

mod bounded;
pub use bounded::{BoundedBuf, BoundedBufMut};

pub(crate) fn deref(buf: &impl IoBuf) -> &[u8] {
// Safety: the `IoBuf` trait is marked as unsafe and is expected to be
// implemented correctly.
unsafe { std::slice::from_raw_parts(buf.stable_ptr(), buf.bytes_init()) }
}

pub(crate) fn deref_mut(buf: &mut impl IoBufMut) -> &mut [u8] {
// Safety: the `IoBufMut` trait is marked as unsafe and is expected to be
// implemented correct.
unsafe { std::slice::from_raw_parts_mut(buf.stable_mut_ptr(), buf.bytes_init()) }
}
Loading

0 comments on commit 91d67e2

Please sign in to comment.