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