From: Breno Leitao <leitao@debian.org>
To: Shuah Khan <shuah@kernel.org>, Andreas Hindborg <a.hindborg@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
gustavold@gmail.com, linux-fsdevel@vger.kernel.org,
Breno Leitao <leitao@debian.org>,
kernel-team@meta.com, vasilisalmpanis@gmail.com
Subject: [PATCH 2/4] samples/configfs: add a subsystem that accepts symlinks
Date: Wed, 26 Aug 2026 03:47:03 -0700 [thread overview]
Message-ID: <20260826-config_selftest-v1-2-e364b07e91ac@debian.org> (raw)
In-Reply-To: <20260826-config_selftest-v1-0-e364b07e91ac@debian.org>
The sample registers three subsystems and none implements ->allow_link(),
so the symlink(2) half of the configfs ABI has no small in-tree user to
test against.
Add 04-symlink-children, whose children take a link to any config_item and
export the number of links they hold.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
samples/configfs/configfs_sample.c | 121 +++++++++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c
index c1b108ec4ea02..08403e787aef6 100644
--- a/samples/configfs/configfs_sample.c
+++ b/samples/configfs/configfs_sample.c
@@ -313,6 +313,126 @@ static struct configfs_subsystem group_children_subsys = {
/* ----------------------------------------------------------------- */
+/*
+ * 04-symlink-children
+ *
+ * This example has children that are valid sources for symlink(2). A
+ * child accepts a link to any other config_item and reports how many
+ * links it currently holds, so ->allow_link() and ->drop_link() are
+ * observable from userspace.
+ */
+
+struct symlink_child {
+ struct config_item item;
+ int nlinks;
+};
+
+static inline struct symlink_child *to_symlink_child(struct config_item *item)
+{
+ return container_of(item, struct symlink_child, item);
+}
+
+static ssize_t symlink_child_nlinks_show(struct config_item *item, char *page)
+{
+ return sprintf(page, "%d\n", to_symlink_child(item)->nlinks);
+}
+
+CONFIGFS_ATTR_RO(symlink_child_, nlinks);
+
+static struct configfs_attribute *symlink_child_attrs[] = {
+ &symlink_child_attr_nlinks,
+ NULL,
+};
+
+/*
+ * The VFS holds the source item's directory locked across symlink(2) and
+ * unlink(2), so ->nlinks needs no lock of its own.
+ */
+static int symlink_child_allow_link(struct config_item *src,
+ struct config_item *target)
+{
+ to_symlink_child(src)->nlinks++;
+
+ return 0;
+}
+
+static void symlink_child_drop_link(struct config_item *src,
+ struct config_item *target)
+{
+ to_symlink_child(src)->nlinks--;
+}
+
+static void symlink_child_release(struct config_item *item)
+{
+ kfree(to_symlink_child(item));
+}
+
+static const struct configfs_item_operations symlink_child_item_ops = {
+ .release = symlink_child_release,
+ .allow_link = symlink_child_allow_link,
+ .drop_link = symlink_child_drop_link,
+};
+
+static const struct config_item_type symlink_child_type = {
+ .ct_item_ops = &symlink_child_item_ops,
+ .ct_attrs = symlink_child_attrs,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct config_item *symlink_children_make_item(
+ struct config_group *group, const char *name)
+{
+ struct symlink_child *symlink_child;
+
+ symlink_child = kzalloc_obj(*symlink_child, GFP_KERNEL);
+ if (!symlink_child)
+ return ERR_PTR(-ENOMEM);
+
+ config_item_init_type_name(&symlink_child->item, name,
+ &symlink_child_type);
+
+ return &symlink_child->item;
+}
+
+static ssize_t symlink_children_description_show(struct config_item *item,
+ char *page)
+{
+ return sprintf(page,
+"[04-symlink-children]\n"
+"\n"
+"This subsystem allows the creation of child config_items that\n"
+"symlink(2) can point at other config_items from. Each child\n"
+"reports the number of links it holds.\n");
+}
+
+CONFIGFS_ATTR_RO(symlink_children_, description);
+
+static struct configfs_attribute *symlink_children_attrs[] = {
+ &symlink_children_attr_description,
+ NULL,
+};
+
+static const struct configfs_group_operations symlink_children_group_ops = {
+ .make_item = symlink_children_make_item,
+};
+
+static const struct config_item_type symlink_children_type = {
+ .ct_group_ops = &symlink_children_group_ops,
+ .ct_attrs = symlink_children_attrs,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct configfs_subsystem symlink_children_subsys = {
+ .su_group = {
+ .cg_item = {
+ .ci_namebuf = "04-symlink-children",
+ .ci_type = &symlink_children_type,
+ },
+ },
+};
+
+/* ----------------------------------------------------------------- */
+
/*
* We're now done with our subsystem definitions.
* For convenience in this module, here's a list of them all. It
@@ -324,6 +444,7 @@ static struct configfs_subsystem *example_subsys[] = {
&childless_subsys.subsys,
&simple_children_subsys,
&group_children_subsys,
+ &symlink_children_subsys,
NULL,
};
--
2.53.0-Meta
next prev parent reply other threads:[~2026-08-26 10:47 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-26 10:47 [PATCH 0/4] configfs: add a basic selftest Breno Leitao
2026-08-26 10:47 ` [PATCH 1/4] selftests/configfs: add tests for the userspace interface Breno Leitao
2026-08-26 10:47 ` Breno Leitao [this message]
2026-08-26 10:47 ` [PATCH 3/4] selftests/configfs: cover symlink and unlink Breno Leitao
2026-08-26 10:47 ` [PATCH 4/4] selftests/configfs: race symlink against rmdir of the target Breno Leitao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260826-config_selftest-v1-2-e364b07e91ac@debian.org \
--to=leitao@debian.org \
--cc=a.hindborg@kernel.org \
--cc=gustavold@gmail.com \
--cc=kernel-team@meta.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=shuah@kernel.org \
--cc=vasilisalmpanis@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox