// SPDX-License-Identifier: GPL-2.012//! Extensions to the [`pin-init`] crate.3//!4//! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential5//! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move.6//!7//! The [`pin-init`] crate is the way such structs are initialized on the Rust side. Please refer8//! to its documentation to better understand how to use it. Additionally, there are many examples9//! throughout the kernel, such as the types from the [`sync`] module. And the ones presented10//! below.11//!12//! [`sync`]: crate::sync13//! [pinning]: https://doc.rust-lang.org/std/pin/index.html14//! [`pin-init`]: https://rust.docs.kernel.org/pin_init/15//!16//! # [`Opaque<T>`]17//!18//! For the special case where initializing a field is a single FFI-function call that cannot fail,19//! there exist the helper function [`Opaque::ffi_init`]. This function initialize a single20//! [`Opaque<T>`] field by just delegating to the supplied closure. You can use these in21//! combination with [`pin_init!`].22//!23//! [`Opaque<T>`]: crate::types::Opaque24//! [`Opaque::ffi_init`]: crate::types::Opaque::ffi_init25//! [`pin_init!`]: pin_init::pin_init26//!27//! # Examples28//!29//! ## General Examples30//!31//! ```rust32//! # #![expect(clippy::undocumented_unsafe_blocks)]33//! use kernel::types::Opaque;34//! use pin_init::pin_init_from_closure;35//!36//! // assume we have some `raw_foo` type in C:37//! #[repr(C)]38//! struct RawFoo([u8; 16]);39//! extern "C" {40//! fn init_foo(_: *mut RawFoo);41//! }42//!43//! #[pin_data]44//! struct Foo {45//! #[pin]46//! raw: Opaque<RawFoo>,47//! }48//!49//! impl Foo {50//! fn setup(self: Pin<&mut Self>) {51//! pr_info!("Setting up foo\n");52//! }53//! }54//!55//! let foo = pin_init!(Foo {56//! raw <- unsafe {57//! Opaque::ffi_init(|s| {58//! // note that this cannot fail.59//! init_foo(s);60//! })61//! },62//! }).pin_chain(|foo| {63//! foo.setup();64//! Ok(())65//! });66//! ```67//!68//! ```rust69//! use kernel::{prelude::*, types::Opaque};70//! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin};71//! # mod bindings {72//! # #![expect(non_camel_case_types, clippy::missing_safety_doc)]73//! # pub struct foo;74//! # pub unsafe fn init_foo(_ptr: *mut foo) {}75//! # pub unsafe fn destroy_foo(_ptr: *mut foo) {}76//! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 }77//! # }78//! /// # Invariants79//! ///80//! /// `foo` is always initialized81//! #[pin_data(PinnedDrop)]82//! pub struct RawFoo {83//! #[pin]84//! foo: Opaque<bindings::foo>,85//! #[pin]86//! _p: PhantomPinned,87//! }88//!89//! impl RawFoo {90//! pub fn new(flags: u32) -> impl PinInit<Self, Error> {91//! // SAFETY:92//! // - when the closure returns `Ok(())`, then it has successfully initialized and93//! // enabled `foo`,94//! // - when it returns `Err(e)`, then it has cleaned up before95//! unsafe {96//! pin_init::pin_init_from_closure(move |slot: *mut Self| {97//! // `slot` contains uninit memory, avoid creating a reference.98//! let foo = addr_of_mut!((*slot).foo);99//!100//! // Initialize the `foo`101//! bindings::init_foo(Opaque::cast_into(foo));102//!103//! // Try to enable it.104//! let err = bindings::enable_foo(Opaque::cast_into(foo), flags);105//! if err != 0 {106//! // Enabling has failed, first clean up the foo and then return the error.107//! bindings::destroy_foo(Opaque::cast_into(foo));108//! return Err(Error::from_errno(err));109//! }110//!111//! // All fields of `RawFoo` have been initialized, since `_p` is a ZST.112//! Ok(())113//! })114//! }115//! }116//! }117//!118//! #[pinned_drop]119//! impl PinnedDrop for RawFoo {120//! fn drop(self: Pin<&mut Self>) {121//! // SAFETY: Since `foo` is initialized, destroying is safe.122//! unsafe { bindings::destroy_foo(self.foo.get()) };123//! }124//! }125//! ```126127use crate::{128alloc::{AllocError, Flags},129error::{self, Error},130};131use pin_init::{init_from_closure, pin_init_from_closure, Init, PinInit};132133/// Smart pointer that can initialize memory in-place.134pub trait InPlaceInit<T>: Sized {135/// Pinned version of `Self`.136///137/// If a type already implicitly pins its pointee, `Pin<Self>` is unnecessary. In this case use138/// `Self`, otherwise just use `Pin<Self>`.139type PinnedSelf;140141/// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this142/// type.143///144/// If `T: !Unpin` it will not be able to move afterwards.145fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>146where147E: From<AllocError>;148149/// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this150/// type.151///152/// If `T: !Unpin` it will not be able to move afterwards.153fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf>154where155Error: From<E>,156{157// SAFETY: We delegate to `init` and only change the error type.158let init = unsafe {159pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))160};161Self::try_pin_init(init, flags)162}163164/// Use the given initializer to in-place initialize a `T`.165fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>166where167E: From<AllocError>;168169/// Use the given initializer to in-place initialize a `T`.170fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>171where172Error: From<E>,173{174// SAFETY: We delegate to `init` and only change the error type.175let init = unsafe {176init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))177};178Self::try_init(init, flags)179}180}181182/// Construct an in-place fallible initializer for `struct`s.183///184/// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use185/// [`init!`].186///187/// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error,188/// append `? $type` after the `struct` initializer.189/// The safety caveats from [`try_pin_init!`] also apply:190/// - `unsafe` code must guarantee either full initialization or return an error and allow191/// deallocation of the memory.192/// - the fields are initialized in the order given in the initializer.193/// - no references to fields are allowed to be created inside of the initializer.194///195/// # Examples196///197/// ```rust198/// use kernel::error::Error;199/// use pin_init::init_zeroed;200/// struct BigBuf {201/// big: KBox<[u8; 1024 * 1024 * 1024]>,202/// small: [u8; 1024 * 1024],203/// }204///205/// impl BigBuf {206/// fn new() -> impl Init<Self, Error> {207/// try_init!(Self {208/// big: KBox::init(init_zeroed(), GFP_KERNEL)?,209/// small: [0; 1024 * 1024],210/// }? Error)211/// }212/// }213/// ```214///215/// [`Infallible`]: core::convert::Infallible216/// [`init!`]: pin_init::init217/// [`try_pin_init!`]: crate::try_pin_init!218/// [`Error`]: crate::error::Error219#[macro_export]220macro_rules! try_init {221($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {222$($fields:tt)*223}) => {224::pin_init::try_init!($(&$this in)? $t $(::<$($generics),*>)? {225$($fields)*226}? $crate::error::Error)227};228($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {229$($fields:tt)*230}? $err:ty) => {231::pin_init::try_init!($(&$this in)? $t $(::<$($generics),*>)? {232$($fields)*233}? $err)234};235}236237/// Construct an in-place, fallible pinned initializer for `struct`s.238///239/// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`].240///241/// You can use the `?` operator or use `return Err(err)` inside the initializer to stop242/// initialization and return the error.243///244/// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when245/// initialization fails, the memory can be safely deallocated without any further modifications.246///247/// This macro defaults the error to [`Error`].248///249/// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type`250/// after the `struct` initializer to specify the error type you want to use.251///252/// # Examples253///254/// ```rust255/// # #![feature(new_uninit)]256/// use kernel::error::Error;257/// use pin_init::init_zeroed;258/// #[pin_data]259/// struct BigBuf {260/// big: KBox<[u8; 1024 * 1024 * 1024]>,261/// small: [u8; 1024 * 1024],262/// ptr: *mut u8,263/// }264///265/// impl BigBuf {266/// fn new() -> impl PinInit<Self, Error> {267/// try_pin_init!(Self {268/// big: KBox::init(init_zeroed(), GFP_KERNEL)?,269/// small: [0; 1024 * 1024],270/// ptr: core::ptr::null_mut(),271/// }? Error)272/// }273/// }274/// ```275///276/// [`Infallible`]: core::convert::Infallible277/// [`pin_init!`]: pin_init::pin_init278/// [`Error`]: crate::error::Error279#[macro_export]280macro_rules! try_pin_init {281($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {282$($fields:tt)*283}) => {284::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? {285$($fields)*286}? $crate::error::Error)287};288($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {289$($fields:tt)*290}? $err:ty) => {291::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? {292$($fields)*293}? $err)294};295}296297298