xref: /linux/rust/kernel/iov.rs (revision 06cb58b310ea38a8135827f726157df59a95376e)
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