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:
Alvin Sun
2026-08-12 09:36:26 +02:00
committed by Miguel Ojeda
parent 0752a2e96e
commit 54f846db7b
2 changed files with 26 additions and 1 deletions
+9
View File
@@ -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
View File
@@ -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