From b40f5ed85c5f162dfb61fe12d3c58a1d5420e3dc Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Wed, 9 Sep 2026 16:44:59 +1000 Subject: [PATCH] rust: uaccess: add UserSliceWriter::write_truncated() Add a helper that writes as much of an AsBytes value as fits in the remaining userspace buffer and returns the number of bytes copied. This avoids requiring callers of versioned UAPIs to convert values to byte slices and truncate them manually. Suggested-by: Danilo Krummrich Link: https://lore.kernel.org/nova-gpu/DKC6T1DQX2L3.HTHPB2L167TC@kernel.org/ Signed-off-by: Alistair Popple Acked-by: Miguel Ojeda Link: https://patch.msgid.link/20260909064506.910162-7-apopple@nvidia.com [ Inline write_slice_partial() and use it to simplify write_truncated(). - Danilo ] Signed-off-by: Danilo Krummrich --- rust/kernel/uaccess.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs index f09078228c53..f1aecda7a90c 100644 --- a/rust/kernel/uaccess.rs +++ b/rust/kernel/uaccess.rs @@ -558,6 +558,7 @@ pub fn write_dma( /// truncates the write to the boundaries of `self` and `data`. /// /// On success, returns the number of bytes written. + #[inline] pub fn write_slice_partial(&mut self, data: &[u8], offset: usize) -> Result { let end = offset.saturating_add(self.len()).min(data.len()); @@ -624,6 +625,19 @@ pub fn write(&mut self, value: &T) -> Result { self.length -= len; Ok(()) } + + /// Writes as much of the provided value as fits in the remaining buffer. + /// + /// Copies `min(size_of::(), self.len())` bytes to userspace. Returns the number of bytes + /// actually written. This is useful for versioned structs where an older userspace may provide + /// a smaller buffer than the current kernel struct. + /// + /// Fails with [`EFAULT`] if the write happens on a bad address. This call may modify the + /// associated userspace slice even if it returns an error. + #[inline] + pub fn write_truncated(&mut self, value: &T) -> Result { + self.write_slice_partial(value.as_bytes(), 0) + } } /// Reads a nul-terminated string into `dst` and returns the length.