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
