Skip to main content

UringDriver

Struct UringDriver 

Source
pub struct UringDriver { /* private fields */ }

Implementations§

Source§

impl UringDriver

Source

pub fn probe_and_start(entries: u32) -> Result<Self, ProbeFailure>

Create the ring AND verify a real IORING_OP_READ round-trip on a temp file before accepting work. io_uring_setup succeeding is not enough: gVisor/seccomp environments can create a ring whose ops then fail with ENOSYS/EINVAL (backlog#894 probe design). Start a single-ring driver. Identical to probe_and_start_sharded(entries, 1).

Source

pub fn probe_and_start_sharded( entries: u32, shards: usize, ) -> Result<Self, ProbeFailure>

Start a driver backed by shards independent rings, each with entries SQ slots and its own driver thread.

Use more than one shard when the workload hits the page cache: such reads complete inline in io_uring_enter, so a single driver thread performs every one of their memcpys and caps the driver at one core’s memory bandwidth. Measured on a 16-core host (rustfs/backlog#1145): 1 ring → 4890 MB/s, 2 → 8969 MB/s, 4 → 15806 MB/s, with per-ring throughput flat. Reads that miss the cache are device-bound and do not need sharding.

In-flight ops are capped at entries per shard (the invariant that makes CQ overflow structurally unreachable holds per ring), so the whole driver admits up to shards * entries concurrent reads.

shards is clamped to at least 1. Probing happens on the first shard, so a restricted environment fails exactly as it does for a single ring; if a later shard fails to start, the ones already running are shut down and joined before the error is returned.

Source

pub fn read_at(&self, file: Arc<File>, offset: u64, len: usize) -> ReadHandle

Positioned read (pread semantics) — regular files, buffered.

Source

pub fn read_current(&self, file: Arc<File>, len: usize) -> ReadHandle

Read at the file’s current position (read(2) semantics) — pipes.

Source

pub fn read_at_direct( &self, file: Arc<File>, offset: u64, len: usize, align: usize, ) -> ReadHandle

Positioned read from a file opened with O_DIRECT (rustfs/backlog#1102).

align is the device’s logical block size — a power of two, typically 512 or 4096. offset and len are the caller’s logical range and need no alignment: the driver reads the block-aligned superset range into a block-aligned buffer and returns exactly [offset, offset + len). Alignment padding never reaches the caller, so a BitrotReader expecting an exact shard length never sees padded output.

The caller must have opened file with O_DIRECT; otherwise this is just a (correct but pointless) buffered read of the superset range.

Source

pub fn stats(&self) -> StatsSnapshot

Counters summed across every shard. The conservation identities the cancel-safety tests assert (submitted == delivered + orphan_reclaimed, in_flight == 0 after a clean drain) hold per shard, so they hold for the sum.

Source

pub fn shutdown(self) -> StatsSnapshot

Stop accepting work, cancel all in-flight ops, drain every ring to in_flight == 0, then join each driver thread. Only after that is a ring dropped/unmapped — the shutdown ordering P2 requires, per shard.

Shards are asked to stop first and joined afterwards, so their bounded drains overlap instead of serializing shards * DRAIN_TIMEOUT.

Trait Implementations§

Source§

impl Drop for UringDriver

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.