]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
rust: types: add Opaque::try_ffi_init
authorAlice Ryhl <aliceryhl@google.com>
Tue, 1 Oct 2024 08:22:21 +0000 (08:22 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Oct 2024 10:18:29 +0000 (12:18 +0200)
This will be used by the miscdevice abstractions, as the C function
`misc_register` is fallible.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Link: https://lore.kernel.org/r/20241001-b4-miscdevice-v2-1-330d760041fa@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
rust/kernel/types.rs

index 9e7ca066355cd590dfe773abcdda464f4e321b75..070d03152937fab82da406591b2f772f7354ca66 100644 (file)
@@ -299,6 +299,22 @@ impl<T> Opaque<T> {
         }
     }
 
+    /// Creates a fallible pin-initializer from the given initializer closure.
+    ///
+    /// The returned initializer calls the given closure with the pointer to the inner `T` of this
+    /// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it.
+    ///
+    /// This function is safe, because the `T` inside of an `Opaque` is allowed to be
+    /// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs
+    /// to verify at that point that the inner value is valid.
+    pub fn try_ffi_init<E>(
+        init_func: impl FnOnce(*mut T) -> Result<(), E>,
+    ) -> impl PinInit<Self, E> {
+        // SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully
+        // initialize the `T`.
+        unsafe { init::pin_init_from_closure::<_, E>(move |slot| init_func(Self::raw_get(slot))) }
+    }
+
     /// Returns a raw pointer to the opaque data.
     pub const fn get(&self) -> *mut T {
         UnsafeCell::get(&self.value).cast::<T>()