Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: pin-init: move the default error behavior of `try_[pin_]init`

Move the ability to just write `try_pin_init!(Foo { a <- a_init })`
(note the missing `? Error` at the end) into the kernel crate.
Remove this notation from the pin-init crate, since the default when no
error is specified is the kernel-internal `Error` type. Instead add two
macros in the kernel crate that serve this default and are used instead
of the ones from `pin-init`.

This is done, because the `Error` type that is used as the default is
from the kernel crate and it thus prevents making the pin-init crate
standalone.

In order to not cause a build error due to a name overlap, the macros in
the pin-init crate are renamed, but this change is reverted in a future
commit when it is a standalone crate.

Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Link: https://lore.kernel.org/r/20250308110339.2997091-8-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

authored by

Benno Lossin and committed by
Miguel Ojeda
578eb8b6 c2ddbdbb

+126 -42
+113
rust/kernel/init.rs
··· 133 133 //! } 134 134 //! } 135 135 //! ``` 136 + 137 + /// Construct an in-place fallible initializer for `struct`s. 138 + /// 139 + /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use 140 + /// [`init!`]. 141 + /// 142 + /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error, 143 + /// append `? $type` after the `struct` initializer. 144 + /// The safety caveats from [`try_pin_init!`] also apply: 145 + /// - `unsafe` code must guarantee either full initialization or return an error and allow 146 + /// deallocation of the memory. 147 + /// - the fields are initialized in the order given in the initializer. 148 + /// - no references to fields are allowed to be created inside of the initializer. 149 + /// 150 + /// # Examples 151 + /// 152 + /// ```rust 153 + /// use kernel::{init::zeroed, error::Error}; 154 + /// struct BigBuf { 155 + /// big: KBox<[u8; 1024 * 1024 * 1024]>, 156 + /// small: [u8; 1024 * 1024], 157 + /// } 158 + /// 159 + /// impl BigBuf { 160 + /// fn new() -> impl Init<Self, Error> { 161 + /// try_init!(Self { 162 + /// big: KBox::init(zeroed(), GFP_KERNEL)?, 163 + /// small: [0; 1024 * 1024], 164 + /// }? Error) 165 + /// } 166 + /// } 167 + /// ``` 168 + /// 169 + /// [`Infallible`]: core::convert::Infallible 170 + /// [`init!`]: crate::init! 171 + /// [`try_pin_init!`]: crate::try_pin_init! 172 + /// [`Error`]: crate::error::Error 173 + #[macro_export] 174 + macro_rules! try_init { 175 + ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 176 + $($fields:tt)* 177 + }) => { 178 + $crate::_try_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? { 179 + $($fields)* 180 + }? $crate::error::Error) 181 + }; 182 + ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 183 + $($fields:tt)* 184 + }? $err:ty) => { 185 + $crate::_try_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? { 186 + $($fields)* 187 + }? $err) 188 + }; 189 + } 190 + 191 + /// Construct an in-place, fallible pinned initializer for `struct`s. 192 + /// 193 + /// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`]. 194 + /// 195 + /// You can use the `?` operator or use `return Err(err)` inside the initializer to stop 196 + /// initialization and return the error. 197 + /// 198 + /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when 199 + /// initialization fails, the memory can be safely deallocated without any further modifications. 200 + /// 201 + /// This macro defaults the error to [`Error`]. 202 + /// 203 + /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type` 204 + /// after the `struct` initializer to specify the error type you want to use. 205 + /// 206 + /// # Examples 207 + /// 208 + /// ```rust 209 + /// # #![feature(new_uninit)] 210 + /// use kernel::{init::zeroed, error::Error}; 211 + /// #[pin_data] 212 + /// struct BigBuf { 213 + /// big: KBox<[u8; 1024 * 1024 * 1024]>, 214 + /// small: [u8; 1024 * 1024], 215 + /// ptr: *mut u8, 216 + /// } 217 + /// 218 + /// impl BigBuf { 219 + /// fn new() -> impl PinInit<Self, Error> { 220 + /// try_pin_init!(Self { 221 + /// big: KBox::init(zeroed(), GFP_KERNEL)?, 222 + /// small: [0; 1024 * 1024], 223 + /// ptr: core::ptr::null_mut(), 224 + /// }? Error) 225 + /// } 226 + /// } 227 + /// ``` 228 + /// 229 + /// [`Infallible`]: core::convert::Infallible 230 + /// [`pin_init!`]: crate::pin_init 231 + /// [`Error`]: crate::error::Error 232 + #[macro_export] 233 + macro_rules! try_pin_init { 234 + ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 235 + $($fields:tt)* 236 + }) => { 237 + $crate::_try_pin_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? { 238 + $($fields)* 239 + }? $crate::error::Error) 240 + }; 241 + ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 242 + $($fields:tt)* 243 + }? $err:ty) => { 244 + $crate::_try_pin_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? { 245 + $($fields)* 246 + }? $err) 247 + }; 248 + }
+13 -42
rust/pin-init/src/lib.rs
··· 481 481 482 482 /// Construct an in-place, pinned initializer for `struct`s. 483 483 /// 484 - /// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use 484 + /// This macro defaults the error to [`Infallible`]. If you need a different error, then use 485 485 /// [`try_pin_init!`]. 486 486 /// 487 487 /// The syntax is almost identical to that of a normal `struct` initializer: ··· 676 676 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 677 677 $($fields:tt)* 678 678 }) => { 679 - $crate::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? { 679 + $crate::_try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? { 680 680 $($fields)* 681 681 }? ::core::convert::Infallible) 682 682 }; ··· 692 692 /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when 693 693 /// initialization fails, the memory can be safely deallocated without any further modifications. 694 694 /// 695 - /// This macro defaults the error to [`Error`]. 696 - /// 697 - /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type` 695 + /// The syntax is identical to [`pin_init!`] with the following exception: you must append `? $type` 698 696 /// after the `struct` initializer to specify the error type you want to use. 699 697 /// 700 698 /// # Examples ··· 722 724 // For a detailed example of how this macro works, see the module documentation of the hidden 723 725 // module `__internal` inside of `init/__internal.rs`. 724 726 #[macro_export] 725 - macro_rules! try_pin_init { 726 - ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 727 - $($fields:tt)* 728 - }) => { 729 - $crate::__init_internal!( 730 - @this($($this)?), 731 - @typ($t $(::<$($generics),*>)? ), 732 - @fields($($fields)*), 733 - @error($crate::error::Error), 734 - @data(PinData, use_data), 735 - @has_data(HasPinData, __pin_data), 736 - @construct_closure(pin_init_from_closure), 737 - @munch_fields($($fields)*), 738 - ) 739 - }; 727 + macro_rules! _try_pin_init { 740 728 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 741 729 $($fields:tt)* 742 730 }? $err:ty) => { ··· 736 752 @construct_closure(pin_init_from_closure), 737 753 @munch_fields($($fields)*), 738 754 ) 739 - }; 755 + } 740 756 } 741 757 742 758 /// Construct an in-place initializer for `struct`s. 743 759 /// 744 - /// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use 760 + /// This macro defaults the error to [`Infallible`]. If you need a different error, then use 745 761 /// [`try_init!`]. 746 762 /// 747 763 /// The syntax is identical to [`pin_init!`] and its safety caveats also apply: ··· 761 777 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 762 778 $($fields:tt)* 763 779 }) => { 764 - $crate::try_init!($(&$this in)? $t $(::<$($generics),*>)? { 780 + $crate::_try_init!($(&$this in)? $t $(::<$($generics),*>)? { 765 781 $($fields)* 766 782 }? ::core::convert::Infallible) 767 783 } ··· 769 785 770 786 /// Construct an in-place fallible initializer for `struct`s. 771 787 /// 772 - /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use 788 + /// If the initialization can complete without error (or [`Infallible`]), then use 773 789 /// [`init!`]. 774 790 /// 775 - /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error, 776 - /// append `? $type` after the `struct` initializer. 791 + /// The syntax is identical to [`try_pin_init!`]. You need to specify a custom error 792 + /// via `? $type` after the `struct` initializer. 777 793 /// The safety caveats from [`try_pin_init!`] also apply: 778 794 /// - `unsafe` code must guarantee either full initialization or return an error and allow 779 795 /// deallocation of the memory. ··· 800 816 /// } 801 817 /// } 802 818 /// ``` 819 + /// [`try_pin_init!`]: crate::try_pin_init 803 820 // For a detailed example of how this macro works, see the module documentation of the hidden 804 821 // module `__internal` inside of `init/__internal.rs`. 805 822 #[macro_export] 806 - macro_rules! try_init { 807 - ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 808 - $($fields:tt)* 809 - }) => { 810 - $crate::__init_internal!( 811 - @this($($this)?), 812 - @typ($t $(::<$($generics),*>)?), 813 - @fields($($fields)*), 814 - @error($crate::error::Error), 815 - @data(InitData, /*no use_data*/), 816 - @has_data(HasInitData, __init_data), 817 - @construct_closure(init_from_closure), 818 - @munch_fields($($fields)*), 819 - ) 820 - }; 823 + macro_rules! _try_init { 821 824 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 822 825 $($fields:tt)* 823 826 }? $err:ty) => { ··· 818 847 @construct_closure(init_from_closure), 819 848 @munch_fields($($fields)*), 820 849 ) 821 - }; 850 + } 822 851 } 823 852 824 853 /// Asserts that a field on a struct using `#[pin_data]` is marked with `#[pin]` ie. that it is