rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/8] Binary Large Objects for Rust DebugFS
@ 2025-10-20 22:26 Danilo Krummrich
  2025-10-20 22:26 ` [PATCH v2 1/8] rust: fs: add file::Offset type alias Danilo Krummrich
                   ` (8 more replies)
  0 siblings, 9 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-20 22:26 UTC (permalink / raw)
  To: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel, Danilo Krummrich

This series adds support for exposing binary large objects via Rust debugfs.

The first two patches extend UserSliceReader and UserSliceWriter with partial
read/write helpers.

The series further introduces read_binary_file(), write_binary_file() and
read_write_binary_file() methods for the Dir and ScopedDir types.

It also introduces the BinaryWriter and BinaryReader traits, which are used to
read/write the implementing type's binary representation with the help of the
backing file operations from/to debugfs.

Additional to some more generic blanked implementations for the BinaryWriter and
BinaryReader traits it also provides implementations for common smart pointer
types.

Both samples (file-based and scoped) are updated with corresponding examples.

A branch containing the patches can be found in [1].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/dakr/linux.git/log/?h=debugfs_blobs

Changes in v2:
  - Add file::Offset type alias.
  - uaccess:
    - Saturate at buffer length on offset overflow.
    - Use file::Offset instead of usize.
  - debugfs:
    - Use file::Offset instead of usize.
    - Handle potential overflow when updating ppos.
    - Use &T::FILE_OPS directly if possible.
    - Fix safety comment in BinaryReaderMut::read_from_slice_mut().

Danilo Krummrich (8):
  rust: fs: add file::Offset type alias
  rust: uaccess: add UserSliceReader::read_slice_partial()
  rust: uaccess: add UserSliceWriter::write_slice_partial()
  rust: debugfs: support for binary large objects
  rust: debugfs: support blobs from smart pointers
  samples: rust: debugfs: add example for blobs
  rust: debugfs: support binary large objects for ScopedDir
  samples: rust: debugfs_scoped: add example for blobs

 rust/kernel/debugfs.rs              | 110 +++++++++++++++-
 rust/kernel/debugfs/file_ops.rs     | 145 ++++++++++++++++++++-
 rust/kernel/debugfs/traits.rs       | 190 +++++++++++++++++++++++++++-
 rust/kernel/fs/file.rs              |   5 +
 rust/kernel/uaccess.rs              |  49 +++++++
 samples/rust/rust_debugfs.rs        |  13 ++
 samples/rust/rust_debugfs_scoped.rs |  14 +-
 7 files changed, 515 insertions(+), 11 deletions(-)


base-commit: 340ccc973544a6e7e331729bc4944603085cafab
-- 
2.51.0


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
@ 2025-10-20 22:26 ` Danilo Krummrich
  2025-10-21 13:40   ` Alice Ryhl
                     ` (2 more replies)
  2025-10-20 22:26 ` [PATCH v2 2/8] rust: uaccess: add UserSliceReader::read_slice_partial() Danilo Krummrich
                   ` (7 subsequent siblings)
  8 siblings, 3 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-20 22:26 UTC (permalink / raw)
  To: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel, Danilo Krummrich,
	Alexander Viro, Christian Brauner, Jan Kara

Add a type alias for file offsets, i.e. bindings::loff_t. Trying to
avoid using raw bindings types, this seems to be the better alternative
compared to just using i64.

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
Al, Christian: If you are okay with the patch, kindly provide an ACK, so I can
take it through the driver-core tree.
---
 rust/kernel/fs/file.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/rust/kernel/fs/file.rs b/rust/kernel/fs/file.rs
index cf06e73a6da0..021a6800b46c 100644
--- a/rust/kernel/fs/file.rs
+++ b/rust/kernel/fs/file.rs
@@ -17,6 +17,11 @@
 };
 use core::ptr;
 
+/// Primitive type representing the offset within a [`File`].
+///
+/// Type alias for `bindings::loff_t`.
+pub type Offset = bindings::loff_t;
+
 /// Flags associated with a [`File`].
 pub mod flags {
     /// File is opened in append mode.
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 2/8] rust: uaccess: add UserSliceReader::read_slice_partial()
  2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
  2025-10-20 22:26 ` [PATCH v2 1/8] rust: fs: add file::Offset type alias Danilo Krummrich
@ 2025-10-20 22:26 ` Danilo Krummrich
  2025-10-20 22:26 ` [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial() Danilo Krummrich
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-20 22:26 UTC (permalink / raw)
  To: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel, Danilo Krummrich

The existing read_slice() method is a wrapper around copy_from_user()
and expects the user buffer to be larger than the destination buffer.

However, userspace may split up writes in multiple partial operations
providing an offset into the destination buffer and a smaller user
buffer.

In order to support this common case, provide a helper for partial
reads.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 rust/kernel/uaccess.rs | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
index a8fb4764185a..2061a7e10c65 100644
--- a/rust/kernel/uaccess.rs
+++ b/rust/kernel/uaccess.rs
@@ -9,6 +9,7 @@
     bindings,
     error::Result,
     ffi::{c_char, c_void},
+    fs::file,
     prelude::*,
     transmute::{AsBytes, FromBytes},
 };
@@ -287,6 +288,30 @@ pub fn read_slice(&mut self, out: &mut [u8]) -> Result {
         self.read_raw(out)
     }
 
+    /// Reads raw data from the user slice into a kernel buffer partially.
+    ///
+    /// This is the same as [`Self::read_slice`] but considers the given `offset` into `out` and
+    /// truncates the read to the boundaries of `self` and `out`.
+    ///
+    /// On success, returns the number of bytes read.
+    pub fn read_slice_partial(&mut self, out: &mut [u8], offset: file::Offset) -> Result<usize> {
+        if offset < 0 {
+            return Err(EINVAL);
+        }
+
+        let Ok(offset) = usize::try_from(offset) else {
+            return Ok(0);
+        };
+
+        let end = offset
+            .checked_add(self.len())
+            .unwrap_or(out.len())
+            .min(out.len());
+
+        out.get_mut(offset..end)
+            .map_or(Ok(0), |dst| self.read_slice(dst).map(|()| dst.len()))
+    }
+
     /// Reads a value of the specified type.
     ///
     /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial()
  2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
  2025-10-20 22:26 ` [PATCH v2 1/8] rust: fs: add file::Offset type alias Danilo Krummrich
  2025-10-20 22:26 ` [PATCH v2 2/8] rust: uaccess: add UserSliceReader::read_slice_partial() Danilo Krummrich
@ 2025-10-20 22:26 ` Danilo Krummrich
  2025-10-21 14:00   ` Alice Ryhl
  2025-10-20 22:26 ` [PATCH v2 4/8] rust: debugfs: support for binary large objects Danilo Krummrich
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-20 22:26 UTC (permalink / raw)
  To: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel, Danilo Krummrich

The existing write_slice() method is a wrapper around copy_to_user() and
expects the user buffer to be larger than the source buffer.

However, userspace may split up reads in multiple partial operations
providing an offset into the source buffer and a smaller user buffer.

In order to support this common case, provide a helper for partial
writes.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 rust/kernel/uaccess.rs | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
index 2061a7e10c65..40d47e94b54f 100644
--- a/rust/kernel/uaccess.rs
+++ b/rust/kernel/uaccess.rs
@@ -463,6 +463,30 @@ pub fn write_slice(&mut self, data: &[u8]) -> Result {
         Ok(())
     }
 
+    /// Writes raw data to this user pointer from a kernel buffer partially.
+    ///
+    /// This is the same as [`Self::write_slice`] but considers the given `offset` into `data` and
+    /// truncates the write to the boundaries of `self` and `data`.
+    ///
+    /// On success, returns the number of bytes written.
+    pub fn write_slice_partial(&mut self, data: &[u8], offset: file::Offset) -> Result<usize> {
+        if offset < 0 {
+            return Err(EINVAL);
+        }
+
+        let Ok(offset) = usize::try_from(offset) else {
+            return Ok(0);
+        };
+
+        let end = offset
+            .checked_add(self.len())
+            .unwrap_or(data.len())
+            .min(data.len());
+
+        data.get(offset..end)
+            .map_or(Ok(0), |src| self.write_slice(src).map(|()| src.len()))
+    }
+
     /// Writes the provided Rust value to this userspace pointer.
     ///
     /// Fails with [`EFAULT`] if the write happens on a bad address, or if the write goes out of
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 4/8] rust: debugfs: support for binary large objects
  2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
                   ` (2 preceding siblings ...)
  2025-10-20 22:26 ` [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial() Danilo Krummrich
@ 2025-10-20 22:26 ` Danilo Krummrich
  2025-10-21 14:03   ` Alice Ryhl
  2025-10-22  5:58   ` Alexandre Courbot
  2025-10-20 22:26 ` [PATCH v2 5/8] rust: debugfs: support blobs from smart pointers Danilo Krummrich
                   ` (4 subsequent siblings)
  8 siblings, 2 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-20 22:26 UTC (permalink / raw)
  To: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel, Danilo Krummrich

Introduce support for read-only, write-only, and read-write binary files
in Rust debugfs. This adds:

- BinaryWriter and BinaryReader traits for writing to and reading from
  user slices in binary form.
- New Dir methods: read_binary_file(), write_binary_file(),
  `read_write_binary_file`.
- Corresponding FileOps implementations: BinaryReadFile,
  BinaryWriteFile, BinaryReadWriteFile.

This allows kernel modules to expose arbitrary binary data through
debugfs, with proper support for offsets and partial reads/writes.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 rust/kernel/debugfs.rs          |  66 ++++++++++++++-
 rust/kernel/debugfs/file_ops.rs | 145 +++++++++++++++++++++++++++++++-
 rust/kernel/debugfs/traits.rs   |  46 +++++++++-
 3 files changed, 250 insertions(+), 7 deletions(-)

diff --git a/rust/kernel/debugfs.rs b/rust/kernel/debugfs.rs
index 381c23b3dd83..95cd3376ecbe 100644
--- a/rust/kernel/debugfs.rs
+++ b/rust/kernel/debugfs.rs
@@ -21,12 +21,15 @@
 use core::ops::Deref;
 
 mod traits;
-pub use traits::{Reader, Writer};
+pub use traits::{BinaryReader, BinaryWriter, Reader, Writer};
 
 mod callback_adapters;
 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)]
@@ -150,6 +153,32 @@ pub fn read_only_file<'a, T, E: 'a>(
         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::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_binary_file(c_str!("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.
@@ -206,6 +235,22 @@ pub fn read_write_file<'a, T, E: 'a>(
         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 +293,23 @@ pub fn write_only_file<'a, T, E: 'a>(
         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.
diff --git a/rust/kernel/debugfs/file_ops.rs b/rust/kernel/debugfs/file_ops.rs
index 50fead17b6f3..14bbd34c4fee 100644
--- a/rust/kernel/debugfs/file_ops.rs
+++ b/rust/kernel/debugfs/file_ops.rs
@@ -1,13 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (C) 2025 Google LLC.
 
-use super::{Reader, Writer};
+use super::{BinaryReader, BinaryWriter, Reader, Writer};
 use crate::debugfs::callback_adapters::Adapter;
+use crate::fs::file;
 use crate::prelude::*;
 use crate::seq_file::SeqFile;
 use crate::seq_print;
 use crate::uaccess::UserSlice;
-use core::fmt::{Display, Formatter, Result};
+use core::fmt;
 use core::marker::PhantomData;
 
 #[cfg(CONFIG_DEBUG_FS)]
@@ -65,8 +66,8 @@ fn deref(&self) -> &Self::Target {
 
 struct WriterAdapter<T>(T);
 
-impl<'a, T: Writer> Display for WriterAdapter<&'a T> {
-    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+impl<'a, T: Writer> fmt::Display for WriterAdapter<&'a T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.0.write(f)
     }
 }
@@ -245,3 +246,139 @@ impl<T: Reader + Sync> WriteFile<T> for T {
         unsafe { FileOps::new(operations, 0o200) }
     };
 }
+
+extern "C" fn blob_read<T: BinaryWriter>(
+    file: *mut bindings::file,
+    buf: *mut c_char,
+    count: usize,
+    ppos: *mut file::Offset,
+) -> isize {
+    // SAFETY:
+    // - `file` is a valid pointer to a `struct file`.
+    // - The type invariant of `FileOps` guarantees that `private_data` points to a valid `T`.
+    let this = unsafe { &*((*file).private_data.cast::<T>()) };
+
+    // SAFETY: `ppos` is a valid `file::Offset` pointer.
+    let pos = unsafe { &mut *ppos };
+
+    let mut writer = UserSlice::new(UserPtr::from_ptr(buf.cast()), count).writer();
+
+    let ret = || -> Result<isize> {
+        let offset = *pos;
+
+        let written = this.write_to_slice(&mut writer, offset)?;
+        *pos = offset.saturating_add(file::Offset::try_from(written)?);
+
+        Ok(written.try_into()?)
+    }();
+
+    match ret {
+        Ok(n) => n,
+        Err(e) => e.to_errno() as isize,
+    }
+}
+
+pub(crate) trait BinaryReadFile<T> {
+    const FILE_OPS: FileOps<T>;
+}
+
+impl<T: BinaryWriter + Sync> BinaryReadFile<T> for T {
+    const FILE_OPS: FileOps<T> = {
+        let operations = bindings::file_operations {
+            read: Some(blob_read::<T>),
+            llseek: Some(bindings::default_llseek),
+            open: Some(bindings::simple_open),
+            // SAFETY: `file_operations` supports zeroes in all fields.
+            ..unsafe { core::mem::zeroed() }
+        };
+
+        // SAFETY:
+        // - The private data of `struct inode` does always contain a pointer to a valid `T`.
+        // - `simple_open()` stores the `struct inode`'s private data in the private data of the
+        //   corresponding `struct file`.
+        // - `blob_read()` re-creates a reference to `T` from the `struct file`'s private data.
+        // - `default_llseek()` does not access the `struct file`'s private data.
+        unsafe { FileOps::new(operations, 0o400) }
+    };
+}
+
+extern "C" fn blob_write<T: BinaryReader>(
+    file: *mut bindings::file,
+    buf: *const c_char,
+    count: usize,
+    ppos: *mut file::Offset,
+) -> isize {
+    // SAFETY:
+    // - `file` is a valid pointer to a `struct file`.
+    // - The type invariant of `FileOps` guarantees that `private_data` points to a valid `T`.
+    let this = unsafe { &*((*file).private_data.cast::<T>()) };
+
+    // SAFETY: `ppos` is a valid `file::Offset` pointer.
+    let pos = unsafe { &mut *ppos };
+
+    let mut reader = UserSlice::new(UserPtr::from_ptr(buf.cast_mut().cast()), count).reader();
+
+    let ret = || -> Result<isize> {
+        let offset = *pos;
+
+        let read = this.read_from_slice(&mut reader, offset)?;
+        *pos = offset.saturating_add(file::Offset::try_from(read)?);
+
+        Ok(read.try_into()?)
+    }();
+
+    match ret {
+        Ok(n) => n,
+        Err(e) => e.to_errno() as isize,
+    }
+}
+
+pub(crate) trait BinaryWriteFile<T> {
+    const FILE_OPS: FileOps<T>;
+}
+
+impl<T: BinaryReader + Sync> BinaryWriteFile<T> for T {
+    const FILE_OPS: FileOps<T> = {
+        let operations = bindings::file_operations {
+            write: Some(blob_write::<T>),
+            llseek: Some(bindings::default_llseek),
+            open: Some(bindings::simple_open),
+            // SAFETY: `file_operations` supports zeroes in all fields.
+            ..unsafe { core::mem::zeroed() }
+        };
+
+        // SAFETY:
+        // - The private data of `struct inode` does always contain a pointer to a valid `T`.
+        // - `simple_open()` stores the `struct inode`'s private data in the private data of the
+        //   corresponding `struct file`.
+        // - `blob_write()` re-creates a reference to `T` from the `struct file`'s private data.
+        // - `default_llseek()` does not access the `struct file`'s private data.
+        unsafe { FileOps::new(operations, 0o200) }
+    };
+}
+
+pub(crate) trait BinaryReadWriteFile<T> {
+    const FILE_OPS: FileOps<T>;
+}
+
+impl<T: BinaryWriter + BinaryReader + Sync> BinaryReadWriteFile<T> for T {
+    const FILE_OPS: FileOps<T> = {
+        let operations = bindings::file_operations {
+            read: Some(blob_read::<T>),
+            write: Some(blob_write::<T>),
+            llseek: Some(bindings::default_llseek),
+            open: Some(bindings::simple_open),
+            // SAFETY: `file_operations` supports zeroes in all fields.
+            ..unsafe { core::mem::zeroed() }
+        };
+
+        // SAFETY:
+        // - The private data of `struct inode` does always contain a pointer to a valid `T`.
+        // - `simple_open()` stores the `struct inode`'s private data in the private data of the
+        //   corresponding `struct file`.
+        // - `blob_read()` re-creates a reference to `T` from the `struct file`'s private data.
+        // - `blob_write()` re-creates a reference to `T` from the `struct file`'s private data.
+        // - `default_llseek()` does not access the `struct file`'s private data.
+        unsafe { FileOps::new(operations, 0o600) }
+    };
+}
diff --git a/rust/kernel/debugfs/traits.rs b/rust/kernel/debugfs/traits.rs
index ab009eb254b3..5f80ce77bf17 100644
--- a/rust/kernel/debugfs/traits.rs
+++ b/rust/kernel/debugfs/traits.rs
@@ -3,9 +3,11 @@
 
 //! Traits for rendering or updating values exported to DebugFS.
 
+use crate::fs::file;
 use crate::prelude::*;
 use crate::sync::Mutex;
-use crate::uaccess::UserSliceReader;
+use crate::transmute::{AsBytes, FromBytes};
+use crate::uaccess::{UserSliceReader, UserSliceWriter};
 use core::fmt::{self, Debug, Formatter};
 use core::str::FromStr;
 use core::sync::atomic::{
@@ -39,6 +41,30 @@ fn write(&self, f: &mut Formatter<'_>) -> fmt::Result {
     }
 }
 
+/// Trait for types that can be written out as binary.
+pub trait BinaryWriter {
+    /// Writes the binary form of `self` into `writer`.
+    ///
+    /// `offset` is the requested offset into the binary representation of `self`.
+    ///
+    /// On success, returns the number of bytes written in to `writer`.
+    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize>;
+}
+
+impl<T: AsBytes> BinaryWriter for T {
+    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
+        writer.write_slice_partial(self.as_bytes(), offset)
+    }
+}
+
+impl<T: BinaryWriter> BinaryWriter for Mutex<T> {
+    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
+        let guard = self.lock();
+
+        guard.write_to_slice(writer, offset)
+    }
+}
+
 /// A trait for types that can be updated from a user slice.
 ///
 /// This works similarly to `FromStr`, but operates on a `UserSliceReader` rather than a &str.
@@ -66,6 +92,24 @@ fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
     }
 }
 
+/// Trait for types that can be constructed from a binary representation.
+pub trait BinaryReader {
+    /// Reads the binary form of `self` from `reader`.
+    ///
+    /// `offset` is the requested offset into the binary representation of `self`.
+    ///
+    /// On success, returns the number of bytes read from `reader`.
+    fn read_from_slice(&self, reader: &mut UserSliceReader, offset: file::Offset) -> Result<usize>;
+}
+
+impl<T: AsBytes + FromBytes> BinaryReader for Mutex<T> {
+    fn read_from_slice(&self, reader: &mut UserSliceReader, offset: file::Offset) -> Result<usize> {
+        let mut this = self.lock();
+
+        reader.read_slice_partial(this.as_bytes_mut(), offset)
+    }
+}
+
 macro_rules! impl_reader_for_atomic {
     ($(($atomic_type:ty, $int_type:ty)),*) => {
         $(
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 5/8] rust: debugfs: support blobs from smart pointers
  2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
                   ` (3 preceding siblings ...)
  2025-10-20 22:26 ` [PATCH v2 4/8] rust: debugfs: support for binary large objects Danilo Krummrich
@ 2025-10-20 22:26 ` Danilo Krummrich
  2025-10-22  5:57   ` Alexandre Courbot
  2025-10-20 22:26 ` [PATCH v2 6/8] samples: rust: debugfs: add example for blobs Danilo Krummrich
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-20 22:26 UTC (permalink / raw)
  To: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel, Danilo Krummrich

Extend Rust debugfs binary support to allow exposing data stored in
common smart pointers and heap-allocated collections.

- Implement BinaryWriter for Box<T>, Pin<Box<T>>, Arc<T>, and Vec<T>.
- Introduce BinaryReaderMut for mutable binary access with outer locks.
- Implement BinaryReaderMut for Box<T>, Vec<T>, and base types.
- Update BinaryReader to delegate to BinaryReaderMut for Mutex<T>,
  Box<T>, Pin<Box<T>> and Arc<T>.

This enables debugfs files to directly expose or update data stored
inside heap-allocated, reference-counted, or lock-protected containers
without manual dereferencing or locking.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 rust/kernel/debugfs.rs        |   2 +-
 rust/kernel/debugfs/traits.rs | 148 +++++++++++++++++++++++++++++++++-
 2 files changed, 147 insertions(+), 3 deletions(-)

diff --git a/rust/kernel/debugfs.rs b/rust/kernel/debugfs.rs
index 95cd3376ecbe..d2bc7550d81e 100644
--- a/rust/kernel/debugfs.rs
+++ b/rust/kernel/debugfs.rs
@@ -21,7 +21,7 @@
 use core::ops::Deref;
 
 mod traits;
-pub use traits::{BinaryReader, BinaryWriter, Reader, Writer};
+pub use traits::{BinaryReader, BinaryReaderMut, BinaryWriter, Reader, Writer};
 
 mod callback_adapters;
 use callback_adapters::{FormatAdapter, NoWriter, WritableAdapter};
diff --git a/rust/kernel/debugfs/traits.rs b/rust/kernel/debugfs/traits.rs
index 5f80ce77bf17..c1adf4d9f270 100644
--- a/rust/kernel/debugfs/traits.rs
+++ b/rust/kernel/debugfs/traits.rs
@@ -3,12 +3,15 @@
 
 //! Traits for rendering or updating values exported to DebugFS.
 
+use crate::alloc::Allocator;
 use crate::fs::file;
 use crate::prelude::*;
+use crate::sync::Arc;
 use crate::sync::Mutex;
 use crate::transmute::{AsBytes, FromBytes};
 use crate::uaccess::{UserSliceReader, UserSliceWriter};
 use core::fmt::{self, Debug, Formatter};
+use core::ops::{Deref, DerefMut};
 use core::str::FromStr;
 use core::sync::atomic::{
     AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU64,
@@ -51,12 +54,14 @@ pub trait BinaryWriter {
     fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize>;
 }
 
+// Base implementation for any `T: AsBytes`.
 impl<T: AsBytes> BinaryWriter for T {
     fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
         writer.write_slice_partial(self.as_bytes(), offset)
     }
 }
 
+// Delegate for `Mutex<T>`: Support a `T` with an outer mutex.
 impl<T: BinaryWriter> BinaryWriter for Mutex<T> {
     fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
         let guard = self.lock();
@@ -65,6 +70,56 @@ fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) ->
     }
 }
 
+// Delegate for `Box<T, A>`: Support a `Box<T, A>` with no lock or an inner lock.
+impl<T, A> BinaryWriter for Box<T, A>
+where
+    T: BinaryWriter,
+    A: Allocator,
+{
+    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
+        self.deref().write_to_slice(writer, offset)
+    }
+}
+
+// Delegate for `Pin<Box<T, A>>`: Support a `Pin<Box<T, A>>` with no lock or an inner lock.
+impl<T, A> BinaryWriter for Pin<Box<T, A>>
+where
+    T: BinaryWriter,
+    A: Allocator,
+{
+    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
+        self.deref().write_to_slice(writer, offset)
+    }
+}
+
+// Delegate for `Arc<T>`: Support a `Arc<T>` with no lock or an inner lock.
+impl<T> BinaryWriter for Arc<T>
+where
+    T: BinaryWriter,
+{
+    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
+        self.deref().write_to_slice(writer, offset)
+    }
+}
+
+// Delegate for `Vec<T, A>`.
+impl<T, A> BinaryWriter for Vec<T, A>
+where
+    T: AsBytes,
+    A: Allocator,
+{
+    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
+        let slice = self.as_slice();
+
+        // SAFETY: `T: AsBytes` allows us to treat `&[T]` as `&[u8]`.
+        let buffer = unsafe {
+            core::slice::from_raw_parts(slice.as_ptr().cast(), core::mem::size_of_val(slice))
+        };
+
+        writer.write_slice_partial(buffer, offset)
+    }
+}
+
 /// A trait for types that can be updated from a user slice.
 ///
 /// This works similarly to `FromStr`, but operates on a `UserSliceReader` rather than a &str.
@@ -93,6 +148,73 @@ fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
 }
 
 /// Trait for types that can be constructed from a binary representation.
+///
+/// See also [`BinaryReader`] for interior mutability.
+pub trait BinaryReaderMut {
+    /// Reads the binary form of `self` from `reader`.
+    ///
+    /// Same as [`BinaryReader::read_from_slice`], but takes a mutable reference.
+    ///
+    /// `offset` is the requested offset into the binary representation of `self`.
+    ///
+    /// On success, returns the number of bytes read from `reader`.
+    fn read_from_slice_mut(
+        &mut self,
+        reader: &mut UserSliceReader,
+        offset: file::Offset,
+    ) -> Result<usize>;
+}
+
+// Base implementation for any `T: AsBytes + FromBytes`.
+impl<T: AsBytes + FromBytes> BinaryReaderMut for T {
+    fn read_from_slice_mut(
+        &mut self,
+        reader: &mut UserSliceReader,
+        offset: file::Offset,
+    ) -> Result<usize> {
+        reader.read_slice_partial(self.as_bytes_mut(), offset)
+    }
+}
+
+// Delegate for `Box<T, A>`: Support a `Box<T, A>` with an outer lock.
+impl<T: ?Sized + BinaryReaderMut, A: Allocator> BinaryReaderMut for Box<T, A> {
+    fn read_from_slice_mut(
+        &mut self,
+        reader: &mut UserSliceReader,
+        offset: file::Offset,
+    ) -> Result<usize> {
+        self.deref_mut().read_from_slice_mut(reader, offset)
+    }
+}
+
+// Delegate for `Vec<T, A>`: Support a `Vec<T, A>` with an outer lock.
+impl<T, A> BinaryReaderMut for Vec<T, A>
+where
+    T: AsBytes + FromBytes,
+    A: Allocator,
+{
+    fn read_from_slice_mut(
+        &mut self,
+        reader: &mut UserSliceReader,
+        offset: file::Offset,
+    ) -> Result<usize> {
+        let slice = self.as_mut_slice();
+
+        // SAFETY: `T: AsBytes + FromBytes` allows us to treat `&mut [T]` as `&mut [u8]`.
+        let buffer = unsafe {
+            core::slice::from_raw_parts_mut(
+                slice.as_mut_ptr().cast(),
+                core::mem::size_of_val(slice),
+            )
+        };
+
+        reader.read_slice_partial(buffer, offset)
+    }
+}
+
+/// Trait for types that can be constructed from a binary representation.
+///
+/// See also [`BinaryReaderMut`] for the mutable version.
 pub trait BinaryReader {
     /// Reads the binary form of `self` from `reader`.
     ///
@@ -102,11 +224,33 @@ pub trait BinaryReader {
     fn read_from_slice(&self, reader: &mut UserSliceReader, offset: file::Offset) -> Result<usize>;
 }
 
-impl<T: AsBytes + FromBytes> BinaryReader for Mutex<T> {
+// Delegate for `Mutex<T>`: Support a `T` with an outer `Mutex`.
+impl<T: BinaryReaderMut> BinaryReader for Mutex<T> {
     fn read_from_slice(&self, reader: &mut UserSliceReader, offset: file::Offset) -> Result<usize> {
         let mut this = self.lock();
 
-        reader.read_slice_partial(this.as_bytes_mut(), offset)
+        this.read_from_slice_mut(reader, offset)
+    }
+}
+
+// Delegate for `Box<T, A>`: Support a `Box<T, A>` with an inner lock.
+impl<T: ?Sized + BinaryReader, A: Allocator> BinaryReader for Box<T, A> {
+    fn read_from_slice(&self, reader: &mut UserSliceReader, offset: file::Offset) -> Result<usize> {
+        self.deref().read_from_slice(reader, offset)
+    }
+}
+
+// Delegate for `Pin<Box<T, A>>`: Support a `Pin<Box<T, A>>` with an inner lock.
+impl<T: ?Sized + BinaryReader, A: Allocator> BinaryReader for Pin<Box<T, A>> {
+    fn read_from_slice(&self, reader: &mut UserSliceReader, offset: file::Offset) -> Result<usize> {
+        self.deref().read_from_slice(reader, offset)
+    }
+}
+
+// Delegate for `Arc<T>`: Support an `Arc<T>` with an inner lock.
+impl<T: ?Sized + BinaryReader> BinaryReader for Arc<T> {
+    fn read_from_slice(&self, reader: &mut UserSliceReader, offset: file::Offset) -> Result<usize> {
+        self.deref().read_from_slice(reader, offset)
     }
 }
 
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 6/8] samples: rust: debugfs: add example for blobs
  2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
                   ` (4 preceding siblings ...)
  2025-10-20 22:26 ` [PATCH v2 5/8] rust: debugfs: support blobs from smart pointers Danilo Krummrich
@ 2025-10-20 22:26 ` Danilo Krummrich
  2025-10-20 22:26 ` [PATCH v2 7/8] rust: debugfs: support binary large objects for ScopedDir Danilo Krummrich
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-20 22:26 UTC (permalink / raw)
  To: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel, Danilo Krummrich

Extend the Rust debugfs sample to demonstrate usage of binary file
support. The example now shows how to expose both fixed-size arrays
and dynamically sized vectors as binary blobs in debugfs.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 samples/rust/rust_debugfs.rs | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/samples/rust/rust_debugfs.rs b/samples/rust/rust_debugfs.rs
index 82b61a15a34b..75ceb95276fa 100644
--- a/samples/rust/rust_debugfs.rs
+++ b/samples/rust/rust_debugfs.rs
@@ -38,6 +38,7 @@
 use kernel::debugfs::{Dir, File};
 use kernel::new_mutex;
 use kernel::prelude::*;
+use kernel::sizes::*;
 use kernel::sync::Mutex;
 
 use kernel::{acpi, device::Core, of, platform, str::CString, types::ARef};
@@ -62,6 +63,10 @@ struct RustDebugFs {
     counter: File<AtomicUsize>,
     #[pin]
     inner: File<Mutex<Inner>>,
+    #[pin]
+    array_blob: File<Mutex<[u8; 4]>>,
+    #[pin]
+    vector_blob: File<Mutex<KVec<u8>>>,
 }
 
 #[derive(Debug)]
@@ -143,6 +148,14 @@ fn new(pdev: &platform::Device<Core>) -> impl PinInit<Self, Error> + '_ {
                 ),
                 counter <- Self::build_counter(&debugfs),
                 inner <- Self::build_inner(&debugfs),
+                array_blob <- debugfs.read_write_binary_file(
+                    c_str!("array_blob"),
+                    new_mutex!([0x62, 0x6c, 0x6f, 0x62]),
+                ),
+                vector_blob <- debugfs.read_write_binary_file(
+                    c_str!("vector_blob"),
+                    new_mutex!(kernel::kvec!(0x42; SZ_4K)?),
+                ),
                 _debugfs: debugfs,
                 pdev: pdev.into(),
             }
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 7/8] rust: debugfs: support binary large objects for ScopedDir
  2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
                   ` (5 preceding siblings ...)
  2025-10-20 22:26 ` [PATCH v2 6/8] samples: rust: debugfs: add example for blobs Danilo Krummrich
@ 2025-10-20 22:26 ` Danilo Krummrich
  2025-10-20 22:26 ` [PATCH v2 8/8] samples: rust: debugfs_scoped: add example for blobs Danilo Krummrich
  2025-10-21  7:09 ` [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Greg KH
  8 siblings, 0 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-20 22:26 UTC (permalink / raw)
  To: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel, Danilo Krummrich

Add support for creating binary debugfs files via ScopedDir. This
mirrors the existing functionality for Dir, but without producing an
owning handle -- files are automatically removed when the associated
Scope is dropped.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 rust/kernel/debugfs.rs | 44 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/rust/kernel/debugfs.rs b/rust/kernel/debugfs.rs
index d2bc7550d81e..e8139d2e5730 100644
--- a/rust/kernel/debugfs.rs
+++ b/rust/kernel/debugfs.rs
@@ -530,6 +530,20 @@ pub fn read_only_file<T: Writer + Send + Sync + 'static>(&self, name: &CStr, dat
         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`.
@@ -567,6 +581,22 @@ pub fn read_write_file<T: Writer + Reader + Send + Sync + 'static>(
         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`.
@@ -606,6 +636,20 @@ pub fn write_only_file<T: Reader + Send + Sync + 'static>(&self, name: &CStr, da
         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`.
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 8/8] samples: rust: debugfs_scoped: add example for blobs
  2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
                   ` (6 preceding siblings ...)
  2025-10-20 22:26 ` [PATCH v2 7/8] rust: debugfs: support binary large objects for ScopedDir Danilo Krummrich
@ 2025-10-20 22:26 ` Danilo Krummrich
  2025-10-21  7:09 ` [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Greg KH
  8 siblings, 0 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-20 22:26 UTC (permalink / raw)
  To: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel, Danilo Krummrich

Extend the rust_debugfs_scoped sample to demonstrate how to export a
large binary object through a ScopedDir.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 samples/rust/rust_debugfs_scoped.rs | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/samples/rust/rust_debugfs_scoped.rs b/samples/rust/rust_debugfs_scoped.rs
index b0c4e76b123e..c80312cf168d 100644
--- a/samples/rust/rust_debugfs_scoped.rs
+++ b/samples/rust/rust_debugfs_scoped.rs
@@ -9,6 +9,7 @@
 use core::sync::atomic::AtomicUsize;
 use kernel::debugfs::{Dir, Scope};
 use kernel::prelude::*;
+use kernel::sizes::*;
 use kernel::sync::Mutex;
 use kernel::{c_str, new_mutex, str::CString};
 
@@ -66,18 +67,22 @@ fn create_file_write(
             GFP_KERNEL,
         )?;
     }
+    let blob = KBox::pin_init(new_mutex!([0x42; SZ_4K]), GFP_KERNEL)?;
 
     let scope = KBox::pin_init(
-        mod_data
-            .device_dir
-            .scope(DeviceData { name, nums }, &file_name, |dev_data, dir| {
+        mod_data.device_dir.scope(
+            DeviceData { name, nums, blob },
+            &file_name,
+            |dev_data, dir| {
                 for (idx, val) in dev_data.nums.iter().enumerate() {
                     let Ok(name) = CString::try_from_fmt(fmt!("{idx}")) else {
                         return;
                     };
                     dir.read_write_file(&name, val);
                 }
-            }),
+                dir.read_write_binary_file(c_str!("blob"), &dev_data.blob);
+            },
+        ),
         GFP_KERNEL,
     )?;
     (*mod_data.devices.lock()).push(scope, GFP_KERNEL)?;
@@ -110,6 +115,7 @@ fn init(device_dir: Dir) -> impl PinInit<Self> {
 struct DeviceData {
     name: CString,
     nums: KVec<AtomicUsize>,
+    blob: Pin<KBox<Mutex<[u8; SZ_4K]>>>,
 }
 
 fn init_control(base_dir: &Dir, dyn_dirs: Dir) -> impl PinInit<Scope<ModuleData>> + '_ {
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 0/8] Binary Large Objects for Rust DebugFS
  2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
                   ` (7 preceding siblings ...)
  2025-10-20 22:26 ` [PATCH v2 8/8] samples: rust: debugfs_scoped: add example for blobs Danilo Krummrich
@ 2025-10-21  7:09 ` Greg KH
  2025-10-21 21:26   ` Matthew Maurer
  8 siblings, 1 reply; 31+ messages in thread
From: Greg KH @ 2025-10-21  7:09 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, lossin,
	a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel

On Tue, Oct 21, 2025 at 12:26:12AM +0200, Danilo Krummrich wrote:
> This series adds support for exposing binary large objects via Rust debugfs.
> 
> The first two patches extend UserSliceReader and UserSliceWriter with partial
> read/write helpers.
> 
> The series further introduces read_binary_file(), write_binary_file() and
> read_write_binary_file() methods for the Dir and ScopedDir types.
> 
> It also introduces the BinaryWriter and BinaryReader traits, which are used to
> read/write the implementing type's binary representation with the help of the
> backing file operations from/to debugfs.
> 
> Additional to some more generic blanked implementations for the BinaryWriter and
> BinaryReader traits it also provides implementations for common smart pointer
> types.
> 
> Both samples (file-based and scoped) are updated with corresponding examples.
> 
> A branch containing the patches can be found in [1].
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/dakr/linux.git/log/?h=debugfs_blobs

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-20 22:26 ` [PATCH v2 1/8] rust: fs: add file::Offset type alias Danilo Krummrich
@ 2025-10-21 13:40   ` Alice Ryhl
  2025-10-21 15:08   ` Miguel Ojeda
  2025-10-29 12:49   ` Christian Brauner
  2 siblings, 0 replies; 31+ messages in thread
From: Alice Ryhl @ 2025-10-21 13:40 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Christian Brauner,
	Jan Kara

On Tue, Oct 21, 2025 at 12:26:13AM +0200, Danilo Krummrich wrote:
> Add a type alias for file offsets, i.e. bindings::loff_t. Trying to
> avoid using raw bindings types, this seems to be the better alternative
> compared to just using i64.
> 
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>

Please consider also changing the instances of i64 in iov.rs.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial()
  2025-10-20 22:26 ` [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial() Danilo Krummrich
@ 2025-10-21 14:00   ` Alice Ryhl
  2025-10-21 14:14     ` Danilo Krummrich
  0 siblings, 1 reply; 31+ messages in thread
From: Alice Ryhl @ 2025-10-21 14:00 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel

On Tue, Oct 21, 2025 at 12:26:15AM +0200, Danilo Krummrich wrote:
> The existing write_slice() method is a wrapper around copy_to_user() and
> expects the user buffer to be larger than the source buffer.
> 
> However, userspace may split up reads in multiple partial operations
> providing an offset into the source buffer and a smaller user buffer.
> 
> In order to support this common case, provide a helper for partial
> writes.
> 
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
>  rust/kernel/uaccess.rs | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
> index 2061a7e10c65..40d47e94b54f 100644
> --- a/rust/kernel/uaccess.rs
> +++ b/rust/kernel/uaccess.rs
> @@ -463,6 +463,30 @@ pub fn write_slice(&mut self, data: &[u8]) -> Result {
>          Ok(())
>      }
>  
> +    /// Writes raw data to this user pointer from a kernel buffer partially.
> +    ///
> +    /// This is the same as [`Self::write_slice`] but considers the given `offset` into `data` and
> +    /// truncates the write to the boundaries of `self` and `data`.
> +    ///
> +    /// On success, returns the number of bytes written.
> +    pub fn write_slice_partial(&mut self, data: &[u8], offset: file::Offset) -> Result<usize> {

I think for the current function signature, it's kind of weird to take a
file::Offset parameter

On one hand, it is described like a generic function for writing a
partial slice, and if that's what it is, then I would argue it should
take usize because it's an offset into the slice.

On another hand, I think what you're actually trying to do is implement
the simple_[read_from|write_to]_buffer utilities for user slices, but
it's only a "partial" version of those utilities. The full utility takes
a `&mut loff_t` so that it can also perform the required modification to
the offset.

Alice

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 4/8] rust: debugfs: support for binary large objects
  2025-10-20 22:26 ` [PATCH v2 4/8] rust: debugfs: support for binary large objects Danilo Krummrich
@ 2025-10-21 14:03   ` Alice Ryhl
  2025-10-22  5:58   ` Alexandre Courbot
  1 sibling, 0 replies; 31+ messages in thread
From: Alice Ryhl @ 2025-10-21 14:03 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel

On Tue, Oct 21, 2025 at 12:26:16AM +0200, Danilo Krummrich wrote:
> Introduce support for read-only, write-only, and read-write binary files
> in Rust debugfs. This adds:
> 
> - BinaryWriter and BinaryReader traits for writing to and reading from
>   user slices in binary form.
> - New Dir methods: read_binary_file(), write_binary_file(),
>   `read_write_binary_file`.
> - Corresponding FileOps implementations: BinaryReadFile,
>   BinaryWriteFile, BinaryReadWriteFile.
> 
> This allows kernel modules to expose arbitrary binary data through
> debugfs, with proper support for offsets and partial reads/writes.
> 
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>

> +/// Trait for types that can be constructed from a binary representation.
> +pub trait BinaryReader {
> +    /// Reads the binary form of `self` from `reader`.
> +    ///
> +    /// `offset` is the requested offset into the binary representation of `self`.
> +    ///
> +    /// On success, returns the number of bytes read from `reader`.
> +    fn read_from_slice(&self, reader: &mut UserSliceReader, offset: file::Offset) -> Result<usize>;

Maybe this should just take a `&mut Offset` to fit what I suggested
under the uaccess slice patch?

Alice

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial()
  2025-10-21 14:00   ` Alice Ryhl
@ 2025-10-21 14:14     ` Danilo Krummrich
  2025-10-21 14:18       ` Alice Ryhl
  0 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-21 14:14 UTC (permalink / raw)
  To: Alice Ryhl
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel

On Tue Oct 21, 2025 at 4:00 PM CEST, Alice Ryhl wrote:
> On Tue, Oct 21, 2025 at 12:26:15AM +0200, Danilo Krummrich wrote:
>> The existing write_slice() method is a wrapper around copy_to_user() and
>> expects the user buffer to be larger than the source buffer.
>> 
>> However, userspace may split up reads in multiple partial operations
>> providing an offset into the source buffer and a smaller user buffer.
>> 
>> In order to support this common case, provide a helper for partial
>> writes.
>> 
>> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
>>  rust/kernel/uaccess.rs | 24 ++++++++++++++++++++++++
>>  1 file changed, 24 insertions(+)
>> 
>> diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
>> index 2061a7e10c65..40d47e94b54f 100644
>> --- a/rust/kernel/uaccess.rs
>> +++ b/rust/kernel/uaccess.rs
>> @@ -463,6 +463,30 @@ pub fn write_slice(&mut self, data: &[u8]) -> Result {
>>          Ok(())
>>      }
>>  
>> +    /// Writes raw data to this user pointer from a kernel buffer partially.
>> +    ///
>> +    /// This is the same as [`Self::write_slice`] but considers the given `offset` into `data` and
>> +    /// truncates the write to the boundaries of `self` and `data`.
>> +    ///
>> +    /// On success, returns the number of bytes written.
>> +    pub fn write_slice_partial(&mut self, data: &[u8], offset: file::Offset) -> Result<usize> {
>
> I think for the current function signature, it's kind of weird to take a
> file::Offset parameter
>
> On one hand, it is described like a generic function for writing a
> partial slice, and if that's what it is, then I would argue it should
> take usize because it's an offset into the slice.
>
> On another hand, I think what you're actually trying to do is implement
> the simple_[read_from|write_to]_buffer utilities for user slices, but
> it's only a "partial" version of those utilities. The full utility takes
> a `&mut loff_t` so that it can also perform the required modification to
> the offset.

Originally, it was intended to be the latter. And, in fact, earlier code (that
did not git the mailing list) had a &mut file::Offset argument (was &mut i64
back then).

However, for the version I sent to the list I chose the former because I
considered it to be more flexible.

Now, in v2, it's indeed a bit mixed up. I think what we should do is to have
both

	fn write_slice_partial(&mut self, data: &[u8], offset: usize) -> Result<usize>

and

	fn write_slice_???(&mut self, data: &[u8], offset: &mut file::Offset) -> Result<usize>

which can forward to write_slice_partial() and update the buffer.

Any name suggestions?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial()
  2025-10-21 14:14     ` Danilo Krummrich
@ 2025-10-21 14:18       ` Alice Ryhl
  2025-10-21 14:34         ` Danilo Krummrich
  0 siblings, 1 reply; 31+ messages in thread
From: Alice Ryhl @ 2025-10-21 14:18 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel

On Tue, Oct 21, 2025 at 04:14:22PM +0200, Danilo Krummrich wrote:
> On Tue Oct 21, 2025 at 4:00 PM CEST, Alice Ryhl wrote:
> > On Tue, Oct 21, 2025 at 12:26:15AM +0200, Danilo Krummrich wrote:
> >> The existing write_slice() method is a wrapper around copy_to_user() and
> >> expects the user buffer to be larger than the source buffer.
> >> 
> >> However, userspace may split up reads in multiple partial operations
> >> providing an offset into the source buffer and a smaller user buffer.
> >> 
> >> In order to support this common case, provide a helper for partial
> >> writes.
> >> 
> >> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> >>  rust/kernel/uaccess.rs | 24 ++++++++++++++++++++++++
> >>  1 file changed, 24 insertions(+)
> >> 
> >> diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
> >> index 2061a7e10c65..40d47e94b54f 100644
> >> --- a/rust/kernel/uaccess.rs
> >> +++ b/rust/kernel/uaccess.rs
> >> @@ -463,6 +463,30 @@ pub fn write_slice(&mut self, data: &[u8]) -> Result {
> >>          Ok(())
> >>      }
> >>  
> >> +    /// Writes raw data to this user pointer from a kernel buffer partially.
> >> +    ///
> >> +    /// This is the same as [`Self::write_slice`] but considers the given `offset` into `data` and
> >> +    /// truncates the write to the boundaries of `self` and `data`.
> >> +    ///
> >> +    /// On success, returns the number of bytes written.
> >> +    pub fn write_slice_partial(&mut self, data: &[u8], offset: file::Offset) -> Result<usize> {
> >
> > I think for the current function signature, it's kind of weird to take a
> > file::Offset parameter
> >
> > On one hand, it is described like a generic function for writing a
> > partial slice, and if that's what it is, then I would argue it should
> > take usize because it's an offset into the slice.
> >
> > On another hand, I think what you're actually trying to do is implement
> > the simple_[read_from|write_to]_buffer utilities for user slices, but
> > it's only a "partial" version of those utilities. The full utility takes
> > a `&mut loff_t` so that it can also perform the required modification to
> > the offset.
> 
> Originally, it was intended to be the latter. And, in fact, earlier code (that
> did not git the mailing list) had a &mut file::Offset argument (was &mut i64
> back then).
> 
> However, for the version I sent to the list I chose the former because I
> considered it to be more flexible.
> 
> Now, in v2, it's indeed a bit mixed up. I think what we should do is to have
> both
> 
> 	fn write_slice_partial(&mut self, data: &[u8], offset: usize) -> Result<usize>
> 
> and
> 
> 	fn write_slice_???(&mut self, data: &[u8], offset: &mut file::Offset) -> Result<usize>
> 
> which can forward to write_slice_partial() and update the buffer.

SGTM.

> Any name suggestions?

I would suggest keeping the name of the equivalent C method:
simple_read_from_buffer/simple_write_to_buffer

Alice

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial()
  2025-10-21 14:18       ` Alice Ryhl
@ 2025-10-21 14:34         ` Danilo Krummrich
  2025-10-22  8:22           ` Alice Ryhl
  0 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-21 14:34 UTC (permalink / raw)
  To: Alice Ryhl
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel

On Tue Oct 21, 2025 at 4:18 PM CEST, Alice Ryhl wrote:
> On Tue, Oct 21, 2025 at 04:14:22PM +0200, Danilo Krummrich wrote:
>> On Tue Oct 21, 2025 at 4:00 PM CEST, Alice Ryhl wrote:
>> > On Tue, Oct 21, 2025 at 12:26:15AM +0200, Danilo Krummrich wrote:
>> >> The existing write_slice() method is a wrapper around copy_to_user() and
>> >> expects the user buffer to be larger than the source buffer.
>> >> 
>> >> However, userspace may split up reads in multiple partial operations
>> >> providing an offset into the source buffer and a smaller user buffer.
>> >> 
>> >> In order to support this common case, provide a helper for partial
>> >> writes.
>> >> 
>> >> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
>> >>  rust/kernel/uaccess.rs | 24 ++++++++++++++++++++++++
>> >>  1 file changed, 24 insertions(+)
>> >> 
>> >> diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
>> >> index 2061a7e10c65..40d47e94b54f 100644
>> >> --- a/rust/kernel/uaccess.rs
>> >> +++ b/rust/kernel/uaccess.rs
>> >> @@ -463,6 +463,30 @@ pub fn write_slice(&mut self, data: &[u8]) -> Result {
>> >>          Ok(())
>> >>      }
>> >>  
>> >> +    /// Writes raw data to this user pointer from a kernel buffer partially.
>> >> +    ///
>> >> +    /// This is the same as [`Self::write_slice`] but considers the given `offset` into `data` and
>> >> +    /// truncates the write to the boundaries of `self` and `data`.
>> >> +    ///
>> >> +    /// On success, returns the number of bytes written.
>> >> +    pub fn write_slice_partial(&mut self, data: &[u8], offset: file::Offset) -> Result<usize> {
>> >
>> > I think for the current function signature, it's kind of weird to take a
>> > file::Offset parameter
>> >
>> > On one hand, it is described like a generic function for writing a
>> > partial slice, and if that's what it is, then I would argue it should
>> > take usize because it's an offset into the slice.
>> >
>> > On another hand, I think what you're actually trying to do is implement
>> > the simple_[read_from|write_to]_buffer utilities for user slices, but
>> > it's only a "partial" version of those utilities. The full utility takes
>> > a `&mut loff_t` so that it can also perform the required modification to
>> > the offset.
>> 
>> Originally, it was intended to be the latter. And, in fact, earlier code (that
>> did not git the mailing list) had a &mut file::Offset argument (was &mut i64
>> back then).
>> 
>> However, for the version I sent to the list I chose the former because I
>> considered it to be more flexible.
>> 
>> Now, in v2, it's indeed a bit mixed up. I think what we should do is to have
>> both
>> 
>> 	fn write_slice_partial(&mut self, data: &[u8], offset: usize) -> Result<usize>
>> 
>> and
>> 
>> 	fn write_slice_???(&mut self, data: &[u8], offset: &mut file::Offset) -> Result<usize>
>> 
>> which can forward to write_slice_partial() and update the buffer.
>
> SGTM.
>
>> Any name suggestions?
>
> I would suggest keeping the name of the equivalent C method:
> simple_read_from_buffer/simple_write_to_buffer

Hm..that's an option, but UserSliceWriter corresponds to
simple_read_from_buffer() and UserSliceReader corresponds to
simple_write_to_buffer().

I think having UserSliceWriter::simple_read_from_buffer() while we have
UserSliceWriter::write_slice() is confusing. But swapping the semantics of
simple_read_from_buffer() and simple_write_to_buffer() is even more confusing.

So, I think using the existing names is not a great fit.

Maybe something like write_file_slice() or write_slice_file()? The former could
be read as "slice of files" which would be misleading though.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-20 22:26 ` [PATCH v2 1/8] rust: fs: add file::Offset type alias Danilo Krummrich
  2025-10-21 13:40   ` Alice Ryhl
@ 2025-10-21 15:08   ` Miguel Ojeda
  2025-10-21 15:26     ` Danilo Krummrich
  2025-10-29 12:49   ` Christian Brauner
  2 siblings, 1 reply; 31+ messages in thread
From: Miguel Ojeda @ 2025-10-21 15:08 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Christian Brauner,
	Jan Kara

On Tue, Oct 21, 2025 at 12:27 AM Danilo Krummrich <dakr@kernel.org> wrote:
>
> Add a type alias for file offsets, i.e. bindings::loff_t. Trying to
> avoid using raw bindings types, this seems to be the better alternative
> compared to just using i64.

Would a newtype be too painful?

Note: I didn't actually check if it is a sensible idea, but when I see
an alias I tend to ask myself that so it would be nice to know the
pros/cons (we could ideally mention why in the commit message in cases
like this).

Thanks!

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-21 15:08   ` Miguel Ojeda
@ 2025-10-21 15:26     ` Danilo Krummrich
  2025-10-21 16:00       ` Miguel Ojeda
  0 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-21 15:26 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Christian Brauner,
	Jan Kara

On Tue Oct 21, 2025 at 5:08 PM CEST, Miguel Ojeda wrote:
> On Tue, Oct 21, 2025 at 12:27 AM Danilo Krummrich <dakr@kernel.org> wrote:
>>
>> Add a type alias for file offsets, i.e. bindings::loff_t. Trying to
>> avoid using raw bindings types, this seems to be the better alternative
>> compared to just using i64.
>
> Would a newtype be too painful?
>
> Note: I didn't actually check if it is a sensible idea, but when I see
> an alias I tend to ask myself that so it would be nice to know the
> pros/cons (we could ideally mention why in the commit message in cases
> like this).

Yeah, I don't think there's any value making this a new type in this case. There
are no type invariants, useful methods, etc.

In fact, not even the type alias is strictly needed, as i64 would be sufficient
as well.

The main motivation for the type alias is that I think i64 is not super
intuitive for an offset value (people would rather expect usize or isize) and
it's nice to not have bindings::loff_t exposed to driver APIs.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-21 15:26     ` Danilo Krummrich
@ 2025-10-21 16:00       ` Miguel Ojeda
  2025-10-21 16:25         ` Danilo Krummrich
  0 siblings, 1 reply; 31+ messages in thread
From: Miguel Ojeda @ 2025-10-21 16:00 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Christian Brauner,
	Jan Kara

On Tue, Oct 21, 2025 at 5:26 PM Danilo Krummrich <dakr@kernel.org> wrote:
>
> Yeah, I don't think there's any value making this a new type in this case. There
> are no type invariants, useful methods, etc.
>
> In fact, not even the type alias is strictly needed, as i64 would be sufficient
> as well.

Even if there are no type invariants nor methods, newtypes are still
useful to prevent bad operations/assignments/...

In general, it would be ideal to have more newtypes (and of course
avoid primitives for everything), but they come with source code
overhead, so I was wondering here, because it is usually one chance we
have to try to go with something stronger vs. the usual C way.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-21 16:00       ` Miguel Ojeda
@ 2025-10-21 16:25         ` Danilo Krummrich
  2025-10-21 16:47           ` Miguel Ojeda
  0 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-21 16:25 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Christian Brauner,
	Jan Kara

On Tue Oct 21, 2025 at 6:00 PM CEST, Miguel Ojeda wrote:
> On Tue, Oct 21, 2025 at 5:26 PM Danilo Krummrich <dakr@kernel.org> wrote:
>>
>> Yeah, I don't think there's any value making this a new type in this case. There
>> are no type invariants, useful methods, etc.
>>
>> In fact, not even the type alias is strictly needed, as i64 would be sufficient
>> as well.
>
> Even if there are no type invariants nor methods, newtypes are still
> useful to prevent bad operations/assignments/...
>
> In general, it would be ideal to have more newtypes (and of course
> avoid primitives for everything), but they come with source code
> overhead, so I was wondering here, because it is usually one chance we
> have to try to go with something stronger vs. the usual C way.

We need arithmetic operations (e.g. checked_add()) and type conversions (e.g.
from/into usize). That'd be quite some code to write that just forwards to the
inner primitive.

So, I think as by now a new type makes sense if there is some reasonable
additional semantics to capture. Of course, if we'd have modular derive macros I
think it is reasonable and makes sense to also do it in cases like this one.

Maybe the action to take from this is to add this to the list of (good first)
issues (not sure this is actually a _good first_ issue though :).

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-21 16:25         ` Danilo Krummrich
@ 2025-10-21 16:47           ` Miguel Ojeda
  2025-10-21 17:34             ` Danilo Krummrich
  0 siblings, 1 reply; 31+ messages in thread
From: Miguel Ojeda @ 2025-10-21 16:47 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Christian Brauner,
	Jan Kara

On Tue, Oct 21, 2025 at 6:25 PM Danilo Krummrich <dakr@kernel.org> wrote:
>
> We need arithmetic operations (e.g. checked_add()) and type conversions (e.g.
> from/into usize). That'd be quite some code to write that just forwards to the
> inner primitive.

If it is just e.g. add/sub and a few from/into, then it sounds ideal
(i.e. I am worried if it wants to be used as essentially a primitive,
in which case I agree it would need to be automated to some degree).

> So, I think as by now a new type makes sense if there is some reasonable
> additional semantics to capture.

To me, part of that is restricting what can be done with the type to
prevent mistakes.

i.e. a type alias is essentially the wild west, and this kind of
type/concept is common enough that it sounds a good idea to pay the
price to provide a proper type for it.

> Maybe the action to take from this is to add this to the list of (good first)
> issues (not sure this is actually a _good first_ issue though :).

So I don't want to delay real work, and as long as we do it early
enough that we don't have many users, that sounds like a good idea to
me -- done:

    https://github.com/Rust-for-Linux/linux/issues/1198

Also took the chance to ask for a couple examples/tests.

I hope that helps.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-21 16:47           ` Miguel Ojeda
@ 2025-10-21 17:34             ` Danilo Krummrich
  2025-10-21 23:16               ` Miguel Ojeda
  0 siblings, 1 reply; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-21 17:34 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Christian Brauner,
	Jan Kara

On Tue Oct 21, 2025 at 6:47 PM CEST, Miguel Ojeda wrote:
> If it is just e.g. add/sub and a few from/into, then it sounds ideal
> (i.e. I am worried if it wants to be used as essentially a primitive,
> in which case I agree it would need to be automated to some degree).

That's what I need for this patch series, I think the operations applicable for
this type are quite some more; not that far from a primitive.

> To me, part of that is restricting what can be done with the type to
> prevent mistakes.
>
> i.e. a type alias is essentially the wild west, and this kind of
> type/concept is common enough that it sounds a good idea to pay the
> price to provide a proper type for it.

The reason why I said for this case I think it would be good to have derive
macros first is that there's a lot of things that are valid to do with an offset
value.

Of course, there's also a lot of things that don't make a lot of sense that we
could prevent (e.g. reverse_bits(), ilogX(), etc.).

I think in this case there not a lot to gain from preventing this, considering
that we don't have derive macros yet.

However, I understand where you're coming from. Even though there's not a huge
gain here, it would be good to set an example -- especially if it's something as
cental as a file offset type.

If this is what you have in mind, let me go ahead and do it right away (at least
for the things needed by this patch series), because that's a very good reason I
think.

> So I don't want to delay real work, and as long as we do it early
> enough that we don't have many users, that sounds like a good idea to
> me -- done:
>
>     https://github.com/Rust-for-Linux/linux/issues/1198
>
> Also took the chance to ask for a couple examples/tests.

Thanks a lot for creating the issue!

(I mainly also thought of adding one for a derive macro.)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 0/8] Binary Large Objects for Rust DebugFS
  2025-10-21  7:09 ` [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Greg KH
@ 2025-10-21 21:26   ` Matthew Maurer
  0 siblings, 0 replies; 31+ messages in thread
From: Matthew Maurer @ 2025-10-21 21:26 UTC (permalink / raw)
  To: Greg KH
  Cc: Danilo Krummrich, rafael, ojeda, alex.gaynor, boqun.feng, gary,
	bjorn3_gh, lossin, a.hindborg, aliceryhl, tmgross, rust-for-linux,
	linux-fsdevel, linux-kernel

On Tue, Oct 21, 2025 at 12:10 AM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Tue, Oct 21, 2025 at 12:26:12AM +0200, Danilo Krummrich wrote:
> > This series adds support for exposing binary large objects via Rust debugfs.
> >
> > The first two patches extend UserSliceReader and UserSliceWriter with partial
> > read/write helpers.
> >
> > The series further introduces read_binary_file(), write_binary_file() and
> > read_write_binary_file() methods for the Dir and ScopedDir types.
> >
> > It also introduces the BinaryWriter and BinaryReader traits, which are used to
> > read/write the implementing type's binary representation with the help of the
> > backing file operations from/to debugfs.
> >
> > Additional to some more generic blanked implementations for the BinaryWriter and
> > BinaryReader traits it also provides implementations for common smart pointer
> > types.
> >
> > Both samples (file-based and scoped) are updated with corresponding examples.
> >
> > A branch containing the patches can be found in [1].
> >
> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/dakr/linux.git/log/?h=debugfs_blobs
>
> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Reviewed-by: Matthew Maurer <mmaurer@google.com>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-21 17:34             ` Danilo Krummrich
@ 2025-10-21 23:16               ` Miguel Ojeda
  0 siblings, 0 replies; 31+ messages in thread
From: Miguel Ojeda @ 2025-10-21 23:16 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Christian Brauner,
	Jan Kara

On Tue, Oct 21, 2025 at 7:34 PM Danilo Krummrich <dakr@kernel.org> wrote:
>
> However, I understand where you're coming from. Even though there's not a huge
> gain here, it would be good to set an example -- especially if it's something as
> cental as a file offset type.
>
> If this is what you have in mind, let me go ahead and do it right away (at least
> for the things needed by this patch series), because that's a very good reason I
> think.

Yeah, exactly, it should be fairly straightforward for at least the ones here.

Up to you, i.e. we can already start (the code you showed me offline
looks good) or wait for someone to send the change (or since you
started, they can still consider more operations and expand the type
etc.).

I will send a small coding guidelines note on type aliases -- I can
reference this example when added, since it is a good example I think.
:)

Thanks!

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 5/8] rust: debugfs: support blobs from smart pointers
  2025-10-20 22:26 ` [PATCH v2 5/8] rust: debugfs: support blobs from smart pointers Danilo Krummrich
@ 2025-10-22  5:57   ` Alexandre Courbot
  2025-10-22  9:34     ` Danilo Krummrich
  0 siblings, 1 reply; 31+ messages in thread
From: Alexandre Courbot @ 2025-10-22  5:57 UTC (permalink / raw)
  To: Danilo Krummrich, gregkh, rafael, ojeda, alex.gaynor, boqun.feng,
	gary, bjorn3_gh, lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel

On Tue Oct 21, 2025 at 7:26 AM JST, Danilo Krummrich wrote:
<snip>
> @@ -51,12 +54,14 @@ pub trait BinaryWriter {
>      fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize>;
>  }
>  
> +// Base implementation for any `T: AsBytes`.
>  impl<T: AsBytes> BinaryWriter for T {
>      fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
>          writer.write_slice_partial(self.as_bytes(), offset)
>      }
>  }
>  
> +// Delegate for `Mutex<T>`: Support a `T` with an outer mutex.

I guess these two comments belong in the previous patch?

>  impl<T: BinaryWriter> BinaryWriter for Mutex<T> {
>      fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
>          let guard = self.lock();
> @@ -65,6 +70,56 @@ fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) ->
>      }
>  }
>  
> +// Delegate for `Box<T, A>`: Support a `Box<T, A>` with no lock or an inner lock.
> +impl<T, A> BinaryWriter for Box<T, A>
> +where
> +    T: BinaryWriter,
> +    A: Allocator,
> +{
> +    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
> +        self.deref().write_to_slice(writer, offset)
> +    }
> +}
> +
> +// Delegate for `Pin<Box<T, A>>`: Support a `Pin<Box<T, A>>` with no lock or an inner lock.
> +impl<T, A> BinaryWriter for Pin<Box<T, A>>
> +where
> +    T: BinaryWriter,
> +    A: Allocator,
> +{
> +    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
> +        self.deref().write_to_slice(writer, offset)
> +    }
> +}
> +
> +// Delegate for `Arc<T>`: Support a `Arc<T>` with no lock or an inner lock.
> +impl<T> BinaryWriter for Arc<T>
> +where
> +    T: BinaryWriter,
> +{
> +    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
> +        self.deref().write_to_slice(writer, offset)
> +    }
> +}

These 3 implementations are identical - can we replace some/all with
just an implementation for anything implementing `Deref<T>`?


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 4/8] rust: debugfs: support for binary large objects
  2025-10-20 22:26 ` [PATCH v2 4/8] rust: debugfs: support for binary large objects Danilo Krummrich
  2025-10-21 14:03   ` Alice Ryhl
@ 2025-10-22  5:58   ` Alexandre Courbot
  1 sibling, 0 replies; 31+ messages in thread
From: Alexandre Courbot @ 2025-10-22  5:58 UTC (permalink / raw)
  To: Danilo Krummrich, gregkh, rafael, ojeda, alex.gaynor, boqun.feng,
	gary, bjorn3_gh, lossin, a.hindborg, aliceryhl, tmgross, mmaurer
  Cc: rust-for-linux, linux-fsdevel, linux-kernel

On Tue Oct 21, 2025 at 7:26 AM JST, Danilo Krummrich wrote:
<snip>
> @@ -65,8 +66,8 @@ fn deref(&self) -> &Self::Target {
>  
>  struct WriterAdapter<T>(T);
>  
> -impl<'a, T: Writer> Display for WriterAdapter<&'a T> {
> -    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
> +impl<'a, T: Writer> fmt::Display for WriterAdapter<&'a T> {
> +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
>          self.0.write(f)
>      }
>  }
> @@ -245,3 +246,139 @@ impl<T: Reader + Sync> WriteFile<T> for T {
>          unsafe { FileOps::new(operations, 0o200) }
>      };
>  }
> +
> +extern "C" fn blob_read<T: BinaryWriter>(
> +    file: *mut bindings::file,
> +    buf: *mut c_char,
> +    count: usize,
> +    ppos: *mut file::Offset,
> +) -> isize {
> +    // SAFETY:
> +    // - `file` is a valid pointer to a `struct file`.
> +    // - The type invariant of `FileOps` guarantees that `private_data` points to a valid `T`.
> +    let this = unsafe { &*((*file).private_data.cast::<T>()) };
> +
> +    // SAFETY: `ppos` is a valid `file::Offset` pointer.
> +    let pos = unsafe { &mut *ppos };
> +
> +    let mut writer = UserSlice::new(UserPtr::from_ptr(buf.cast()), count).writer();
> +
> +    let ret = || -> Result<isize> {
> +        let offset = *pos;
> +
> +        let written = this.write_to_slice(&mut writer, offset)?;
> +        *pos = offset.saturating_add(file::Offset::try_from(written)?);
> +
> +        Ok(written.try_into()?)
> +    }();
> +
> +    match ret {
> +        Ok(n) => n,
> +        Err(e) => e.to_errno() as isize,
> +    }
> +}
> +
> +pub(crate) trait BinaryReadFile<T> {

I know this trait is crate-local, but having a short documentation for
it would be helpful for first-time readers like myself. :)


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial()
  2025-10-21 14:34         ` Danilo Krummrich
@ 2025-10-22  8:22           ` Alice Ryhl
  2025-10-22  9:06             ` Danilo Krummrich
  0 siblings, 1 reply; 31+ messages in thread
From: Alice Ryhl @ 2025-10-22  8:22 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel

On Tue, Oct 21, 2025 at 04:34:49PM +0200, Danilo Krummrich wrote:
> On Tue Oct 21, 2025 at 4:18 PM CEST, Alice Ryhl wrote:
> > On Tue, Oct 21, 2025 at 04:14:22PM +0200, Danilo Krummrich wrote:
> >> On Tue Oct 21, 2025 at 4:00 PM CEST, Alice Ryhl wrote:
> >> > On Tue, Oct 21, 2025 at 12:26:15AM +0200, Danilo Krummrich wrote:
> >> >> The existing write_slice() method is a wrapper around copy_to_user() and
> >> >> expects the user buffer to be larger than the source buffer.
> >> >> 
> >> >> However, userspace may split up reads in multiple partial operations
> >> >> providing an offset into the source buffer and a smaller user buffer.
> >> >> 
> >> >> In order to support this common case, provide a helper for partial
> >> >> writes.
> >> >> 
> >> >> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> >> >>  rust/kernel/uaccess.rs | 24 ++++++++++++++++++++++++
> >> >>  1 file changed, 24 insertions(+)
> >> >> 
> >> >> diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
> >> >> index 2061a7e10c65..40d47e94b54f 100644
> >> >> --- a/rust/kernel/uaccess.rs
> >> >> +++ b/rust/kernel/uaccess.rs
> >> >> @@ -463,6 +463,30 @@ pub fn write_slice(&mut self, data: &[u8]) -> Result {
> >> >>          Ok(())
> >> >>      }
> >> >>  
> >> >> +    /// Writes raw data to this user pointer from a kernel buffer partially.
> >> >> +    ///
> >> >> +    /// This is the same as [`Self::write_slice`] but considers the given `offset` into `data` and
> >> >> +    /// truncates the write to the boundaries of `self` and `data`.
> >> >> +    ///
> >> >> +    /// On success, returns the number of bytes written.
> >> >> +    pub fn write_slice_partial(&mut self, data: &[u8], offset: file::Offset) -> Result<usize> {
> >> >
> >> > I think for the current function signature, it's kind of weird to take a
> >> > file::Offset parameter
> >> >
> >> > On one hand, it is described like a generic function for writing a
> >> > partial slice, and if that's what it is, then I would argue it should
> >> > take usize because it's an offset into the slice.
> >> >
> >> > On another hand, I think what you're actually trying to do is implement
> >> > the simple_[read_from|write_to]_buffer utilities for user slices, but
> >> > it's only a "partial" version of those utilities. The full utility takes
> >> > a `&mut loff_t` so that it can also perform the required modification to
> >> > the offset.
> >> 
> >> Originally, it was intended to be the latter. And, in fact, earlier code (that
> >> did not git the mailing list) had a &mut file::Offset argument (was &mut i64
> >> back then).
> >> 
> >> However, for the version I sent to the list I chose the former because I
> >> considered it to be more flexible.
> >> 
> >> Now, in v2, it's indeed a bit mixed up. I think what we should do is to have
> >> both
> >> 
> >> 	fn write_slice_partial(&mut self, data: &[u8], offset: usize) -> Result<usize>
> >> 
> >> and
> >> 
> >> 	fn write_slice_???(&mut self, data: &[u8], offset: &mut file::Offset) -> Result<usize>
> >> 
> >> which can forward to write_slice_partial() and update the buffer.
> >
> > SGTM.
> >
> >> Any name suggestions?
> >
> > I would suggest keeping the name of the equivalent C method:
> > simple_read_from_buffer/simple_write_to_buffer
> 
> Hm..that's an option, but UserSliceWriter corresponds to
> simple_read_from_buffer() and UserSliceReader corresponds to
> simple_write_to_buffer().
> 
> I think having UserSliceWriter::simple_read_from_buffer() while we have
> UserSliceWriter::write_slice() is confusing. But swapping the semantics of
> simple_read_from_buffer() and simple_write_to_buffer() is even more confusing.
> 
> So, I think using the existing names is not a great fit.
> 
> Maybe something like write_file_slice() or write_slice_file()? The former could
> be read as "slice of files" which would be misleading though.

It's tricky. Perhaps if you make them standalone functions, then using
the simple_read_from_buffer naming is less confusing? Then it's just
kernel::uaccess::simple_read_from_buffer() and it takes a
UserSliceWriter.

Alice

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial()
  2025-10-22  8:22           ` Alice Ryhl
@ 2025-10-22  9:06             ` Danilo Krummrich
  0 siblings, 0 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-22  9:06 UTC (permalink / raw)
  To: Alice Ryhl
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel

On 10/22/25 10:22 AM, Alice Ryhl wrote:
> It's tricky. Perhaps if you make them standalone functions, then using
> the simple_read_from_buffer naming is less confusing? Then it's just
> kernel::uaccess::simple_read_from_buffer() and it takes a
> UserSliceWriter.

If we want to preserve the name, then that's probably the best option.

However, given that write_slice() and read_slice() represent
copy_{to,from}_user(), it also seems reasonable to give it a name that matches
the UserSlice{Writer,Reader} naming scheme. Also because the implementation
utilizes UserSlice{Writer,Reader} rather than doing the corresponding FFI call.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 5/8] rust: debugfs: support blobs from smart pointers
  2025-10-22  5:57   ` Alexandre Courbot
@ 2025-10-22  9:34     ` Danilo Krummrich
  0 siblings, 0 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-22  9:34 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel

On 10/22/25 7:57 AM, Alexandre Courbot wrote:
> On Tue Oct 21, 2025 at 7:26 AM JST, Danilo Krummrich wrote:
> <snip>
>> @@ -51,12 +54,14 @@ pub trait BinaryWriter {
>>      fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize>;
>>  }
>>  
>> +// Base implementation for any `T: AsBytes`.
>>  impl<T: AsBytes> BinaryWriter for T {
>>      fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
>>          writer.write_slice_partial(self.as_bytes(), offset)
>>      }
>>  }
>>  
>> +// Delegate for `Mutex<T>`: Support a `T` with an outer mutex.
> 
> I guess these two comments belong in the previous patch?

I added them in this patch since it is where the comments become useful, but
technically they can indeed go in the previous one.

>>  impl<T: BinaryWriter> BinaryWriter for Mutex<T> {
>>      fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
>>          let guard = self.lock();
>> @@ -65,6 +70,56 @@ fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) ->
>>      }
>>  }
>>  
>> +// Delegate for `Box<T, A>`: Support a `Box<T, A>` with no lock or an inner lock.
>> +impl<T, A> BinaryWriter for Box<T, A>
>> +where
>> +    T: BinaryWriter,
>> +    A: Allocator,
>> +{
>> +    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
>> +        self.deref().write_to_slice(writer, offset)
>> +    }
>> +}
>> +
>> +// Delegate for `Pin<Box<T, A>>`: Support a `Pin<Box<T, A>>` with no lock or an inner lock.
>> +impl<T, A> BinaryWriter for Pin<Box<T, A>>
>> +where
>> +    T: BinaryWriter,
>> +    A: Allocator,
>> +{
>> +    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
>> +        self.deref().write_to_slice(writer, offset)
>> +    }
>> +}
>> +
>> +// Delegate for `Arc<T>`: Support a `Arc<T>` with no lock or an inner lock.
>> +impl<T> BinaryWriter for Arc<T>
>> +where
>> +    T: BinaryWriter,
>> +{
>> +    fn write_to_slice(&self, writer: &mut UserSliceWriter, offset: file::Offset) -> Result<usize> {
>> +        self.deref().write_to_slice(writer, offset)
>> +    }
>> +}
> 
> These 3 implementations are identical - can we replace some/all with
> just an implementation for anything implementing `Deref<T>`?

Unfortunately, this would lead to some ambiguity for the compiler. A type could
match

	impl<T: AsBytes> BinaryWriter for T {}

and

	impl<T, D> BinaryWriter for T
	where
    	    T: Deref<Target = D>,
	    D: BinaryWriter,
	{}

at the same time.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-20 22:26 ` [PATCH v2 1/8] rust: fs: add file::Offset type alias Danilo Krummrich
  2025-10-21 13:40   ` Alice Ryhl
  2025-10-21 15:08   ` Miguel Ojeda
@ 2025-10-29 12:49   ` Christian Brauner
  2025-10-29 15:26     ` Danilo Krummrich
  2 siblings, 1 reply; 31+ messages in thread
From: Christian Brauner @ 2025-10-29 12:49 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Jan Kara

On Tue, Oct 21, 2025 at 12:26:13AM +0200, Danilo Krummrich wrote:
> Add a type alias for file offsets, i.e. bindings::loff_t. Trying to
> avoid using raw bindings types, this seems to be the better alternative
> compared to just using i64.
> 
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> ---
> Al, Christian: If you are okay with the patch, kindly provide an ACK, so I can
> take it through the driver-core tree.
> ---

Reviewed-by: Christian Brauner <brauner@kernel.org>

>  rust/kernel/fs/file.rs | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/rust/kernel/fs/file.rs b/rust/kernel/fs/file.rs
> index cf06e73a6da0..021a6800b46c 100644
> --- a/rust/kernel/fs/file.rs
> +++ b/rust/kernel/fs/file.rs
> @@ -17,6 +17,11 @@
>  };
>  use core::ptr;
>  
> +/// Primitive type representing the offset within a [`File`].
> +///
> +/// Type alias for `bindings::loff_t`.
> +pub type Offset = bindings::loff_t;
> +
>  /// Flags associated with a [`File`].
>  pub mod flags {
>      /// File is opened in append mode.
> -- 
> 2.51.0
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 1/8] rust: fs: add file::Offset type alias
  2025-10-29 12:49   ` Christian Brauner
@ 2025-10-29 15:26     ` Danilo Krummrich
  0 siblings, 0 replies; 31+ messages in thread
From: Danilo Krummrich @ 2025-10-29 15:26 UTC (permalink / raw)
  To: Christian Brauner
  Cc: gregkh, rafael, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, mmaurer, rust-for-linux,
	linux-fsdevel, linux-kernel, Alexander Viro, Jan Kara

On Wed Oct 29, 2025 at 1:49 PM CET, Christian Brauner wrote:
> On Tue, Oct 21, 2025 at 12:26:13AM +0200, Danilo Krummrich wrote:
>> Add a type alias for file offsets, i.e. bindings::loff_t. Trying to
>> avoid using raw bindings types, this seems to be the better alternative
>> compared to just using i64.
>> 
>> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
>> Cc: Christian Brauner <brauner@kernel.org>
>> Cc: Jan Kara <jack@suse.cz>
>> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
>> ---
>> Al, Christian: If you are okay with the patch, kindly provide an ACK, so I can
>> take it through the driver-core tree.
>> ---
>
> Reviewed-by: Christian Brauner <brauner@kernel.org>

Thanks Christian!

Based on Miguel's suggestion [1] v3 of the series introduces a new type for
file::Offset rather than just a type alias.

Therefore, v3 [2] is significantly different, hence I will wait for you to reply
to v3 before picking up the entire series.

Thanks,
Danilo

[1] https://github.com/Rust-for-Linux/linux/issues/1198
[2] https://lore.kernel.org/lkml/20251022143158.64475-2-dakr@kernel.org/

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2025-10-29 15:26 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-20 22:26 [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Danilo Krummrich
2025-10-20 22:26 ` [PATCH v2 1/8] rust: fs: add file::Offset type alias Danilo Krummrich
2025-10-21 13:40   ` Alice Ryhl
2025-10-21 15:08   ` Miguel Ojeda
2025-10-21 15:26     ` Danilo Krummrich
2025-10-21 16:00       ` Miguel Ojeda
2025-10-21 16:25         ` Danilo Krummrich
2025-10-21 16:47           ` Miguel Ojeda
2025-10-21 17:34             ` Danilo Krummrich
2025-10-21 23:16               ` Miguel Ojeda
2025-10-29 12:49   ` Christian Brauner
2025-10-29 15:26     ` Danilo Krummrich
2025-10-20 22:26 ` [PATCH v2 2/8] rust: uaccess: add UserSliceReader::read_slice_partial() Danilo Krummrich
2025-10-20 22:26 ` [PATCH v2 3/8] rust: uaccess: add UserSliceWriter::write_slice_partial() Danilo Krummrich
2025-10-21 14:00   ` Alice Ryhl
2025-10-21 14:14     ` Danilo Krummrich
2025-10-21 14:18       ` Alice Ryhl
2025-10-21 14:34         ` Danilo Krummrich
2025-10-22  8:22           ` Alice Ryhl
2025-10-22  9:06             ` Danilo Krummrich
2025-10-20 22:26 ` [PATCH v2 4/8] rust: debugfs: support for binary large objects Danilo Krummrich
2025-10-21 14:03   ` Alice Ryhl
2025-10-22  5:58   ` Alexandre Courbot
2025-10-20 22:26 ` [PATCH v2 5/8] rust: debugfs: support blobs from smart pointers Danilo Krummrich
2025-10-22  5:57   ` Alexandre Courbot
2025-10-22  9:34     ` Danilo Krummrich
2025-10-20 22:26 ` [PATCH v2 6/8] samples: rust: debugfs: add example for blobs Danilo Krummrich
2025-10-20 22:26 ` [PATCH v2 7/8] rust: debugfs: support binary large objects for ScopedDir Danilo Krummrich
2025-10-20 22:26 ` [PATCH v2 8/8] samples: rust: debugfs_scoped: add example for blobs Danilo Krummrich
2025-10-21  7:09 ` [PATCH v2 0/8] Binary Large Objects for Rust DebugFS Greg KH
2025-10-21 21:26   ` Matthew Maurer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).