[RFC PATCH 03/14] sysfs: introduce sysfs_kf_syscall_ops dispatching to kobj_type
From: Pavol Sakac
Date: Thu Jul 02 2026 - 14:26:36 EST
Wire the sysfs side of the lazy populate chain. sysfs_init()
previously passed NULL as syscall_ops to kernfs_create_root();
install sysfs_kf_syscall_ops with populate and populate_all
that dispatch to the owning kobject's kobj_type.
The kernfs lookup path pins the parent's active reference, so
parent->priv is safe to read; sysfs_populate() additionally
pins the dereferenced kobject with kobject_get_unless_zero()
across the sleeping ktype->populate call. sysfs_populate_all()
does the same for ktype->populate_all on readdir.
Both callbacks refuse dispatch in namespaced directories: the
initial consumers (PCI, VFIO) are namespace-agnostic, and tag
propagation is out of scope. Transient errors propagate without
negative-dentry caching so the next lookup retries populate.
No behavior change: no kobj_type sets populate/populate_all yet.
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Cc: Rafael J. Wysocki <rafael@xxxxxxxxxx>
Cc: linux-kernel@xxxxxxxxxxxxxxx
Cc: linux-api@xxxxxxxxxxxxxxx
Cc: Danilo Krummrich <dakr@xxxxxxxxxx>
Cc: driver-core@xxxxxxxxxxxxxxx
Cc: Tejun Heo <tj@xxxxxxxxxx>
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Pavol Sakac <sakacpav@xxxxxxxxx>
---
fs/sysfs/mount.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index b199e8ff79b1f..9e0a37b60d6e7 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -10,6 +10,7 @@
*/
#include <linux/fs.h>
+#include <linux/kobject.h>
#include <linux/magic.h>
#include <linux/mount.h>
#include <linux/init.h>
@@ -96,11 +97,68 @@ static struct file_system_type sysfs_fs_type = {
.fs_flags = FS_USERNS_MOUNT,
};
+/*
+ * sysfs_populate - dispatch a lookup miss to the owning kobj_type.
+ *
+ * kernfs pins @parent across the call; we pin @kobj while the
+ * (sleepable) ktype->populate callback runs.
+ */
+static int sysfs_populate(struct kernfs_node *parent, const char *name)
+{
+ struct kobject *kobj;
+ const struct kobj_type *ktype;
+ int ret;
+
+ if (kernfs_ns_enabled(parent))
+ return -ENOENT;
+
+ kobj = parent->priv;
+ ktype = kobj ? kobj->ktype : NULL;
+ if (!ktype || !ktype->populate)
+ return -ENOENT;
+
+ if (!kobject_get_unless_zero(kobj))
+ return -ENOENT;
+
+ ret = ktype->populate(kobj, name);
+
+ kobject_put(kobj);
+ return ret;
+}
+
+/* sysfs_populate_all - readdir-time variant; best-effort, retry-safe. */
+static void sysfs_populate_all(struct kernfs_node *parent)
+{
+ struct kobject *kobj;
+ const struct kobj_type *ktype;
+
+ if (kernfs_ns_enabled(parent))
+ return;
+
+ kobj = parent->priv;
+ ktype = kobj ? kobj->ktype : NULL;
+ if (!ktype || !ktype->populate_all)
+ return;
+
+ if (!kobject_get_unless_zero(kobj))
+ return;
+
+ ktype->populate_all(kobj);
+
+ kobject_put(kobj);
+}
+
+static struct kernfs_syscall_ops sysfs_kf_syscall_ops = {
+ .populate = sysfs_populate,
+ .populate_all = sysfs_populate_all,
+};
+
int __init sysfs_init(void)
{
int err;
- sysfs_root = kernfs_create_root(NULL, KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK,
+ sysfs_root = kernfs_create_root(&sysfs_kf_syscall_ops,
+ KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK,
NULL);
if (IS_ERR(sysfs_root))
return PTR_ERR(sysfs_root);
--
2.47.3
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597