mirror of
https://github.com/torvalds/linux.git
synced 2026-10-22 23:01:49 +02:00
rust: debugfs: drop 'static bound from ScopedDir file creation methods
Drop the T: 'static bound from ScopedDir's file creation methods (read_binary_file(), read_only_file(), etc.) to support registering debugfs files backed by types that contain non-'static references, such as dma::Coherent<'a, T>. The previous 'static bound existed because ScopedDir::create_file() took &'static FileOps<T>, and &'static requires T: 'static for well- formedness. However, this was overly conservative: the file_operations pointer passed to the C debugfs API just needs to be 'static, not the entire FileOps<T>. Store &'static bindings::file_operations in FileOps<T> instead of the file_operations by value. In each trait impl, take a reference to the file_operations struct within the const block; since bindings::file_operations does not mention T, the reference is promoted to 'static regardless of T's lifetime parameters. Replace the Deref impl with an explicit fops() method that returns the stored &'static reference. Link: https://lore.kernel.org/driver-core/20260830193824.471089-2-dakr@kernel.org Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://patch.msgid.link/20260830193824.471089-2-dakr@kernel.org [ Remove unrelated change from Self to T. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
parent
cee9395acd
commit
9dc6cedcd9
|
|
@ -538,7 +538,7 @@ pub fn dir<'dir2>(&'dir2 self, name: &CStr) -> ScopedDir<'data, 'dir2> {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_file<T: Sync>(&self, name: &CStr, data: &'data T, vtable: &'static FileOps<T>) {
|
||||
fn create_file<T: Sync>(&self, name: &CStr, data: &'data T, vtable: &FileOps<T>) {
|
||||
#[cfg(CONFIG_DEBUG_FS)]
|
||||
core::mem::forget(Entry::file(name, &self.entry, data, vtable));
|
||||
}
|
||||
|
|
@ -550,7 +550,7 @@ fn create_file<T: Sync>(&self, name: &CStr, data: &'data T, vtable: &'static Fil
|
|||
/// This function does not produce an owning handle to the file. The created
|
||||
/// file is removed when the [`Scope`] that this directory belongs
|
||||
/// to is dropped.
|
||||
pub fn read_only_file<T: Writer + Send + Sync + 'static>(&self, name: &CStr, data: &'data T) {
|
||||
pub fn read_only_file<T: Writer + Send + Sync>(&self, name: &CStr, data: &'data T) {
|
||||
self.create_file(name, data, &T::FILE_OPS)
|
||||
}
|
||||
|
||||
|
|
@ -560,11 +560,7 @@ pub fn read_only_file<T: Writer + Send + Sync + 'static>(&self, name: &CStr, dat
|
|||
///
|
||||
/// This function does not produce an owning handle to the file. The created file is removed
|
||||
/// when the [`Scope`] that this directory belongs to is dropped.
|
||||
pub fn read_binary_file<T: BinaryWriter + Send + Sync + 'static>(
|
||||
&self,
|
||||
name: &CStr,
|
||||
data: &'data T,
|
||||
) {
|
||||
pub fn read_binary_file<T: BinaryWriter + Send + Sync>(&self, name: &CStr, data: &'data T) {
|
||||
self.create_file(name, data, &T::FILE_OPS)
|
||||
}
|
||||
|
||||
|
|
@ -596,11 +592,7 @@ pub fn read_callback_file<T, F>(&self, name: &CStr, data: &'data T, _f: &'static
|
|||
/// This function does not produce an owning handle to the file. The created
|
||||
/// file is removed when the [`Scope`] that this directory belongs
|
||||
/// to is dropped.
|
||||
pub fn read_write_file<T: Writer + Reader + Send + Sync + 'static>(
|
||||
&self,
|
||||
name: &CStr,
|
||||
data: &'data T,
|
||||
) {
|
||||
pub fn read_write_file<T: Writer + Reader + Send + Sync>(&self, name: &CStr, data: &'data T) {
|
||||
let vtable = &<T as ReadWriteFile<_>>::FILE_OPS;
|
||||
self.create_file(name, data, vtable)
|
||||
}
|
||||
|
|
@ -612,7 +604,7 @@ pub fn read_write_file<T: Writer + Reader + Send + Sync + 'static>(
|
|||
///
|
||||
/// This function does not produce an owning handle to the file. The created file is removed
|
||||
/// when the [`Scope`] that this directory belongs to is dropped.
|
||||
pub fn read_write_binary_file<T: BinaryWriter + BinaryReader + Send + Sync + 'static>(
|
||||
pub fn read_write_binary_file<T: BinaryWriter + BinaryReader + Send + Sync>(
|
||||
&self,
|
||||
name: &CStr,
|
||||
data: &'data T,
|
||||
|
|
@ -655,7 +647,7 @@ pub fn read_write_callback_file<T, F, W>(
|
|||
/// This function does not produce an owning handle to the file. The created
|
||||
/// file is removed when the [`Scope`] that this directory belongs
|
||||
/// to is dropped.
|
||||
pub fn write_only_file<T: Reader + Send + Sync + 'static>(&self, name: &CStr, data: &'data T) {
|
||||
pub fn write_only_file<T: Reader + Send + Sync>(&self, name: &CStr, data: &'data T) {
|
||||
let vtable = &<T as WriteFile<_>>::FILE_OPS;
|
||||
self.create_file(name, data, vtable)
|
||||
}
|
||||
|
|
@ -666,11 +658,7 @@ pub fn write_only_file<T: Reader + Send + Sync + 'static>(&self, name: &CStr, da
|
|||
///
|
||||
/// This function does not produce an owning handle to the file. The created file is removed
|
||||
/// when the [`Scope`] that this directory belongs to is dropped.
|
||||
pub fn write_binary_file<T: BinaryReader + Send + Sync + 'static>(
|
||||
&self,
|
||||
name: &CStr,
|
||||
data: &'data T,
|
||||
) {
|
||||
pub fn write_binary_file<T: BinaryReader + Send + Sync>(&self, name: &CStr, data: &'data T) {
|
||||
self.create_file(name, data, &T::FILE_OPS)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ pub(crate) unsafe fn dynamic_file<T>(
|
|||
parent.as_ptr(),
|
||||
core::ptr::from_ref(data) as *mut c_void,
|
||||
core::ptr::null(),
|
||||
&**file_ops,
|
||||
file_ops.fops(),
|
||||
)
|
||||
};
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ pub(crate) fn file<T>(
|
|||
parent.as_ptr(),
|
||||
core::ptr::from_ref(data) as *mut c_void,
|
||||
core::ptr::null(),
|
||||
&**file_ops,
|
||||
file_ops.fops(),
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,6 @@
|
|||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
#[cfg(CONFIG_DEBUG_FS)]
|
||||
use core::ops::Deref;
|
||||
|
||||
/// # Invariant
|
||||
///
|
||||
/// `FileOps<T>` will always contain an `operations` which is safe to use for a file backed
|
||||
|
|
@ -30,7 +27,7 @@
|
|||
/// into a reference.
|
||||
pub(super) struct FileOps<T> {
|
||||
#[cfg(CONFIG_DEBUG_FS)]
|
||||
operations: bindings::file_operations,
|
||||
operations: &'static bindings::file_operations,
|
||||
#[cfg(CONFIG_DEBUG_FS)]
|
||||
mode: u16,
|
||||
_phantom: PhantomData<T>,
|
||||
|
|
@ -41,7 +38,7 @@ impl<T> FileOps<T> {
|
|||
///
|
||||
/// The caller asserts that the provided `operations` is safe to use for a file whose
|
||||
/// inode has a pointer to `T` in its private data that is safe to convert into a reference.
|
||||
const unsafe fn new(operations: bindings::file_operations, mode: u16) -> Self {
|
||||
const unsafe fn new(operations: &'static bindings::file_operations, mode: u16) -> Self {
|
||||
Self {
|
||||
#[cfg(CONFIG_DEBUG_FS)]
|
||||
operations,
|
||||
|
|
@ -65,11 +62,11 @@ pub(super) const fn adapt(&self) -> &FileOps<T::Inner> {
|
|||
}
|
||||
|
||||
#[cfg(CONFIG_DEBUG_FS)]
|
||||
impl<T> Deref for FileOps<T> {
|
||||
type Target = bindings::file_operations;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.operations
|
||||
impl<T> FileOps<T> {
|
||||
/// Returns a `'static` reference to the inner `file_operations`.
|
||||
#[inline]
|
||||
pub(crate) fn fops(&self) -> &'static bindings::file_operations {
|
||||
self.operations
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +127,7 @@ pub(crate) trait ReadFile<T> {
|
|||
|
||||
impl<T: Writer + Sync> ReadFile<T> for T {
|
||||
const FILE_OPS: FileOps<T> = {
|
||||
let operations = bindings::file_operations {
|
||||
let operations = &bindings::file_operations {
|
||||
read: Some(bindings::seq_read),
|
||||
llseek: Some(bindings::seq_lseek),
|
||||
release: Some(bindings::single_release),
|
||||
|
|
@ -181,7 +178,7 @@ pub(crate) trait ReadWriteFile<T> {
|
|||
|
||||
impl<T: Writer + Reader + Sync> ReadWriteFile<T> for T {
|
||||
const FILE_OPS: FileOps<T> = {
|
||||
let operations = bindings::file_operations {
|
||||
let operations = &bindings::file_operations {
|
||||
open: Some(writer_open::<T>),
|
||||
read: Some(bindings::seq_read),
|
||||
write: Some(write::<T>),
|
||||
|
|
@ -238,7 +235,7 @@ pub(crate) trait WriteFile<T> {
|
|||
|
||||
impl<T: Reader + Sync> WriteFile<T> for T {
|
||||
const FILE_OPS: FileOps<T> = {
|
||||
let operations = bindings::file_operations {
|
||||
let operations = &bindings::file_operations {
|
||||
open: Some(write_only_open),
|
||||
write: Some(write_only_write::<T>),
|
||||
llseek: Some(bindings::noop_llseek),
|
||||
|
|
@ -290,7 +287,7 @@ pub(crate) trait BinaryReadFile<T> {
|
|||
|
||||
impl<T: BinaryWriter + Sync> BinaryReadFile<T> for T {
|
||||
const FILE_OPS: FileOps<T> = {
|
||||
let operations = bindings::file_operations {
|
||||
let operations = &bindings::file_operations {
|
||||
read: Some(blob_read::<T>),
|
||||
llseek: Some(bindings::default_llseek),
|
||||
open: Some(bindings::simple_open),
|
||||
|
|
@ -344,7 +341,7 @@ pub(crate) trait BinaryWriteFile<T> {
|
|||
|
||||
impl<T: BinaryReader + Sync> BinaryWriteFile<T> for T {
|
||||
const FILE_OPS: FileOps<T> = {
|
||||
let operations = bindings::file_operations {
|
||||
let operations = &bindings::file_operations {
|
||||
write: Some(blob_write::<T>),
|
||||
llseek: Some(bindings::default_llseek),
|
||||
open: Some(bindings::simple_open),
|
||||
|
|
@ -368,7 +365,7 @@ pub(crate) trait BinaryReadWriteFile<T> {
|
|||
|
||||
impl<T: BinaryWriter + BinaryReader + Sync> BinaryReadWriteFile<T> for T {
|
||||
const FILE_OPS: FileOps<T> = {
|
||||
let operations = bindings::file_operations {
|
||||
let operations = &bindings::file_operations {
|
||||
read: Some(blob_read::<T>),
|
||||
write: Some(blob_write::<T>),
|
||||
llseek: Some(bindings::default_llseek),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user