Provides an example of using the Rust DebugFS bindings.
Signed-off-by: Matthew Maurer <mmaurer@google.com>
---
MAINTAINERS | 1 +
samples/rust/Kconfig | 11 +++++++++++
samples/rust/Makefile | 1 +
samples/rust/rust_debugfs.rs | 37 +++++++++++++++++++++++++++++++++++++
4 files changed, 50 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index a3b835e427b083a4ddd690d9e7739851f0af47ae..426bcdac025134e20911de8e2cf5c9efb0591814 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7278,6 +7278,7 @@ F: rust/kernel/devres.rs
F: rust/kernel/driver.rs
F: rust/kernel/faux.rs
F: rust/kernel/platform.rs
+F: samples/rust/rust_debugfs.rs
F: samples/rust/rust_driver_platform.rs
F: samples/rust/rust_driver_faux.rs
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig
index 43cb72d72631bb2d6e06185e1d88778edff6ee13..6c42ed73f842cda26256039e6917bb443738d3f1 100644
--- a/samples/rust/Kconfig
+++ b/samples/rust/Kconfig
@@ -51,6 +51,17 @@ config SAMPLE_RUST_DMA
If unsure, say N.
+config SAMPLE_RUST_DEBUGFS
+ tristate "DebugFS Test Driver"
+ depends on DEBUG_FS
+ help
+ This option builds the Rust DebugFS Test driver sample.
+
+ To compile this as a module, choose M here:
+ the module will be called rust_debugfs.
+
+ If unsure, say N.
+
config SAMPLE_RUST_DRIVER_PCI
tristate "PCI Driver"
depends on PCI
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
index 6a466afd2a21eba84a3b7b2be29f25dce44e9053..b1fc4677ed53fcf7d0f5a3dbf322f65851bc1784 100644
--- a/samples/rust/Makefile
+++ b/samples/rust/Makefile
@@ -4,6 +4,7 @@ ccflags-y += -I$(src) # needed for trace events
obj-$(CONFIG_SAMPLE_RUST_MINIMAL) += rust_minimal.o
obj-$(CONFIG_SAMPLE_RUST_MISC_DEVICE) += rust_misc_device.o
obj-$(CONFIG_SAMPLE_RUST_PRINT) += rust_print.o
+obj-$(CONFIG_SAMPLE_RUST_DEBUGFS) += rust_debugfs.o
obj-$(CONFIG_SAMPLE_RUST_DMA) += rust_dma.o
obj-$(CONFIG_SAMPLE_RUST_DRIVER_PCI) += rust_driver_pci.o
obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o
diff --git a/samples/rust/rust_debugfs.rs b/samples/rust/rust_debugfs.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ce3e1a997bf314f63026446f5a6d2a00579c602a
--- /dev/null
+++ b/samples/rust/rust_debugfs.rs
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+
+// Copyright (C) 2025 Google LLC.
+
+//! Sample DebugFS exporting module
+
+use core::sync::atomic::{AtomicU32, Ordering};
+use kernel::c_str;
+use kernel::debugfs::Dir;
+use kernel::prelude::*;
+
+module! {
+ type: RustDebugFs,
+ name: "rust_debugfs",
+ authors: ["Matthew Maurer"],
+ description: "Rust DebugFS usage sample",
+ license: "GPL",
+}
+
+struct RustDebugFs {
+ _debugfs: Dir,
+}
+
+static EXAMPLE: AtomicU32 = AtomicU32::new(8);
+
+impl kernel::Module for RustDebugFs {
+ fn init(_this: &'static ThisModule) -> Result<Self> {
+ let debugfs = Dir::new(c_str!("sample_debugfs"));
+ debugfs
+ .fmt_file(c_str!("example"), &EXAMPLE, &|example, f| {
+ writeln!(f, "Reading atomic: {}", example.load(Ordering::Relaxed))
+ })
+ .keep();
+ EXAMPLE.store(10, Ordering::Relaxed);
+ Ok(Self { _debugfs: debugfs })
+ }
+}
--
2.49.0.906.g1f30a19c02-goog
On Wed, Apr 30, 2025 at 11:31:59PM +0000, Matthew Maurer wrote:
> Provides an example of using the Rust DebugFS bindings.
>
> Signed-off-by: Matthew Maurer <mmaurer@google.com>
Much nicer, many thanks for this!
Some minor comments on the sample code here. As someone coming from C
with limited Rust experience, I think I do understand it, but I think it
could use a bunch of comments to make it more "obvious" what is
happening, see below.
> +static EXAMPLE: AtomicU32 = AtomicU32::new(8);
Wait, why is this set to 8 and then you automatically set it to 10 after
you create the file? No one is ever going to see 8 as a valid value
unless they really race to read the file, right?
> +impl kernel::Module for RustDebugFs {
> + fn init(_this: &'static ThisModule) -> Result<Self> {
> + let debugfs = Dir::new(c_str!("sample_debugfs"));
> + debugfs
> + .fmt_file(c_str!("example"), &EXAMPLE, &|example, f| {
> + writeln!(f, "Reading atomic: {}", example.load(Ordering::Relaxed))
> + })
> + .keep();
> + EXAMPLE.store(10, Ordering::Relaxed);
> + Ok(Self { _debugfs: debugfs })
> + }
> +}
How about this rewrite with comments added to help make things more
obvious:
impl kernel::Module for RustDebugFs {
fn init(_this: &'static ThisModule) -> Result<Self> {
// Create a debugfs directory in the root of the filesystem
// called "sample_debugfs"
let debugfs = Dir::new(c_str!("sample_debugfs"));
// Create a single file in the directory called "example" that
// allows to read from the EXAMPLE atomic variable, and make
// sure it lives past the scope of this function by calling
// .keep() on it.
debugfs
.fmt_file(c_str!("example"), &EXAMPLE, &|example, f| {
writeln!(f, "Reading atomic: {}", example.load(Ordering::Relaxed))
})
.keep();
// Change the value of EXAMPLE to be 10 so that will be the
// value read from the file. Note, the original value 8 will be
// read if the file is read right before this is called.
EXAMPLE.store(10, Ordering::Relaxed);
// Create our module object and save off the pointer to the
// debugfs directory we created. It will be automatically
// removed when the module is unloaded by virtue of the
// reference count to the structure being dropped at that point
// in time.
Ok(Self { _debugfs: debugfs })
}
}
thanks,
greg k-h
On Thu, 2025-05-01 at 09:40 +0200, Greg Kroah-Hartman wrote: > On Wed, Apr 30, 2025 at 11:31:59PM +0000, Matthew Maurer wrote: > > Provides an example of using the Rust DebugFS bindings. > > > > Signed-off-by: Matthew Maurer <mmaurer@google.com> > > Much nicer, many thanks for this! > > Some minor comments on the sample code here. As someone coming from C > with limited Rust experience, I think I do understand it, but I think it > could use a bunch of comments to make it more "obvious" what is > happening, see below. Agree 100%. I'm using this patch set to learn more about R4L. > > +static EXAMPLE: AtomicU32 = AtomicU32::new(8); > > Wait, why is this set to 8 and then you automatically set it to 10 after > you create the file? No one is ever going to see 8 as a valid value > unless they really race to read the file, right? Well, it does show that the driver still has the ability to write to EXAMPLE even after the debugfs entry is created. That demonstrates that the driver retains ownership, which is a useful test for any debugfs implementation.
© 2016 - 2026 Red Hat, Inc.