summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWedson Almeida Filho <walmeida@microsoft.com>2023-09-29 17:58:09 -0300
committerDanilo Krummrich <dakr@kernel.org>2024-08-13 15:53:39 +0200
commit6e14443091639269f9866cac0c9d82d44335eee5 (patch)
tree3226c4ae7bff0cc124d7603f650e0a58b2cc4941
parentde9c2c66ad8e787abec7c9d7eff4f8c3cdd28aed (diff)
rust: init: introduce `Opaque::try_ffi_init`
We'll need it, for example, when calling `register_filesystem` to initialise a file system registration. Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
-rw-r--r--rust/kernel/types.rs20
1 files changed, 14 insertions, 6 deletions
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index bd189d646adb..e27e4ef3793b 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -259,14 +259,22 @@ impl<T> Opaque<T> {
/// 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 ffi_init(init_func: impl FnOnce(*mut T)) -> impl PinInit<Self> {
+ Self::try_ffi_init(move |slot| {
+ init_func(slot);
+ Ok(())
+ })
+ }
+
+ /// Similar to [`Self::ffi_init`], except that the closure can fail.
+ ///
+ /// To avoid leaks on failure, the closure must drop any fields it has initialised before the
+ /// failure.
+ 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::<_, ::core::convert::Infallible>(move |slot| {
- init_func(Self::raw_get(slot));
- Ok(())
- })
- }
+ unsafe { init::pin_init_from_closure(|slot| init_func(Self::raw_get(slot))) }
}
/// Returns a raw pointer to the opaque data.