* [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; 3+ 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] 3+ 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; 3+ 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] 3+ 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; 3+ 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] 3+ messages in thread
end of thread, other threads:[~2026-02-16 9:58 UTC | newest]
Thread overview: 3+ 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-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