aboutsummaryrefslogtreecommitdiff
path: root/rust/kernel/debugfs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/kernel/debugfs.rs')
-rw-r--r--rust/kernel/debugfs.rs184
1 files changed, 157 insertions, 27 deletions
diff --git a/rust/kernel/debugfs.rs b/rust/kernel/debugfs.rs
index 8c35d032acfe..d7b8014a6474 100644
--- a/rust/kernel/debugfs.rs
+++ b/rust/kernel/debugfs.rs
@@ -8,25 +8,52 @@
// When DebugFS is disabled, many parameters are dead. Linting for this isn't helpful.
#![cfg_attr(not(CONFIG_DEBUG_FS), allow(unused_variables))]
-use crate::fmt;
-use crate::prelude::*;
-use crate::str::CStr;
#[cfg(CONFIG_DEBUG_FS)]
use crate::sync::Arc;
-use crate::uaccess::UserSliceReader;
-use core::marker::PhantomData;
-use core::marker::PhantomPinned;
+use crate::{
+ fmt,
+ prelude::*,
+ str::CStr,
+ uaccess::UserSliceReader, //
+};
+
#[cfg(CONFIG_DEBUG_FS)]
use core::mem::ManuallyDrop;
-use core::ops::Deref;
+use core::{
+ marker::{
+ PhantomData,
+ PhantomPinned, //
+ },
+ ops::Deref,
+};
mod traits;
-pub use traits::{Reader, Writer};
+pub use traits::{
+ BinaryReader,
+ BinaryReaderMut,
+ BinaryWriter,
+ Reader,
+ Writer, //
+};
mod callback_adapters;
-use callback_adapters::{FormatAdapter, NoWriter, WritableAdapter};
+use callback_adapters::{
+ FormatAdapter,
+ NoWriter,
+ WritableAdapter, //
+};
+
mod file_ops;
-use file_ops::{FileOps, ReadFile, ReadWriteFile, WriteFile};
+use file_ops::{
+ BinaryReadFile,
+ BinaryReadWriteFile,
+ BinaryWriteFile,
+ FileOps,
+ ReadFile,
+ ReadWriteFile,
+ WriteFile, //
+};
+
#[cfg(CONFIG_DEBUG_FS)]
mod entry;
#[cfg(CONFIG_DEBUG_FS)]
@@ -99,9 +126,8 @@ impl Dir {
/// # Examples
///
/// ```
- /// # use kernel::c_str;
/// # use kernel::debugfs::Dir;
- /// let debugfs = Dir::new(c_str!("parent"));
+ /// let debugfs = Dir::new(c"parent");
/// ```
pub fn new(name: &CStr) -> Self {
Dir::create(name, None)
@@ -112,10 +138,9 @@ impl Dir {
/// # Examples
///
/// ```
- /// # use kernel::c_str;
/// # use kernel::debugfs::Dir;
- /// let parent = Dir::new(c_str!("parent"));
- /// let child = parent.subdir(c_str!("child"));
+ /// let parent = Dir::new(c"parent");
+ /// let child = parent.subdir(c"child");
/// ```
pub fn subdir(&self, name: &CStr) -> Self {
Dir::create(name, Some(self))
@@ -129,11 +154,10 @@ impl Dir {
/// # Examples
///
/// ```
- /// # use kernel::c_str;
/// # use kernel::debugfs::Dir;
/// # use kernel::prelude::*;
- /// # let dir = Dir::new(c_str!("my_debugfs_dir"));
- /// let file = KBox::pin_init(dir.read_only_file(c_str!("foo"), 200), GFP_KERNEL)?;
+ /// # let dir = Dir::new(c"my_debugfs_dir");
+ /// let file = KBox::pin_init(dir.read_only_file(c"foo", 200), GFP_KERNEL)?;
/// // "my_debugfs_dir/foo" now contains the number 200.
/// // The file is removed when `file` is dropped.
/// # Ok::<(), Error>(())
@@ -150,6 +174,31 @@ impl Dir {
self.create_file(name, data, file_ops)
}
+ /// Creates a read-only binary file in this directory.
+ ///
+ /// The file's contents are produced by invoking [`BinaryWriter::write_to_slice`] on the value
+ /// initialized by `data`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use kernel::debugfs::Dir;
+ /// # use kernel::prelude::*;
+ /// # let dir = Dir::new(c"my_debugfs_dir");
+ /// let file = KBox::pin_init(dir.read_binary_file(c"foo", [0x1, 0x2]), GFP_KERNEL)?;
+ /// # Ok::<(), Error>(())
+ /// ```
+ pub fn read_binary_file<'a, T, E: 'a>(
+ &'a self,
+ name: &'a CStr,
+ data: impl PinInit<T, E> + 'a,
+ ) -> impl PinInit<File<T>, E> + 'a
+ where
+ T: BinaryWriter + Send + Sync + 'static,
+ {
+ self.create_file(name, data, &T::FILE_OPS)
+ }
+
/// Creates a read-only file in this directory, with contents from a callback.
///
/// `f` must be a function item or a non-capturing closure.
@@ -158,21 +207,25 @@ impl Dir {
/// # Examples
///
/// ```
- /// # use core::sync::atomic::{AtomicU32, Ordering};
- /// # use kernel::c_str;
- /// # use kernel::debugfs::Dir;
- /// # use kernel::prelude::*;
- /// # let dir = Dir::new(c_str!("foo"));
+ /// # use kernel::{
+ /// # debugfs::Dir,
+ /// # prelude::*,
+ /// # sync::atomic::{
+ /// # Atomic,
+ /// # Relaxed,
+ /// # },
+ /// # };
+ /// # let dir = Dir::new(c"foo");
/// let file = KBox::pin_init(
- /// dir.read_callback_file(c_str!("bar"),
- /// AtomicU32::new(3),
+ /// dir.read_callback_file(c"bar",
+ /// Atomic::<u32>::new(3),
/// &|val, f| {
- /// let out = val.load(Ordering::Relaxed);
+ /// let out = val.load(Relaxed);
/// writeln!(f, "{out:#010x}")
/// }),
/// GFP_KERNEL)?;
/// // Reading "foo/bar" will show "0x00000003".
- /// file.store(10, Ordering::Relaxed);
+ /// file.store(10, Relaxed);
/// // Reading "foo/bar" will now show "0x0000000a".
/// # Ok::<(), Error>(())
/// ```
@@ -206,6 +259,22 @@ impl Dir {
self.create_file(name, data, file_ops)
}
+ /// Creates a read-write binary file in this directory.
+ ///
+ /// Reading the file uses the [`BinaryWriter`] implementation.
+ /// Writing to the file uses the [`BinaryReader`] implementation.
+ pub fn read_write_binary_file<'a, T, E: 'a>(
+ &'a self,
+ name: &'a CStr,
+ data: impl PinInit<T, E> + 'a,
+ ) -> impl PinInit<File<T>, E> + 'a
+ where
+ T: BinaryWriter + BinaryReader + Send + Sync + 'static,
+ {
+ let file_ops = &<T as BinaryReadWriteFile<_>>::FILE_OPS;
+ self.create_file(name, data, file_ops)
+ }
+
/// Creates a read-write file in this directory, with logic from callbacks.
///
/// Reading from the file is handled by `f`. Writing to the file is handled by `w`.
@@ -248,6 +317,23 @@ impl Dir {
self.create_file(name, data, &T::FILE_OPS)
}
+ /// Creates a write-only binary file in this directory.
+ ///
+ /// The file owns its backing data. Writing to the file uses the [`BinaryReader`]
+ /// implementation.
+ ///
+ /// The file is removed when the returned [`File`] is dropped.
+ pub fn write_binary_file<'a, T, E: 'a>(
+ &'a self,
+ name: &'a CStr,
+ data: impl PinInit<T, E> + 'a,
+ ) -> impl PinInit<File<T>, E> + 'a
+ where
+ T: BinaryReader + Send + Sync + 'static,
+ {
+ self.create_file(name, data, &T::FILE_OPS)
+ }
+
/// Creates a write-only file in this directory, with write logic from a callback.
///
/// `w` must be a function item or a non-capturing closure.
@@ -468,6 +554,20 @@ impl<'data, 'dir> ScopedDir<'data, 'dir> {
self.create_file(name, data, &T::FILE_OPS)
}
+ /// Creates a read-only binary file in this directory.
+ ///
+ /// The file's contents are produced by invoking [`BinaryWriter::write_to_slice`].
+ ///
+ /// 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,
+ ) {
+ self.create_file(name, data, &T::FILE_OPS)
+ }
+
/// Creates a read-only file in this directory, with contents from a callback.
///
/// The file contents are generated by calling `f` with `data`.
@@ -505,6 +605,22 @@ impl<'data, 'dir> ScopedDir<'data, 'dir> {
self.create_file(name, data, vtable)
}
+ /// Creates a read-write binary file in this directory.
+ ///
+ /// Reading the file uses the [`BinaryWriter`] implementation on `data`. Writing to the file
+ /// uses the [`BinaryReader`] implementation on `data`.
+ ///
+ /// 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>(
+ &self,
+ name: &CStr,
+ data: &'data T,
+ ) {
+ let vtable = &<T as BinaryReadWriteFile<_>>::FILE_OPS;
+ self.create_file(name, data, vtable)
+ }
+
/// Creates a read-write file in this directory, with logic from callbacks.
///
/// Reading from the file is handled by `f`. Writing to the file is handled by `w`.
@@ -544,6 +660,20 @@ impl<'data, 'dir> ScopedDir<'data, 'dir> {
self.create_file(name, data, vtable)
}
+ /// Creates a write-only binary file in this directory.
+ ///
+ /// Writing to the file uses the [`BinaryReader`] implementation on `data`.
+ ///
+ /// 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,
+ ) {
+ self.create_file(name, data, &T::FILE_OPS)
+ }
+
/// Creates a write-only file in this directory, with write logic from a callback.
///
/// Writing to the file is handled by `w`.