Types that implement both `AsBytes` and `FromBytes` can be safely
modified as a slice of bytes. Add a `as_bytes_mut` method for that
purpose.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
rust/kernel/transmute.rs | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/rust/kernel/transmute.rs b/rust/kernel/transmute.rs
index d541c9960904d8c7f755351f22d06e4e8dbd546a..000fda2a78f8e6e8378bbe93cddd8a5008db20cc 100644
--- a/rust/kernel/transmute.rs
+++ b/rust/kernel/transmute.rs
@@ -56,6 +56,19 @@ fn as_bytes(&self) -> &[u8] {
// SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes.
unsafe { core::slice::from_raw_parts(data, len) }
}
+
+ /// Returns `self` as a mutable slice of bytes.
+ fn as_bytes_mut(&mut self) -> &mut [u8]
+ where
+ Self: FromBytes,
+ {
+ let data = core::ptr::from_mut(self).cast::<u8>();
+ let len = size_of_val(self);
+
+ // SAFETY: `data` is non-null and valid for read and writes over `len * sizeof::<u8>()`
+ // bytes. Since `Self` implements `FromBytes` it can be represented by any value.
+ unsafe { core::slice::from_raw_parts_mut(data, len) }
+ }
}
macro_rules! impl_asbytes {
--
2.50.1
On Mon Jul 28, 2025 at 2:47 PM CEST, Alexandre Courbot wrote: > diff --git a/rust/kernel/transmute.rs b/rust/kernel/transmute.rs > index d541c9960904d8c7f755351f22d06e4e8dbd546a..000fda2a78f8e6e8378bbe93cddd8a5008db20cc 100644 > --- a/rust/kernel/transmute.rs > +++ b/rust/kernel/transmute.rs > @@ -56,6 +56,19 @@ fn as_bytes(&self) -> &[u8] { > // SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes. > unsafe { core::slice::from_raw_parts(data, len) } > } > + > + /// Returns `self` as a mutable slice of bytes. > + fn as_bytes_mut(&mut self) -> &mut [u8] > + where > + Self: FromBytes, > + { > + let data = core::ptr::from_mut(self).cast::<u8>(); Also add a `CAST` comment above this line: // CAST: `Self` implements both `AsBytes` and `FromBytes` thus making `Self` bi-directionally // transmutable to `[u8; size_of_val(self)]`. On that note, `FromBytes` probably entails `Sized`, or does someone have a use-case in mind? (because then we could replace the `size_of_val(self)` above with `size_of::<Self>()` which I think makes it simpler to understand) > + let len = size_of_val(self); > + > + // SAFETY: `data` is non-null and valid for read and writes over `len * sizeof::<u8>()` s/over/of/ > + // bytes. Since `Self` implements `FromBytes` it can be represented by any value. Don't need the second sentence due to the `CAST` comment above. --- Cheers, Benno > + unsafe { core::slice::from_raw_parts_mut(data, len) } > + } > } > > macro_rules! impl_asbytes {
On Mon, Jul 28, 2025 at 04:53:31PM +0200, Benno Lossin wrote: > On Mon Jul 28, 2025 at 2:47 PM CEST, Alexandre Courbot wrote: > > diff --git a/rust/kernel/transmute.rs b/rust/kernel/transmute.rs > > index d541c9960904d8c7f755351f22d06e4e8dbd546a..000fda2a78f8e6e8378bbe93cddd8a5008db20cc 100644 > > --- a/rust/kernel/transmute.rs > > +++ b/rust/kernel/transmute.rs > > @@ -56,6 +56,19 @@ fn as_bytes(&self) -> &[u8] { > > // SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes. > > unsafe { core::slice::from_raw_parts(data, len) } > > } > > + > > + /// Returns `self` as a mutable slice of bytes. > > + fn as_bytes_mut(&mut self) -> &mut [u8] > > + where > > + Self: FromBytes, > > + { > > + let data = core::ptr::from_mut(self).cast::<u8>(); > > Also add a `CAST` comment above this line: > > // CAST: `Self` implements both `AsBytes` and `FromBytes` thus making `Self` bi-directionally > // transmutable to `[u8; size_of_val(self)]`. > > On that note, `FromBytes` probably entails `Sized`, or does someone have > a use-case in mind? (because then we could replace the Because if `T` is `FromBytes` then we want `[T]` is `FromBytes` too? Also it would be weird if `[u8]` itself doesn't implement `FromBytes`. Regards, Boqun > `size_of_val(self)` above with `size_of::<Self>()` which I think makes > it simpler to understand) > [...]
On Mon Jul 28, 2025 at 4:59 PM CEST, Boqun Feng wrote: > On Mon, Jul 28, 2025 at 04:53:31PM +0200, Benno Lossin wrote: >> On Mon Jul 28, 2025 at 2:47 PM CEST, Alexandre Courbot wrote: >> > diff --git a/rust/kernel/transmute.rs b/rust/kernel/transmute.rs >> > index d541c9960904d8c7f755351f22d06e4e8dbd546a..000fda2a78f8e6e8378bbe93cddd8a5008db20cc 100644 >> > --- a/rust/kernel/transmute.rs >> > +++ b/rust/kernel/transmute.rs >> > @@ -56,6 +56,19 @@ fn as_bytes(&self) -> &[u8] { >> > // SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes. >> > unsafe { core::slice::from_raw_parts(data, len) } >> > } >> > + >> > + /// Returns `self` as a mutable slice of bytes. >> > + fn as_bytes_mut(&mut self) -> &mut [u8] >> > + where >> > + Self: FromBytes, >> > + { >> > + let data = core::ptr::from_mut(self).cast::<u8>(); >> >> Also add a `CAST` comment above this line: >> >> // CAST: `Self` implements both `AsBytes` and `FromBytes` thus making `Self` bi-directionally >> // transmutable to `[u8; size_of_val(self)]`. >> >> On that note, `FromBytes` probably entails `Sized`, or does someone have >> a use-case in mind? (because then we could replace the > > Because if `T` is `FromBytes` then we want `[T]` is `FromBytes` too? > Also it would be weird if `[u8]` itself doesn't implement `FromBytes`. Oh yeah that's true. --- Cheers, Benno
On 7/28/25 2:47 PM, Alexandre Courbot wrote: > Types that implement both `AsBytes` and `FromBytes` can be safely > modified as a slice of bytes. Add a `as_bytes_mut` method for that > purpose. > > Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Danilo Krummrich <dakr@kernel.org>
© 2016 - 2025 Red Hat, Inc.