// 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::disallowed_names, 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//! # #![expect(unreachable_pub, clippy::disallowed_names)]70//! use kernel::{prelude::*, types::Opaque};71//! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin};72//! # mod bindings {73//! # #![expect(non_camel_case_types, clippy::missing_safety_doc)]74//! # pub struct foo;75//! # pub unsafe fn init_foo(_ptr: *mut foo) {}76//! # pub unsafe fn destroy_foo(_ptr: *mut foo) {}77//! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 }78//! # }79//! /// # Invariants80//! ///81//! /// `foo` is always initialized82//! #[pin_data(PinnedDrop)]83//! pub struct RawFoo {84//! #[pin]85//! foo: Opaque<bindings::foo>,86//! #[pin]87//! _p: PhantomPinned,88//! }89//!90//! impl RawFoo {91//! pub fn new(flags: u32) -> impl PinInit<Self, Error> {92//! // SAFETY:93//! // - when the closure returns `Ok(())`, then it has successfully initialized and94//! // enabled `foo`,95//! // - when it returns `Err(e)`, then it has cleaned up before96//! unsafe {97//! pin_init::pin_init_from_closure(move |slot: *mut Self| {98//! // `slot` contains uninit memory, avoid creating a reference.99//! let foo = addr_of_mut!((*slot).foo);100//!101//! // Initialize the `foo`102//! bindings::init_foo(Opaque::cast_into(foo));103//!104//! // Try to enable it.105//! let err = bindings::enable_foo(Opaque::cast_into(foo), flags);106//! if err != 0 {107//! // Enabling has failed, first clean up the foo and then return the error.108//! bindings::destroy_foo(Opaque::cast_into(foo));109//! return Err(Error::from_errno(err));110//! }111//!112//! // All fields of `RawFoo` have been initialized, since `_p` is a ZST.113//! Ok(())114//! })115//! }116//! }117//! }118//!119//! #[pinned_drop]120//! impl PinnedDrop for RawFoo {121//! fn drop(self: Pin<&mut Self>) {122//! // SAFETY: Since `foo` is initialized, destroying is safe.123//! unsafe { bindings::destroy_foo(self.foo.get()) };124//! }125//! }126//! ```127128use crate::{129alloc::{AllocError, Flags},130error::{self, Error},131};132use pin_init::{init_from_closure, pin_init_from_closure, Init, PinInit};133134/// Smart pointer that can initialize memory in-place.135pub trait InPlaceInit<T>: Sized {136/// Pinned version of `Self`.137///138/// If a type already implicitly pins its pointee, `Pin<Self>` is unnecessary. In this case use139/// `Self`, otherwise just use `Pin<Self>`.140type PinnedSelf;141142/// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this143/// type.144///145/// If `T: !Unpin` it will not be able to move afterwards.146fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>147where148E: From<AllocError>;149150/// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this151/// type.152///153/// If `T: !Unpin` it will not be able to move afterwards.154fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf>155where156Error: From<E>,157{158// SAFETY: We delegate to `init` and only change the error type.159let init = unsafe {160pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))161};162Self::try_pin_init(init, flags)163}164165/// Use the given initializer to in-place initialize a `T`.166fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>167where168E: From<AllocError>;169170/// Use the given initializer to in-place initialize a `T`.171fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>172where173Error: From<E>,174{175// SAFETY: We delegate to `init` and only change the error type.176let init = unsafe {177init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))178};179Self::try_init(init, flags)180}181}182183/// Construct an in-place fallible initializer for `struct`s.184///185/// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use186/// [`init!`].187///188/// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error,189/// append `? $type` after the `struct` initializer.190/// The safety caveats from [`try_pin_init!`] also apply:191/// - `unsafe` code must guarantee either full initialization or return an error and allow192/// deallocation of the memory.193/// - the fields are initialized in the order given in the initializer.194/// - no references to fields are allowed to be created inside of the initializer.195///196/// # Examples197///198/// ```rust199/// use kernel::error::Error;200/// use pin_init::init_zeroed;201/// struct BigBuf {202/// big: KBox<[u8; 1024 * 1024 * 1024]>,203/// small: [u8; 1024 * 1024],204/// }205///206/// impl BigBuf {207/// fn new() -> impl Init<Self, Error> {208/// try_init!(Self {209/// big: KBox::init(init_zeroed(), GFP_KERNEL)?,210/// small: [0; 1024 * 1024],211/// }? Error)212/// }213/// }214/// ```215///216/// [`Infallible`]: core::convert::Infallible217/// [`init!`]: pin_init::init218/// [`try_pin_init!`]: crate::try_pin_init!219/// [`Error`]: crate::error::Error220#[macro_export]221macro_rules! try_init {222($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {223$($fields:tt)*224}) => {225::pin_init::try_init!($(&$this in)? $t $(::<$($generics),*>)? {226$($fields)*227}? $crate::error::Error)228};229($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {230$($fields:tt)*231}? $err:ty) => {232::pin_init::try_init!($(&$this in)? $t $(::<$($generics),*>)? {233$($fields)*234}? $err)235};236}237238/// Construct an in-place, fallible pinned initializer for `struct`s.239///240/// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`].241///242/// You can use the `?` operator or use `return Err(err)` inside the initializer to stop243/// initialization and return the error.244///245/// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when246/// initialization fails, the memory can be safely deallocated without any further modifications.247///248/// This macro defaults the error to [`Error`].249///250/// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type`251/// after the `struct` initializer to specify the error type you want to use.252///253/// # Examples254///255/// ```rust256/// # #![feature(new_uninit)]257/// use kernel::error::Error;258/// use pin_init::init_zeroed;259/// #[pin_data]260/// struct BigBuf {261/// big: KBox<[u8; 1024 * 1024 * 1024]>,262/// small: [u8; 1024 * 1024],263/// ptr: *mut u8,264/// }265///266/// impl BigBuf {267/// fn new() -> impl PinInit<Self, Error> {268/// try_pin_init!(Self {269/// big: KBox::init(init_zeroed(), GFP_KERNEL)?,270/// small: [0; 1024 * 1024],271/// ptr: core::ptr::null_mut(),272/// }? Error)273/// }274/// }275/// ```276///277/// [`Infallible`]: core::convert::Infallible278/// [`pin_init!`]: pin_init::pin_init279/// [`Error`]: crate::error::Error280#[macro_export]281macro_rules! try_pin_init {282($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {283$($fields:tt)*284}) => {285::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? {286$($fields)*287}? $crate::error::Error)288};289($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {290$($fields:tt)*291}? $err:ty) => {292::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? {293$($fields)*294}? $err)295};296}297298299