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 <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Danilo Krummrich <[email protected]>
Cc: [email protected]
Cc: Tejun Heo <[email protected]>
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Pavol Sakac <[email protected]>
---
 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


Reply via email to