rust/kernel/iov.rs

Source file repositories/reference/linux-study-clean/rust/kernel/iov.rs

File Facts

System
Linux kernel
Corpus path
rust/kernel/iov.rs
Extension
.rs
Size
12443 bytes
Lines
315
Domain
Rust Kernel Layer
Bucket
Rust API Membrane
Inferred role
Rust Kernel Layer: implementation source
Status
source implementation candidate

Why This File Exists

Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.

Dependency Surface

Detected Declarations

Annotated Snippet

pub fn advance(&mut self, bytes: usize) {
        // SAFETY: By the type invariants, `self.iov` is a valid IO vector.
        unsafe { bindings::iov_iter_advance(self.as_raw(), bytes) };
    }

    /// Advance this IO vector backwards by `bytes` bytes.
    ///
    /// # Safety
    ///
    /// The IO vector must not be reverted to before its beginning.
    #[inline]
    pub unsafe fn revert(&mut self, bytes: usize) {
        // SAFETY: By the type invariants, `self.iov` is a valid IO vector, and the caller
        // ensures that `bytes` is in bounds.
        unsafe { bindings::iov_iter_revert(self.as_raw(), bytes) };
    }

    /// Read data from this IO vector.
    ///
    /// Returns the number of bytes that have been copied.
    #[inline]
    pub fn copy_from_iter(&mut self, out: &mut [u8]) -> usize {
        // SAFETY: `Self::copy_from_iter_raw` guarantees that it will not write any uninitialized
        // bytes in the provided buffer, so `out` is still a valid `u8` slice after this call.
        let out = unsafe { &mut *(ptr::from_mut(out) as *mut [MaybeUninit<u8>]) };

        self.copy_from_iter_raw(out).len()
    }

    /// Read data from this IO vector and append it to a vector.
    ///
    /// Returns the number of bytes that have been copied.
    #[inline]
    pub fn copy_from_iter_vec<A: Allocator>(
        &mut self,
        out: &mut Vec<u8, A>,
        flags: Flags,
    ) -> Result<usize> {
        out.reserve(self.len(), flags)?;
        let len = self.copy_from_iter_raw(out.spare_capacity_mut()).len();
        // SAFETY:
        // - `len` is the length of a subslice of the spare capacity, so `len` is at most the
        //   length of the spare capacity.
        // - `Self::copy_from_iter_raw` guarantees that the first `len` bytes of the spare capacity
        //   have been initialized.
        unsafe { out.inc_len(len) };
        Ok(len)
    }

    /// Read data from this IO vector into potentially uninitialized memory.
    ///
    /// Returns the sub-slice of the output that has been initialized. If the returned slice is
    /// shorter than the input buffer, then the entire IO vector has been read.
    ///
    /// This will never write uninitialized bytes to the provided buffer.
    #[inline]
    pub fn copy_from_iter_raw(&mut self, out: &mut [MaybeUninit<u8>]) -> &mut [u8] {
        let capacity = out.len();
        let out = out.as_mut_ptr().cast::<u8>();

        // GUARANTEES: The C API guarantees that it does not write uninitialized bytes to the
        // provided buffer.
        // SAFETY:
        // * By the type invariants, it is still valid to read from this IO vector.
        // * `out` is valid for writing for `capacity` bytes because it comes from a slice of
        //   that length.
        let len = unsafe { bindings::_copy_from_iter(out.cast(), capacity, self.as_raw()) };

        // SAFETY: The underlying C api guarantees that initialized bytes have been written to the
        // first `len` bytes of the spare capacity.
        unsafe { slice::from_raw_parts_mut(out, len) }
    }
}

/// An IO vector that acts as a destination for data.
///
/// IO vectors support many different types of destinations. This includes both buffers in
/// kernel-space and writing to userspace. It's possible that the destination buffer is mapped in a
/// thread-local manner using e.g. `kmap_local_page()`, so this type is not `Send` to ensure that
/// the mapping is written to the right context in that scenario.
///
/// # Invariants
///
/// Must hold a valid `struct iov_iter` with `data_source` set to `ITER_DEST`. For the duration of
/// `'data`, it must be safe to write to this IO vector using the standard C methods for this
/// purpose.
#[repr(transparent)]
pub struct IovIterDest<'data> {
    iov: Opaque<bindings::iov_iter>,
    /// Represent to the type system that this value contains a pointer to writable data it does

Annotation

Implementation Notes