[PATCH v17 03/10] rust: implement `ForeignOwnable` for `Owned`

Gary Guo gary at garyguo.net
Tue Jun 16 11:55:52 UTC 2026


On Thu Jun 4, 2026 at 9:11 PM BST, Andreas Hindborg wrote:
> Implement `ForeignOwnable` for `Owned<T>`. This allows use of `Owned<T>` in
> places such as the `XArray`.
>
> Note that `T` does not need to implement `ForeignOwnable` for `Owned<T>` to
> implement `ForeignOwnable`.
>
> Signed-off-by: Andreas Hindborg <a.hindborg at kernel.org>
> ---
>  rust/kernel/owned.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
>
> diff --git a/rust/kernel/owned.rs b/rust/kernel/owned.rs
> index 456e239e906e..5eacdf327d12 100644
> --- a/rust/kernel/owned.rs
> +++ b/rust/kernel/owned.rs
> @@ -15,6 +15,8 @@
>      ptr::NonNull, //
>  };
>  
> +use kernel::types::ForeignOwnable;
> +
>  /// Types that specify their own way of performing allocation and destruction. Typically, this trait
>  /// is implemented on types from the C side.
>  ///
> @@ -108,6 +110,7 @@ pub trait Ownable {
>  ///
>  /// - Until `T::release` is called, this `Owned<T>` exclusively owns the underlying `T`.
>  /// - The `T` value is pinned.
> +#[repr(transparent)]

AFAIT this `#[repr(transparent)]` isn't actually needed.

>  pub struct Owned<T: Ownable> {
>      ptr: NonNull<T>,
>  }
> @@ -185,3 +188,46 @@ fn drop(&mut self) {
>          unsafe { T::release(self.ptr.as_mut()) };
>      }
>  }
> +
> +// SAFETY: We derive the pointer to `T` from a valid `T`, so the returned
> +// pointer satisfy alignment requirements of `T`.
> +unsafe impl<T: Ownable + 'static> ForeignOwnable for Owned<T> {

You should drop the `'static` bound and put where bound on the GAT below
instead. See how `Box` is doing it.

Best,
Gary

> +    const FOREIGN_ALIGN: usize = core::mem::align_of::<Owned<T>>();
> +
> +    type Borrowed<'a> = &'a T;
> +    type BorrowedMut<'a> = Pin<&'a mut T>;
> +
> +    #[inline]
> +    fn into_foreign(self) -> *mut kernel::ffi::c_void {
> +        let ptr = self.ptr.as_ptr().cast();
> +        core::mem::forget(self);
> +        ptr
> +    }
> +
> +    #[inline]
> +    unsafe fn from_foreign(ptr: *mut kernel::ffi::c_void) -> Self {
> +        Self {
> +            // SAFETY: By function safety contract, `ptr` came from
> +            // `into_foreign` and cannot be null.
> +            ptr: unsafe { NonNull::new_unchecked(ptr.cast()) },
> +        }
> +    }
> +
> +    #[inline]
> +    unsafe fn borrow<'a>(ptr: *mut kernel::ffi::c_void) -> Self::Borrowed<'a> {
> +        // SAFETY: By function safety requirements, `ptr` is valid for use as a
> +        // reference for `'a`.
> +        unsafe { &*ptr.cast() }
> +    }
> +
> +    #[inline]
> +    unsafe fn borrow_mut<'a>(ptr: *mut kernel::ffi::c_void) -> Self::BorrowedMut<'a> {
> +        // SAFETY: By function safety requirements, `ptr` is valid for use as a
> +        // unique reference for `'a`.
> +        let inner = unsafe { &mut *ptr.cast() };
> +
> +        // SAFETY: We never move out of inner, and we do not hand out mutable
> +        // references when `T: !Unpin`.
> +        unsafe { Pin::new_unchecked(inner) }
> +    }
> +}





More information about the Linux-security-module-archive mailing list