From: Dirk Behme <dirk.behme@de.bosch.com>
To: "Matthew Maurer" <mmaurer@google.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Sami Tolvanen" <samitolvanen@google.com>,
"Timur Tabi" <ttabi@nvidia.com>,
"Benno Lossin" <lossin@kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <rust-for-linux@vger.kernel.org>
Subject: Re: [PATCH v11 2/7] rust: debugfs: Add support for read-only files
Date: Tue, 9 Sep 2025 09:29:50 +0200 [thread overview]
Message-ID: <45f6f6e0-bd1e-41e7-8c8e-bb556644a873@de.bosch.com> (raw)
In-Reply-To: <20250904-debugfs-rust-v11-2-7d12a165685a@google.com>
On 04/09/2025 23:13, Matthew Maurer wrote:
> Extends the `debugfs` API to support creating read-only files. This
> is done via the `Dir::read_only_file` method, which takes a data object
> that implements the `Writer` trait.
>
> The file's content is generated by the `Writer` implementation, and the
> file is automatically removed when the returned `File` handle is
> dropped.
>
> Signed-off-by: Matthew Maurer <mmaurer@google.com>
> ---
> rust/kernel/debugfs.rs | 148 +++++++++++++++++++++++++++++++++++++++-
> rust/kernel/debugfs/entry.rs | 42 ++++++++++++
> rust/kernel/debugfs/file_ops.rs | 128 ++++++++++++++++++++++++++++++++++
> rust/kernel/debugfs/traits.rs | 33 +++++++++
> 4 files changed, 350 insertions(+), 1 deletion(-)
>
> diff --git a/rust/kernel/debugfs.rs b/rust/kernel/debugfs.rs
> index 65be71600b8eda83c0d313f3d205d0713e8e9510..b28665f58cd6a17e188aef5e8c539f6c7433a3b0 100644
> --- a/rust/kernel/debugfs.rs
> +++ b/rust/kernel/debugfs.rs
> @@ -8,12 +8,18 @@
> // When DebugFS is disabled, many parameters are dead. Linting for this isn't helpful.
> #![cfg_attr(not(CONFIG_DEBUG_FS), allow(unused_variables))]
>
> -#[cfg(CONFIG_DEBUG_FS)]
> use crate::prelude::*;
> use crate::str::CStr;
> #[cfg(CONFIG_DEBUG_FS)]
> use crate::sync::Arc;
> +use core::marker::PhantomPinned;
> +use core::ops::Deref;
> +
> +mod traits;
> +pub use traits::Writer;
>
> +mod file_ops;
> +use file_ops::{FileOps, ReadFile};
> #[cfg(CONFIG_DEBUG_FS)]
> mod entry;
> #[cfg(CONFIG_DEBUG_FS)]
> @@ -53,6 +59,34 @@ fn create(name: &CStr, parent: Option<&Dir>) -> Self {
> Self()
> }
>
> + /// Creates a DebugFS file which will own the data produced by the initializer provided in
> + /// `data`.
> + fn create_file<'a, T, E: 'a>(
> + &'a self,
> + name: &'a CStr,
> + data: impl PinInit<T, E> + 'a,
> + file_ops: &'static FileOps<T>,
> + ) -> impl PinInit<File<T>, E> + 'a
> + where
> + T: Sync + 'static,
> + {
> + let scope = Scope::<T>::new(data, move |data| {
> + #[cfg(CONFIG_DEBUG_FS)]
> + if let Some(parent) = &self.0 {
> + // SAFETY: Because data derives from a scope, and our entry will be dropped before
> + // the data is dropped, it is guaranteed to outlive the entry we return.
> + unsafe { Entry::dynamic_file(name, parent.clone(), data, file_ops) }
> + } else {
> + Entry::empty()
> + }
> + });
> + try_pin_init! {
> + File {
> + scope <- scope
> + } ? E
> + }
> + }
> +
> /// Create a new directory in DebugFS at the root.
> ///
> /// # Examples
> @@ -79,4 +113,116 @@ pub fn new(name: &CStr) -> Self {
> pub fn subdir(&self, name: &CStr) -> Self {
> Dir::create(name, Some(self))
> }
> +
> + /// Creates a read-only file in this directory.
> + ///
> + /// The file's contents are produced by invoking [`Writer::write`] on the value initialized by
> + /// `data`.
> + ///
> + /// # 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)?;
> + /// // "my_debugfs_dir/foo" now contains the number 200.
> + /// // The file is removed when `file` is dropped.
> + /// # Ok::<(), Error>(())
> + /// ```
> + pub fn read_only_file<'a, T, E: 'a>(
> + &'a self,
> + name: &'a CStr,
> + data: impl PinInit<T, E> + 'a,
> + ) -> impl PinInit<File<T>, E> + 'a
> + where
> + T: Writer + Send + Sync + 'static,
> + {
> + let file_ops = &<T as ReadFile<_>>::FILE_OPS;
> + self.create_file(name, data, file_ops)
> + }
> +}
> +
> +#[pin_data]
> +/// Handle to a DebugFS scope, which ensures that attached `data` will outlive the provided
> +/// [`Entry`] without moving.
> +/// Currently, this is used to back [`File`] so that its `read` and/or `write` implementations
> +/// can assume that their backing data is still alive.
> +struct Scope<T> {
> + // This order is load-bearing for drops - `_entry` must be dropped before `data`.
> + #[cfg(CONFIG_DEBUG_FS)]
> + _entry: Entry,
> + #[pin]
> + data: T,
> + // Even if `T` is `Unpin`, we still can't allow it to be moved.
> + #[pin]
> + _pin: PhantomPinned,
> +}
> +
> +#[pin_data]
> +/// Handle to a DebugFS file, owning its backing data.
> +///
> +/// When dropped, the DebugFS file will be removed and the attached data will be dropped.
> +pub struct File<T> {
> + #[pin]
> + scope: Scope<T>,
> +}
> +
> +#[cfg(not(CONFIG_DEBUG_FS))]
> +impl<'b, T: 'b> Scope<T> {
> + fn new<E: 'b, F>(data: impl PinInit<T, E> + 'b, init: F) -> impl PinInit<Self, E> + 'b
> + where
> + F: for<'a> FnOnce(&'a T) -> Entry + 'b,
Inspired by Greg's & Danilo's discussion I tried building with
CONFIG_DEBUG_FS disabled. And get
error[E0412]: cannot find type `Entry` in this scope
--> rust/kernel/debugfs.rs:351:37
|
351 | F: for<'a> FnOnce(&'a T) -> Entry + 'b,
| ^^^^^ not found in this scope
And giving it some Entry (for my 1.81.0)
error: hidden lifetime parameters in types are deprecated
--> rust/kernel/debugfs.rs:352:37
|
352 | F: for<'a> FnOnce(&'a T) -> Entry + 'b,
| ^^^^^ expected lifetime parameter
Dirk
next prev parent reply other threads:[~2025-09-09 7:30 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-04 21:13 [PATCH v11 0/7] rust: DebugFS Bindings Matthew Maurer
2025-09-04 21:13 ` [PATCH v11 1/7] rust: debugfs: Add initial support for directories Matthew Maurer
2025-09-04 21:13 ` [PATCH v11 2/7] rust: debugfs: Add support for read-only files Matthew Maurer
2025-09-08 10:17 ` Greg Kroah-Hartman
2025-09-08 10:54 ` Danilo Krummrich
2025-09-08 10:56 ` Danilo Krummrich
2025-09-08 12:48 ` Greg Kroah-Hartman
2025-09-08 13:22 ` Danilo Krummrich
2025-09-08 13:30 ` Greg Kroah-Hartman
2025-09-08 13:34 ` Alice Ryhl
2025-09-08 13:38 ` Danilo Krummrich
2025-09-08 13:36 ` Danilo Krummrich
2025-09-08 14:16 ` Greg Kroah-Hartman
2025-09-08 14:59 ` Danilo Krummrich
2025-09-08 16:19 ` Greg Kroah-Hartman
2025-09-08 16:30 ` Danilo Krummrich
2025-09-08 16:55 ` Danilo Krummrich
2025-09-10 15:21 ` Greg Kroah-Hartman
2025-09-08 17:58 ` Danilo Krummrich
2025-09-09 7:29 ` Dirk Behme [this message]
2025-09-09 8:29 ` Danilo Krummrich
2025-09-10 15:22 ` Greg Kroah-Hartman
2025-09-10 15:23 ` Danilo Krummrich
2025-09-10 15:36 ` Greg Kroah-Hartman
2025-09-10 15:43 ` Danilo Krummrich
2025-09-10 17:10 ` Danilo Krummrich
2025-09-04 21:13 ` [PATCH v11 3/7] rust: debugfs: Add support for writable files Matthew Maurer
2025-09-04 21:13 ` [PATCH v11 4/7] rust: debugfs: Add support for callback-based files Matthew Maurer
2025-09-04 21:13 ` [PATCH v11 5/7] samples: rust: Add debugfs sample driver Matthew Maurer
2025-09-05 9:00 ` Danilo Krummrich
2025-09-06 3:19 ` Matthew Maurer
2025-09-07 23:25 ` Danilo Krummrich
2025-09-08 13:08 ` Greg Kroah-Hartman
2025-09-08 13:30 ` Danilo Krummrich
2025-09-04 21:13 ` [PATCH v11 6/7] rust: debugfs: Add support for scoped directories Matthew Maurer
2025-09-04 21:13 ` [PATCH v11 7/7] samples: rust: Add scoped debugfs sample driver Matthew Maurer
2025-09-08 13:04 ` Greg Kroah-Hartman
2025-09-08 7:01 ` [PATCH v11 0/7] rust: DebugFS Bindings Dirk Behme
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45f6f6e0-bd1e-41e7-8c8e-bb556644a873@de.bosch.com \
--to=dirk.behme@de.bosch.com \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=mmaurer@google.com \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=samitolvanen@google.com \
--cc=tmgross@umich.edu \
--cc=ttabi@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®