mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:09:29 +02:00
rust: module: add THIS_MODULE const to ModuleMetadata trait
Since `const_refs_to_static` has been stable as of the MSRV bump, a `ThisModule` pointer can now be used in const contexts. Add a `THIS_MODULE` const to the `ModuleMetadata` trait so that modules can provide their `ThisModule` pointer in const contexts such as static `file_operations`. Add a `this_module()` helper to retrieve the `THIS_MODULE` pointer of a given module type, and update `__init` to use it instead of the `THIS_MODULE` static generated by the `module!` macro. The `static THIS_MODULE` generated by the `module!` macro is retained for backwards compatibility with existing users and removed in a later patch once all references have been migrated. Assisted-by: opencode:glm-5.2 Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Gary Guo <gary@garyguo.net> Acked-by: Danilo Krummrich <dakr@kernel.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Alvin Sun <alvin.sun@linux.dev> Link: https://patch.msgid.link/20260811-fix-fops-owner-v10-2-7e71776f9dbe@linux.dev Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
@@ -42,6 +42,15 @@ impl<T: Module> InPlaceModule for T {
|
||||
pub trait ModuleMetadata {
|
||||
/// The name of the module as specified in the `module!` macro.
|
||||
const NAME: &'static crate::str::CStr;
|
||||
|
||||
/// The module's `THIS_MODULE` pointer.
|
||||
const THIS_MODULE: ThisModule;
|
||||
}
|
||||
|
||||
/// Returns a reference to the `THIS_MODULE` of the given module type.
|
||||
#[inline]
|
||||
pub const fn this_module<M: ModuleMetadata>() -> &'static ThisModule {
|
||||
&M::THIS_MODULE
|
||||
}
|
||||
|
||||
/// Equivalent to `THIS_MODULE` in the C API.
|
||||
|
||||
+17
-1
@@ -519,6 +519,22 @@ pub(crate) fn module(info: ModuleInfo) -> Result<TokenStream> {
|
||||
|
||||
impl ::kernel::ModuleMetadata for #type_ {
|
||||
const NAME: &'static ::kernel::str::CStr = #name_cstr;
|
||||
|
||||
#[cfg(MODULE)]
|
||||
const THIS_MODULE: ::kernel::ThisModule = {
|
||||
extern "C" {
|
||||
static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
|
||||
}
|
||||
|
||||
// SAFETY: `__this_module` is constructed by the kernel at load time
|
||||
// and lives until the module is unloaded.
|
||||
unsafe { ::kernel::ThisModule::from_ptr(__this_module.get()) }
|
||||
};
|
||||
|
||||
#[cfg(not(MODULE))]
|
||||
const THIS_MODULE: ::kernel::ThisModule = unsafe {
|
||||
::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
|
||||
};
|
||||
}
|
||||
|
||||
// Double nested modules, since then nobody can access the public items inside.
|
||||
@@ -616,7 +632,7 @@ pub(crate) fn module(info: ModuleInfo) -> Result<TokenStream> {
|
||||
/// This function must only be called once.
|
||||
unsafe fn __init() -> ::kernel::ffi::c_int {
|
||||
let initer = <super::super::LocalModule as ::kernel::InPlaceModule>::init(
|
||||
&super::super::THIS_MODULE
|
||||
::kernel::module::this_module::<super::super::LocalModule>()
|
||||
);
|
||||
// SAFETY: No data race, since `__MOD` can only be accessed by this module
|
||||
// and there only `__init` and `__exit` access it. These functions are only
|
||||
|
||||
Reference in New Issue
Block a user