Rust for Linux List
 help / color / mirror / Atom feed
* [PATCH] configfs: rust: add an API for adding default groups from C
@ 2026-02-15 20:33 Andreas Hindborg
  2026-02-16  8:37 ` Alice Ryhl
  2026-02-16  9:58 ` Danilo Krummrich
  0 siblings, 2 replies; 4+ messages in thread
From: Andreas Hindborg @ 2026-02-15 20:33 UTC (permalink / raw)
  To: Boqun Feng, Jens Axboe, Miguel Ojeda, Gary Guo,
	Björn Roy Baron, Benno Lossin, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Breno Leitao
  Cc: linux-kernel, linux-block, rust-for-linux, Andreas Hindborg

Some C subsystems provide a feature to add configfs default groups to the
configfs hierarchy of other drivers or subsystems. Rust abstractions for
these subsystems will want a way to add these default groups via the
configfs Rust API. So add infrastructure to make this possible.

Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
 drivers/block/rnull/configfs.rs |  1 +
 rust/helpers/configfs.c         | 16 ++++++++++++++++
 rust/helpers/helpers.c          |  1 +
 rust/kernel/configfs.rs         | 33 ++++++++++++++++++++++++++++++++-
 samples/rust/rust_configfs.rs   |  8 +++++++-
 5 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs
index 6713a6d92391d..ea38b27a9011c 100644
--- a/drivers/block/rnull/configfs.rs
+++ b/drivers/block/rnull/configfs.rs
@@ -78,6 +78,7 @@ fn make_group(
                     name: name.try_into()?,
                 }),
             }),
+            core::iter::empty(),
         ))
     }
 }
diff --git a/rust/helpers/configfs.c b/rust/helpers/configfs.c
new file mode 100644
index 0000000000000..7cec8ffcb093d
--- /dev/null
+++ b/rust/helpers/configfs.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/configfs.h>
+
+__rust_helper void
+rust_helper_configfs_add_default_group(struct config_group *new_group,
+				       struct config_group *group)
+{
+	configfs_add_default_group(new_group, group);
+}
+
+__rust_helper void
+__rust_helper_configfs_remove_default_groups(struct config_group *group)
+{
+	configfs_remove_default_groups(group);
+}
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 79c72762ad9c4..613b41e8b781c 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -19,6 +19,7 @@
 #include "build_bug.c"
 #include "clk.c"
 #include "completion.c"
+#include "configfs.c"
 #include "cpu.c"
 #include "cpufreq.c"
 #include "cpumask.c"
diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
index 466fb7f407628..705f1647269d9 100644
--- a/rust/kernel/configfs.rs
+++ b/rust/kernel/configfs.rs
@@ -242,12 +242,22 @@ unsafe fn container_of(group: *const bindings::config_group) -> *const Self {
 ///
 /// To add a subgroup to configfs, pass this type as `ctype` to
 /// [`crate::configfs_attrs`] when creating a group in [`GroupOperations::make_group`].
-#[pin_data]
+#[pin_data(PinnedDrop)]
 pub struct Group<Data> {
     #[pin]
     group: Opaque<bindings::config_group>,
     #[pin]
     data: Data,
+    default_groups: KVec<Arc<dyn CDefaultGroup>>,
+}
+
+#[pinned_drop]
+impl<Data> PinnedDrop for Group<Data> {
+    fn drop(self: Pin<&mut Self>) {
+        // SAFETY: We have exclusive access to `self` and we know the default groups are alive
+        // because we reference them through `self.default_groups`.
+        unsafe { bindings::configfs_remove_default_groups(self.group.get()) };
+    }
 }
 
 impl<Data> Group<Data> {
@@ -259,7 +269,13 @@ pub fn new(
         name: CString,
         item_type: &'static ItemType<Group<Data>, Data>,
         data: impl PinInit<Data, Error>,
+        default_groups: impl IntoIterator<Item = Arc<dyn CDefaultGroup>>,
     ) -> impl PinInit<Self, Error> {
+        let mut dg = KVec::new();
+        for group in default_groups {
+            dg.push(group, GFP_KERNEL).unwrap();
+        }
+
         try_pin_init!(Self {
             group <- pin_init::init_zeroed().chain(|v: &mut Opaque<bindings::config_group>| {
                 let place = v.get();
@@ -268,13 +284,28 @@ pub fn new(
                 unsafe {
                     bindings::config_group_init_type_name(place, name.cast(), item_type.as_ptr())
                 };
+
+                for default_group in &dg {
+                    // SAFETY: We keep the default groups alive until `Self` is dropped.
+                    unsafe { bindings::configfs_add_default_group(default_group.group_ptr(), place) }
+                }
                 Ok(())
             }),
             data <- data,
+            default_groups: dg,
         })
     }
 }
 
+/// A trait for default configfs groups added by C code.
+///
+/// Rust abstractions that work with C code that creates configfs groups can implement this trait to
+/// add the groups as default groups via the Rust configfs API.
+pub trait CDefaultGroup {
+    /// Return a raw pointer to the group definition.
+    fn group_ptr(&self) -> *mut bindings::config_group;
+}
+
 // SAFETY: `Group<Data>` embeds a field of type `bindings::config_group`
 // within the `group` field.
 unsafe impl<Data> HasGroup<Data> for Group<Data> {
diff --git a/samples/rust/rust_configfs.rs b/samples/rust/rust_configfs.rs
index 0ccc7553ef395..c65dda8bfacd2 100644
--- a/samples/rust/rust_configfs.rs
+++ b/samples/rust/rust_configfs.rs
@@ -84,7 +84,12 @@ fn make_group(&self, name: &CStr) -> Result<impl PinInit<configfs::Group<Child>,
             ],
         };
 
-        Ok(configfs::Group::new(name.try_into()?, tpe, Child::new()))
+        Ok(configfs::Group::new(
+            name.try_into()?,
+            tpe,
+            Child::new(),
+            core::iter::empty(),
+        ))
     }
 }
 
@@ -153,6 +158,7 @@ fn make_group(&self, name: &CStr) -> Result<impl PinInit<configfs::Group<GrandCh
             name.try_into()?,
             tpe,
             GrandChild::new(),
+            core::iter::empty(),
         ))
     }
 }

---
base-commit: 05f7e89ab9731565d8a62e3b5d1ec206485eeb0b
change-id: 20260215-configfs-c-default-groups-bdb0a44633a6

Best regards,
-- 
Andreas Hindborg <a.hindborg@kernel.org>



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

* Re: [PATCH] configfs: rust: add an API for adding default groups from C
  2026-02-15 20:33 [PATCH] configfs: rust: add an API for adding default groups from C Andreas Hindborg
@ 2026-02-16  8:37 ` Alice Ryhl
  2026-05-13 14:39   ` Andreas Hindborg
  2026-02-16  9:58 ` Danilo Krummrich
  1 sibling, 1 reply; 4+ messages in thread
From: Alice Ryhl @ 2026-02-16  8:37 UTC (permalink / raw)
  To: Andreas Hindborg
  Cc: Boqun Feng, Jens Axboe, Miguel Ojeda, Gary Guo,
	Björn Roy Baron, Benno Lossin, Trevor Gross,
	Danilo Krummrich, Breno Leitao, linux-kernel, linux-block,
	rust-for-linux

On Sun, Feb 15, 2026 at 09:33:47PM +0100, Andreas Hindborg wrote:
> Some C subsystems provide a feature to add configfs default groups to the
> configfs hierarchy of other drivers or subsystems. Rust abstractions for
> these subsystems will want a way to add these default groups via the
> configfs Rust API. So add infrastructure to make this possible.
> 
> Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
> ---
>  drivers/block/rnull/configfs.rs |  1 +
>  rust/helpers/configfs.c         | 16 ++++++++++++++++
>  rust/helpers/helpers.c          |  1 +
>  rust/kernel/configfs.rs         | 33 ++++++++++++++++++++++++++++++++-
>  samples/rust/rust_configfs.rs   |  8 +++++++-
>  5 files changed, 57 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs
> index 6713a6d92391d..ea38b27a9011c 100644
> --- a/drivers/block/rnull/configfs.rs
> +++ b/drivers/block/rnull/configfs.rs
> @@ -78,6 +78,7 @@ fn make_group(
>                      name: name.try_into()?,
>                  }),
>              }),
> +            core::iter::empty(),
>          ))
>      }
>  }
> diff --git a/rust/helpers/configfs.c b/rust/helpers/configfs.c
> new file mode 100644
> index 0000000000000..7cec8ffcb093d
> --- /dev/null
> +++ b/rust/helpers/configfs.c
> @@ -0,0 +1,16 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/configfs.h>
> +
> +__rust_helper void
> +rust_helper_configfs_add_default_group(struct config_group *new_group,
> +				       struct config_group *group)
> +{
> +	configfs_add_default_group(new_group, group);
> +}
> +
> +__rust_helper void
> +__rust_helper_configfs_remove_default_groups(struct config_group *group)

Only the annotation has the two __ prefix, not the symbol name.

> +#[pinned_drop]
> +impl<Data> PinnedDrop for Group<Data> {
> +    fn drop(self: Pin<&mut Self>) {
> +        // SAFETY: We have exclusive access to `self` and we know the default groups are alive
> +        // because we reference them through `self.default_groups`.
> +        unsafe { bindings::configfs_remove_default_groups(self.group.get()) };

Why isn't this here already?

> +    }
>  }
>  
>  impl<Data> Group<Data> {
> @@ -259,7 +269,13 @@ pub fn new(
>          name: CString,
>          item_type: &'static ItemType<Group<Data>, Data>,
>          data: impl PinInit<Data, Error>,
> +        default_groups: impl IntoIterator<Item = Arc<dyn CDefaultGroup>>,

Honestly, I'd just take a KVec here.

>      ) -> impl PinInit<Self, Error> {
> +        let mut dg = KVec::new();
> +        for group in default_groups {
> +            dg.push(group, GFP_KERNEL).unwrap();
> +        }
> +
>          try_pin_init!(Self {
>              group <- pin_init::init_zeroed().chain(|v: &mut Opaque<bindings::config_group>| {
>                  let place = v.get();
> @@ -268,13 +284,28 @@ pub fn new(
>                  unsafe {
>                      bindings::config_group_init_type_name(place, name.cast(), item_type.as_ptr())
>                  };
> +
> +                for default_group in &dg {
> +                    // SAFETY: We keep the default groups alive until `Self` is dropped.
> +                    unsafe { bindings::configfs_add_default_group(default_group.group_ptr(), place) }
> +                }

Do these not need to be removed in drop?

Alice

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

* Re: [PATCH] configfs: rust: add an API for adding default groups from C
  2026-02-15 20:33 [PATCH] configfs: rust: add an API for adding default groups from C Andreas Hindborg
  2026-02-16  8:37 ` Alice Ryhl
@ 2026-02-16  9:58 ` Danilo Krummrich
  1 sibling, 0 replies; 4+ messages in thread
From: Danilo Krummrich @ 2026-02-16  9:58 UTC (permalink / raw)
  To: Andreas Hindborg
  Cc: Boqun Feng, Jens Axboe, Miguel Ojeda, Gary Guo,
	Björn Roy Baron, Benno Lossin, Alice Ryhl, Trevor Gross,
	Breno Leitao, linux-kernel, linux-block, rust-for-linux

On Sun Feb 15, 2026 at 9:33 PM CET, Andreas Hindborg wrote:
> @@ -259,7 +269,13 @@ pub fn new(
>          name: CString,
>          item_type: &'static ItemType<Group<Data>, Data>,
>          data: impl PinInit<Data, Error>,
> +        default_groups: impl IntoIterator<Item = Arc<dyn CDefaultGroup>>,
>      ) -> impl PinInit<Self, Error> {
> +        let mut dg = KVec::new();
> +        for group in default_groups {
> +            dg.push(group, GFP_KERNEL).unwrap();

We should not panic the kernel on allocation failure.

If you wrap the function body into pin_init::pin_init_scope() you can just use
the '?' operator instead.

> +        }
> +
>          try_pin_init!(Self {
>              group <- pin_init::init_zeroed().chain(|v: &mut Opaque<bindings::config_group>| {
>                  let place = v.get();
> @@ -268,13 +284,28 @@ pub fn new(
>                  unsafe {
>                      bindings::config_group_init_type_name(place, name.cast(), item_type.as_ptr())
>                  };
> +
> +                for default_group in &dg {
> +                    // SAFETY: We keep the default groups alive until `Self` is dropped.
> +                    unsafe { bindings::configfs_add_default_group(default_group.group_ptr(), place) }
> +                }
>                  Ok(())
>              }),
>              data <- data,
> +            default_groups: dg,
>          })
>      }
>  }

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

* Re: [PATCH] configfs: rust: add an API for adding default groups from C
  2026-02-16  8:37 ` Alice Ryhl
@ 2026-05-13 14:39   ` Andreas Hindborg
  0 siblings, 0 replies; 4+ messages in thread
From: Andreas Hindborg @ 2026-05-13 14:39 UTC (permalink / raw)
  To: Alice Ryhl
  Cc: Boqun Feng, Jens Axboe, Miguel Ojeda, Gary Guo,
	Björn Roy Baron, Benno Lossin, Trevor Gross,
	Danilo Krummrich, Breno Leitao, linux-kernel, linux-block,
	rust-for-linux

Alice Ryhl <aliceryhl@google.com> writes:

> On Sun, Feb 15, 2026 at 09:33:47PM +0100, Andreas Hindborg wrote:
>> Some C subsystems provide a feature to add configfs default groups to the
>> configfs hierarchy of other drivers or subsystems. Rust abstractions for
>> these subsystems will want a way to add these default groups via the
>> configfs Rust API. So add infrastructure to make this possible.
>> 
>> Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
>> ---
>>  drivers/block/rnull/configfs.rs |  1 +
>>  rust/helpers/configfs.c         | 16 ++++++++++++++++
>>  rust/helpers/helpers.c          |  1 +
>>  rust/kernel/configfs.rs         | 33 ++++++++++++++++++++++++++++++++-
>>  samples/rust/rust_configfs.rs   |  8 +++++++-
>>  5 files changed, 57 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs
>> index 6713a6d92391d..ea38b27a9011c 100644
>> --- a/drivers/block/rnull/configfs.rs
>> +++ b/drivers/block/rnull/configfs.rs
>> @@ -78,6 +78,7 @@ fn make_group(
>>                      name: name.try_into()?,
>>                  }),
>>              }),
>> +            core::iter::empty(),
>>          ))
>>      }
>>  }
>> diff --git a/rust/helpers/configfs.c b/rust/helpers/configfs.c
>> new file mode 100644
>> index 0000000000000..7cec8ffcb093d
>> --- /dev/null
>> +++ b/rust/helpers/configfs.c
>> @@ -0,0 +1,16 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +#include <linux/configfs.h>
>> +
>> +__rust_helper void
>> +rust_helper_configfs_add_default_group(struct config_group *new_group,
>> +				       struct config_group *group)
>> +{
>> +	configfs_add_default_group(new_group, group);
>> +}
>> +
>> +__rust_helper void
>> +__rust_helper_configfs_remove_default_groups(struct config_group *group)
>
> Only the annotation has the two __ prefix, not the symbol name.

Hmm, odd that the bindings generate correct anyway.

>
>> +#[pinned_drop]
>> +impl<Data> PinnedDrop for Group<Data> {
>> +    fn drop(self: Pin<&mut Self>) {
>> +        // SAFETY: We have exclusive access to `self` and we know the default groups are alive
>> +        // because we reference them through `self.default_groups`.
>> +        unsafe { bindings::configfs_remove_default_groups(self.group.get()) };
>
> Why isn't this here already?

What do you mean. The drop of default groups is not there already,
because it was not previously possible to add default groups. So there
would be nothing to drop.

>
>> +    }
>>  }
>>  
>>  impl<Data> Group<Data> {
>> @@ -259,7 +269,13 @@ pub fn new(
>>          name: CString,
>>          item_type: &'static ItemType<Group<Data>, Data>,
>>          data: impl PinInit<Data, Error>,
>> +        default_groups: impl IntoIterator<Item = Arc<dyn CDefaultGroup>>,
>
> Honestly, I'd just take a KVec here.

I was trying to be fancy. Is it not more flexible to take an iterator?
What are the pros/cons?

>
>>      ) -> impl PinInit<Self, Error> {
>> +        let mut dg = KVec::new();
>> +        for group in default_groups {
>> +            dg.push(group, GFP_KERNEL).unwrap();
>> +        }
>> +
>>          try_pin_init!(Self {
>>              group <- pin_init::init_zeroed().chain(|v: &mut Opaque<bindings::config_group>| {
>>                  let place = v.get();
>> @@ -268,13 +284,28 @@ pub fn new(
>>                  unsafe {
>>                      bindings::config_group_init_type_name(place, name.cast(), item_type.as_ptr())
>>                  };
>> +
>> +                for default_group in &dg {
>> +                    // SAFETY: We keep the default groups alive until `Self` is dropped.
>> +                    unsafe { bindings::configfs_add_default_group(default_group.group_ptr(), place) }
>> +                }
>
> Do these not need to be removed in drop?

Yes, I added the drop logic above. It is the hunk you asked why is it not
already here?


Best regards,
Andreas Hindborg




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

end of thread, other threads:[~2026-05-13 14:39 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-15 20:33 [PATCH] configfs: rust: add an API for adding default groups from C Andreas Hindborg
2026-02-16  8:37 ` Alice Ryhl
2026-05-13 14:39   ` Andreas Hindborg
2026-02-16  9:58 ` Danilo Krummrich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox