// SPDX-License-Identifier: GPL-2.012// Copyright (C) 2025 Google LLC.34//! IO vectors.5//!6//! C headers: [`include/linux/iov_iter.h`](srctree/include/linux/iov_iter.h),7//! [`include/linux/uio.h`](srctree/include/linux/uio.h)89use crate::{10alloc::{Allocator, Flags},11bindings,12prelude::*,13types::Opaque,14};15use core::{marker::PhantomData, mem::MaybeUninit, ptr, slice};1617const ITER_SOURCE: bool = bindings::ITER_SOURCE != 0;18const ITER_DEST: bool = bindings::ITER_DEST != 0;1920// Compile-time assertion for the above constants.21const _: () = {22build_assert!(23ITER_SOURCE != ITER_DEST,24"ITER_DEST and ITER_SOURCE should be different."25);26};2728/// An IO vector that acts as a source of data.29///30/// The data may come from many different sources. This includes both things in kernel-space and31/// reading from userspace. It's not necessarily the case that the data source is immutable, so32/// rewinding the IO vector to read the same data twice is not guaranteed to result in the same33/// bytes. It's also possible that the data source is mapped in a thread-local manner using e.g.34/// `kmap_local_page()`, so this type is not `Send` to ensure that the mapping is read from the35/// right context in that scenario.36///37/// # Invariants38///39/// Must hold a valid `struct iov_iter` with `data_source` set to `ITER_SOURCE`. For the duration40/// of `'data`, it must be safe to read from this IO vector using the standard C methods for this41/// purpose.42#[repr(transparent)]43pub struct IovIterSource<'data> {44iov: Opaque<bindings::iov_iter>,45/// Represent to the type system that this value contains a pointer to readable data it does46/// not own.47_source: PhantomData<&'data [u8]>,48}4950impl<'data> IovIterSource<'data> {51/// Obtain an `IovIterSource` from a raw pointer.52///53/// # Safety54///55/// * The referenced `struct iov_iter` must be valid and must only be accessed through the56/// returned reference for the duration of `'iov`.57/// * The referenced `struct iov_iter` must have `data_source` set to `ITER_SOURCE`.58/// * For the duration of `'data`, it must be safe to read from this IO vector using the59/// standard C methods for this purpose.60#[track_caller]61#[inline]62pub unsafe fn from_raw<'iov>(ptr: *mut bindings::iov_iter) -> &'iov mut IovIterSource<'data> {63// SAFETY: The caller ensures that `ptr` is valid.64let data_source = unsafe { (*ptr).data_source };65assert_eq!(data_source, ITER_SOURCE);6667// SAFETY: The caller ensures the type invariants for the right durations, and68// `IovIterSource` is layout compatible with `struct iov_iter`.69unsafe { &mut *ptr.cast::<IovIterSource<'data>>() }70}7172/// Access this as a raw `struct iov_iter`.73#[inline]74pub fn as_raw(&mut self) -> *mut bindings::iov_iter {75self.iov.get()76}7778/// Returns the number of bytes available in this IO vector.79///80/// Note that this may overestimate the number of bytes. For example, reading from userspace81/// memory could fail with `EFAULT`, which will be treated as the end of the IO vector.82#[inline]83pub fn len(&self) -> usize {84// SAFETY: We have shared access to this IO vector, so we can read its `count` field.85unsafe {86(*self.iov.get())87.__bindgen_anon_188.__bindgen_anon_189.as_ref()90.count91}92}9394/// Returns whether there are any bytes left in this IO vector.95///96/// This may return `true` even if there are no more bytes available. For example, reading from97/// userspace memory could fail with `EFAULT`, which will be treated as the end of the IO vector.98#[inline]99pub fn is_empty(&self) -> bool {100self.len() == 0101}102103/// Advance this IO vector by `bytes` bytes.104///105/// If `bytes` is larger than the size of this IO vector, it is advanced to the end.106#[inline]107pub fn advance(&mut self, bytes: usize) {108// SAFETY: By the type invariants, `self.iov` is a valid IO vector.109unsafe { bindings::iov_iter_advance(self.as_raw(), bytes) };110}111112/// Advance this IO vector backwards by `bytes` bytes.113///114/// # Safety115///116/// The IO vector must not be reverted to before its beginning.117#[inline]118pub unsafe fn revert(&mut self, bytes: usize) {119// SAFETY: By the type invariants, `self.iov` is a valid IO vector, and the caller120// ensures that `bytes` is in bounds.121unsafe { bindings::iov_iter_revert(self.as_raw(), bytes) };122}123124/// Read data from this IO vector.125///126/// Returns the number of bytes that have been copied.127#[inline]128pub fn copy_from_iter(&mut self, out: &mut [u8]) -> usize {129// SAFETY: `Self::copy_from_iter_raw` guarantees that it will not write any uninitialized130// bytes in the provided buffer, so `out` is still a valid `u8` slice after this call.131let out = unsafe { &mut *(ptr::from_mut(out) as *mut [MaybeUninit<u8>]) };132133self.copy_from_iter_raw(out).len()134}135136/// Read data from this IO vector and append it to a vector.137///138/// Returns the number of bytes that have been copied.139#[inline]140pub fn copy_from_iter_vec<A: Allocator>(141&mut self,142out: &mut Vec<u8, A>,143flags: Flags,144) -> Result<usize> {145out.reserve(self.len(), flags)?;146let len = self.copy_from_iter_raw(out.spare_capacity_mut()).len();147// SAFETY:148// - `len` is the length of a subslice of the spare capacity, so `len` is at most the149// length of the spare capacity.150// - `Self::copy_from_iter_raw` guarantees that the first `len` bytes of the spare capacity151// have been initialized.152unsafe { out.inc_len(len) };153Ok(len)154}155156/// Read data from this IO vector into potentially uninitialized memory.157///158/// Returns the sub-slice of the output that has been initialized. If the returned slice is159/// shorter than the input buffer, then the entire IO vector has been read.160///161/// This will never write uninitialized bytes to the provided buffer.162#[inline]163pub fn copy_from_iter_raw(&mut self, out: &mut [MaybeUninit<u8>]) -> &mut [u8] {164let capacity = out.len();165let out = out.as_mut_ptr().cast::<u8>();166167// GUARANTEES: The C API guarantees that it does not write uninitialized bytes to the168// provided buffer.169// SAFETY:170// * By the type invariants, it is still valid to read from this IO vector.171// * `out` is valid for writing for `capacity` bytes because it comes from a slice of172// that length.173let len = unsafe { bindings::_copy_from_iter(out.cast(), capacity, self.as_raw()) };174175// SAFETY: The underlying C api guarantees that initialized bytes have been written to the176// first `len` bytes of the spare capacity.177unsafe { slice::from_raw_parts_mut(out, len) }178}179}180181/// An IO vector that acts as a destination for data.182///183/// IO vectors support many different types of destinations. This includes both buffers in184/// kernel-space and writing to userspace. It's possible that the destination buffer is mapped in a185/// thread-local manner using e.g. `kmap_local_page()`, so this type is not `Send` to ensure that186/// the mapping is written to the right context in that scenario.187///188/// # Invariants189///190/// Must hold a valid `struct iov_iter` with `data_source` set to `ITER_DEST`. For the duration of191/// `'data`, it must be safe to write to this IO vector using the standard C methods for this192/// purpose.193#[repr(transparent)]194pub struct IovIterDest<'data> {195iov: Opaque<bindings::iov_iter>,196/// Represent to the type system that this value contains a pointer to writable data it does197/// not own.198_source: PhantomData<&'data mut [u8]>,199}200201impl<'data> IovIterDest<'data> {202/// Obtain an `IovIterDest` from a raw pointer.203///204/// # Safety205///206/// * The referenced `struct iov_iter` must be valid and must only be accessed through the207/// returned reference for the duration of `'iov`.208/// * The referenced `struct iov_iter` must have `data_source` set to `ITER_DEST`.209/// * For the duration of `'data`, it must be safe to write to this IO vector using the210/// standard C methods for this purpose.211#[track_caller]212#[inline]213pub unsafe fn from_raw<'iov>(ptr: *mut bindings::iov_iter) -> &'iov mut IovIterDest<'data> {214// SAFETY: The caller ensures that `ptr` is valid.215let data_source = unsafe { (*ptr).data_source };216assert_eq!(data_source, ITER_DEST);217218// SAFETY: The caller ensures the type invariants for the right durations, and219// `IovIterSource` is layout compatible with `struct iov_iter`.220unsafe { &mut *ptr.cast::<IovIterDest<'data>>() }221}222223/// Access this as a raw `struct iov_iter`.224#[inline]225pub fn as_raw(&mut self) -> *mut bindings::iov_iter {226self.iov.get()227}228229/// Returns the number of bytes available in this IO vector.230///231/// Note that this may overestimate the number of bytes. For example, reading from userspace232/// memory could fail with EFAULT, which will be treated as the end of the IO vector.233#[inline]234pub fn len(&self) -> usize {235// SAFETY: We have shared access to this IO vector, so we can read its `count` field.236unsafe {237(*self.iov.get())238.__bindgen_anon_1239.__bindgen_anon_1240.as_ref()241.count242}243}244245/// Returns whether there are any bytes left in this IO vector.246///247/// This may return `true` even if there are no more bytes available. For example, reading from248/// userspace memory could fail with EFAULT, which will be treated as the end of the IO vector.249#[inline]250pub fn is_empty(&self) -> bool {251self.len() == 0252}253254/// Advance this IO vector by `bytes` bytes.255///256/// If `bytes` is larger than the size of this IO vector, it is advanced to the end.257#[inline]258pub fn advance(&mut self, bytes: usize) {259// SAFETY: By the type invariants, `self.iov` is a valid IO vector.260unsafe { bindings::iov_iter_advance(self.as_raw(), bytes) };261}262263/// Advance this IO vector backwards by `bytes` bytes.264///265/// # Safety266///267/// The IO vector must not be reverted to before its beginning.268#[inline]269pub unsafe fn revert(&mut self, bytes: usize) {270// SAFETY: By the type invariants, `self.iov` is a valid IO vector, and the caller271// ensures that `bytes` is in bounds.272unsafe { bindings::iov_iter_revert(self.as_raw(), bytes) };273}274275/// Write data to this IO vector.276///277/// Returns the number of bytes that were written. If this is shorter than the provided slice,278/// then no more bytes can be written.279#[inline]280pub fn copy_to_iter(&mut self, input: &[u8]) -> usize {281// SAFETY:282// * By the type invariants, it is still valid to write to this IO vector.283// * `input` is valid for `input.len()` bytes.284unsafe { bindings::_copy_to_iter(input.as_ptr().cast(), input.len(), self.as_raw()) }285}286287/// Utility for implementing `read_iter` given the full contents of the file.288///289/// The full contents of the file being read from is represented by `contents`. This call will290/// write the appropriate sub-slice of `contents` and update the file position in `ppos` so291/// that the file will appear to contain `contents` even if takes multiple reads to read the292/// entire file.293#[inline]294pub fn simple_read_from_buffer(&mut self, ppos: &mut i64, contents: &[u8]) -> Result<usize> {295if *ppos < 0 {296return Err(EINVAL);297}298let Ok(pos) = usize::try_from(*ppos) else {299return Ok(0);300};301if pos >= contents.len() {302return Ok(0);303}304305// BOUNDS: We just checked that `pos < contents.len()` above.306let num_written = self.copy_to_iter(&contents[pos..]);307308// OVERFLOW: `pos+num_written <= contents.len() <= isize::MAX <= i64::MAX`.309*ppos = (pos + num_written) as i64;310311Ok(num_written)312}313}314315316