1*06cb58b3SAlice Ryhl // SPDX-License-Identifier: GPL-2.0 2*06cb58b3SAlice Ryhl 3*06cb58b3SAlice Ryhl // Copyright (C) 2025 Google LLC. 4*06cb58b3SAlice Ryhl 5*06cb58b3SAlice Ryhl //! IO vectors. 6*06cb58b3SAlice Ryhl //! 7*06cb58b3SAlice Ryhl //! C headers: [`include/linux/iov_iter.h`](srctree/include/linux/iov_iter.h), 8*06cb58b3SAlice Ryhl //! [`include/linux/uio.h`](srctree/include/linux/uio.h) 9*06cb58b3SAlice Ryhl 10*06cb58b3SAlice Ryhl use crate::{ 11*06cb58b3SAlice Ryhl alloc::{Allocator, Flags}, 12*06cb58b3SAlice Ryhl bindings, 13*06cb58b3SAlice Ryhl prelude::*, 14*06cb58b3SAlice Ryhl types::Opaque, 15*06cb58b3SAlice Ryhl }; 16*06cb58b3SAlice Ryhl use core::{marker::PhantomData, mem::MaybeUninit, ptr, slice}; 17*06cb58b3SAlice Ryhl 18*06cb58b3SAlice Ryhl const ITER_SOURCE: bool = bindings::ITER_SOURCE != 0; 19*06cb58b3SAlice Ryhl 20*06cb58b3SAlice Ryhl /// An IO vector that acts as a source of data. 21*06cb58b3SAlice Ryhl /// 22*06cb58b3SAlice Ryhl /// The data may come from many different sources. This includes both things in kernel-space and 23*06cb58b3SAlice Ryhl /// reading from userspace. It's not necessarily the case that the data source is immutable, so 24*06cb58b3SAlice Ryhl /// rewinding the IO vector to read the same data twice is not guaranteed to result in the same 25*06cb58b3SAlice Ryhl /// bytes. It's also possible that the data source is mapped in a thread-local manner using e.g. 26*06cb58b3SAlice Ryhl /// `kmap_local_page()`, so this type is not `Send` to ensure that the mapping is read from the 27*06cb58b3SAlice Ryhl /// right context in that scenario. 28*06cb58b3SAlice Ryhl /// 29*06cb58b3SAlice Ryhl /// # Invariants 30*06cb58b3SAlice Ryhl /// 31*06cb58b3SAlice Ryhl /// Must hold a valid `struct iov_iter` with `data_source` set to `ITER_SOURCE`. For the duration 32*06cb58b3SAlice Ryhl /// of `'data`, it must be safe to read from this IO vector using the standard C methods for this 33*06cb58b3SAlice Ryhl /// purpose. 34*06cb58b3SAlice Ryhl #[repr(transparent)] 35*06cb58b3SAlice Ryhl pub struct IovIterSource<'data> { 36*06cb58b3SAlice Ryhl iov: Opaque<bindings::iov_iter>, 37*06cb58b3SAlice Ryhl /// Represent to the type system that this value contains a pointer to readable data it does 38*06cb58b3SAlice Ryhl /// not own. 39*06cb58b3SAlice Ryhl _source: PhantomData<&'data [u8]>, 40*06cb58b3SAlice Ryhl } 41*06cb58b3SAlice Ryhl 42*06cb58b3SAlice Ryhl impl<'data> IovIterSource<'data> { 43*06cb58b3SAlice Ryhl /// Obtain an `IovIterSource` from a raw pointer. 44*06cb58b3SAlice Ryhl /// 45*06cb58b3SAlice Ryhl /// # Safety 46*06cb58b3SAlice Ryhl /// 47*06cb58b3SAlice Ryhl /// * The referenced `struct iov_iter` must be valid and must only be accessed through the 48*06cb58b3SAlice Ryhl /// returned reference for the duration of `'iov`. 49*06cb58b3SAlice Ryhl /// * The referenced `struct iov_iter` must have `data_source` set to `ITER_SOURCE`. 50*06cb58b3SAlice Ryhl /// * For the duration of `'data`, it must be safe to read from this IO vector using the 51*06cb58b3SAlice Ryhl /// standard C methods for this purpose. 52*06cb58b3SAlice Ryhl #[track_caller] 53*06cb58b3SAlice Ryhl #[inline] 54*06cb58b3SAlice Ryhl pub unsafe fn from_raw<'iov>(ptr: *mut bindings::iov_iter) -> &'iov mut IovIterSource<'data> { 55*06cb58b3SAlice Ryhl // SAFETY: The caller ensures that `ptr` is valid. 56*06cb58b3SAlice Ryhl let data_source = unsafe { (*ptr).data_source }; 57*06cb58b3SAlice Ryhl assert_eq!(data_source, ITER_SOURCE); 58*06cb58b3SAlice Ryhl 59*06cb58b3SAlice Ryhl // SAFETY: The caller ensures the type invariants for the right durations, and 60*06cb58b3SAlice Ryhl // `IovIterSource` is layout compatible with `struct iov_iter`. 61*06cb58b3SAlice Ryhl unsafe { &mut *ptr.cast::<IovIterSource<'data>>() } 62*06cb58b3SAlice Ryhl } 63*06cb58b3SAlice Ryhl 64*06cb58b3SAlice Ryhl /// Access this as a raw `struct iov_iter`. 65*06cb58b3SAlice Ryhl #[inline] 66*06cb58b3SAlice Ryhl pub fn as_raw(&mut self) -> *mut bindings::iov_iter { 67*06cb58b3SAlice Ryhl self.iov.get() 68*06cb58b3SAlice Ryhl } 69*06cb58b3SAlice Ryhl 70*06cb58b3SAlice Ryhl /// Returns the number of bytes available in this IO vector. 71*06cb58b3SAlice Ryhl /// 72*06cb58b3SAlice Ryhl /// Note that this may overestimate the number of bytes. For example, reading from userspace 73*06cb58b3SAlice Ryhl /// memory could fail with `EFAULT`, which will be treated as the end of the IO vector. 74*06cb58b3SAlice Ryhl #[inline] 75*06cb58b3SAlice Ryhl pub fn len(&self) -> usize { 76*06cb58b3SAlice Ryhl // SAFETY: We have shared access to this IO vector, so we can read its `count` field. 77*06cb58b3SAlice Ryhl unsafe { 78*06cb58b3SAlice Ryhl (*self.iov.get()) 79*06cb58b3SAlice Ryhl .__bindgen_anon_1 80*06cb58b3SAlice Ryhl .__bindgen_anon_1 81*06cb58b3SAlice Ryhl .as_ref() 82*06cb58b3SAlice Ryhl .count 83*06cb58b3SAlice Ryhl } 84*06cb58b3SAlice Ryhl } 85*06cb58b3SAlice Ryhl 86*06cb58b3SAlice Ryhl /// Returns whether there are any bytes left in this IO vector. 87*06cb58b3SAlice Ryhl /// 88*06cb58b3SAlice Ryhl /// This may return `true` even if there are no more bytes available. For example, reading from 89*06cb58b3SAlice Ryhl /// userspace memory could fail with `EFAULT`, which will be treated as the end of the IO vector. 90*06cb58b3SAlice Ryhl #[inline] 91*06cb58b3SAlice Ryhl pub fn is_empty(&self) -> bool { 92*06cb58b3SAlice Ryhl self.len() == 0 93*06cb58b3SAlice Ryhl } 94*06cb58b3SAlice Ryhl 95*06cb58b3SAlice Ryhl /// Advance this IO vector by `bytes` bytes. 96*06cb58b3SAlice Ryhl /// 97*06cb58b3SAlice Ryhl /// If `bytes` is larger than the size of this IO vector, it is advanced to the end. 98*06cb58b3SAlice Ryhl #[inline] 99*06cb58b3SAlice Ryhl pub fn advance(&mut self, bytes: usize) { 100*06cb58b3SAlice Ryhl // SAFETY: By the type invariants, `self.iov` is a valid IO vector. 101*06cb58b3SAlice Ryhl unsafe { bindings::iov_iter_advance(self.as_raw(), bytes) }; 102*06cb58b3SAlice Ryhl } 103*06cb58b3SAlice Ryhl 104*06cb58b3SAlice Ryhl /// Advance this IO vector backwards by `bytes` bytes. 105*06cb58b3SAlice Ryhl /// 106*06cb58b3SAlice Ryhl /// # Safety 107*06cb58b3SAlice Ryhl /// 108*06cb58b3SAlice Ryhl /// The IO vector must not be reverted to before its beginning. 109*06cb58b3SAlice Ryhl #[inline] 110*06cb58b3SAlice Ryhl pub unsafe fn revert(&mut self, bytes: usize) { 111*06cb58b3SAlice Ryhl // SAFETY: By the type invariants, `self.iov` is a valid IO vector, and the caller 112*06cb58b3SAlice Ryhl // ensures that `bytes` is in bounds. 113*06cb58b3SAlice Ryhl unsafe { bindings::iov_iter_revert(self.as_raw(), bytes) }; 114*06cb58b3SAlice Ryhl } 115*06cb58b3SAlice Ryhl 116*06cb58b3SAlice Ryhl /// Read data from this IO vector. 117*06cb58b3SAlice Ryhl /// 118*06cb58b3SAlice Ryhl /// Returns the number of bytes that have been copied. 119*06cb58b3SAlice Ryhl #[inline] 120*06cb58b3SAlice Ryhl pub fn copy_from_iter(&mut self, out: &mut [u8]) -> usize { 121*06cb58b3SAlice Ryhl // SAFETY: `Self::copy_from_iter_raw` guarantees that it will not write any uninitialized 122*06cb58b3SAlice Ryhl // bytes in the provided buffer, so `out` is still a valid `u8` slice after this call. 123*06cb58b3SAlice Ryhl let out = unsafe { &mut *(ptr::from_mut(out) as *mut [MaybeUninit<u8>]) }; 124*06cb58b3SAlice Ryhl 125*06cb58b3SAlice Ryhl self.copy_from_iter_raw(out).len() 126*06cb58b3SAlice Ryhl } 127*06cb58b3SAlice Ryhl 128*06cb58b3SAlice Ryhl /// Read data from this IO vector and append it to a vector. 129*06cb58b3SAlice Ryhl /// 130*06cb58b3SAlice Ryhl /// Returns the number of bytes that have been copied. 131*06cb58b3SAlice Ryhl #[inline] 132*06cb58b3SAlice Ryhl pub fn copy_from_iter_vec<A: Allocator>( 133*06cb58b3SAlice Ryhl &mut self, 134*06cb58b3SAlice Ryhl out: &mut Vec<u8, A>, 135*06cb58b3SAlice Ryhl flags: Flags, 136*06cb58b3SAlice Ryhl ) -> Result<usize> { 137*06cb58b3SAlice Ryhl out.reserve(self.len(), flags)?; 138*06cb58b3SAlice Ryhl let len = self.copy_from_iter_raw(out.spare_capacity_mut()).len(); 139*06cb58b3SAlice Ryhl // SAFETY: 140*06cb58b3SAlice Ryhl // - `len` is the length of a subslice of the spare capacity, so `len` is at most the 141*06cb58b3SAlice Ryhl // length of the spare capacity. 142*06cb58b3SAlice Ryhl // - `Self::copy_from_iter_raw` guarantees that the first `len` bytes of the spare capacity 143*06cb58b3SAlice Ryhl // have been initialized. 144*06cb58b3SAlice Ryhl unsafe { out.inc_len(len) }; 145*06cb58b3SAlice Ryhl Ok(len) 146*06cb58b3SAlice Ryhl } 147*06cb58b3SAlice Ryhl 148*06cb58b3SAlice Ryhl /// Read data from this IO vector into potentially uninitialized memory. 149*06cb58b3SAlice Ryhl /// 150*06cb58b3SAlice Ryhl /// Returns the sub-slice of the output that has been initialized. If the returned slice is 151*06cb58b3SAlice Ryhl /// shorter than the input buffer, then the entire IO vector has been read. 152*06cb58b3SAlice Ryhl /// 153*06cb58b3SAlice Ryhl /// This will never write uninitialized bytes to the provided buffer. 154*06cb58b3SAlice Ryhl #[inline] 155*06cb58b3SAlice Ryhl pub fn copy_from_iter_raw(&mut self, out: &mut [MaybeUninit<u8>]) -> &mut [u8] { 156*06cb58b3SAlice Ryhl let capacity = out.len(); 157*06cb58b3SAlice Ryhl let out = out.as_mut_ptr().cast::<u8>(); 158*06cb58b3SAlice Ryhl 159*06cb58b3SAlice Ryhl // GUARANTEES: The C API guarantees that it does not write uninitialized bytes to the 160*06cb58b3SAlice Ryhl // provided buffer. 161*06cb58b3SAlice Ryhl // SAFETY: 162*06cb58b3SAlice Ryhl // * By the type invariants, it is still valid to read from this IO vector. 163*06cb58b3SAlice Ryhl // * `out` is valid for writing for `capacity` bytes because it comes from a slice of 164*06cb58b3SAlice Ryhl // that length. 165*06cb58b3SAlice Ryhl let len = unsafe { bindings::_copy_from_iter(out.cast(), capacity, self.as_raw()) }; 166*06cb58b3SAlice Ryhl 167*06cb58b3SAlice Ryhl // SAFETY: The underlying C api guarantees that initialized bytes have been written to the 168*06cb58b3SAlice Ryhl // first `len` bytes of the spare capacity. 169*06cb58b3SAlice Ryhl unsafe { slice::from_raw_parts_mut(out, len) } 170*06cb58b3SAlice Ryhl } 171*06cb58b3SAlice Ryhl } 172