Introduce a /sys/module entry for loaded pstore backends which provide users and testcases with a standarized interface to retrieve information on which pstore backends are currently registered. Signed-off-by: Yuanhe Shu <xiangzao@xxxxxxxxxxxxxxxxx> --- fs/pstore/inode.c | 38 ++++++++++++++++++++++++++++++++++++++ fs/pstore/internal.h | 1 + fs/pstore/platform.c | 9 ++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index bee71c7da995..5800fa4abfce 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -6,6 +6,7 @@ */ #include <linux/module.h> +#include <linux/kobject.h> #include <linux/fs.h> #include <linux/fsnotify.h> #include <linux/pagemap.h> @@ -491,6 +492,43 @@ int __init pstore_init_fs(void) return err; } +static ssize_t loaded_backend_show(struct kobject *k, + struct kobj_attribute *attr, char *buf) +{ + struct pstore_info_list *entry; + char *old, *loaded_backend = NULL; + + mutex_lock(&psback_lock); + list_for_each_entry(entry, &psback->list_entry, list) + if (!loaded_backend) + loaded_backend = kstrdup(entry->psi->name, GFP_KERNEL); + else { + old = loaded_backend; + loaded_backend = kasprintf(GFP_KERNEL, "%s,%s", + old, entry->psi->name); + kfree(old); + } + mutex_unlock(&psback_lock); + + return sprintf(buf, "%s\n", loaded_backend); +} + +static struct kobj_attribute backend_attribute = + __ATTR(loaded_backend, 0444, loaded_backend_show, NULL); + +int __init pstore_init_entry(void) +{ + int err = 0; + struct kobject *pstore_kobj; + + pstore_kobj = kset_find_obj(module_kset, "pstore"); + if (pstore_kobj) { + err = sysfs_create_file(pstore_kobj, &backend_attribute.attr); + kobject_put(pstore_kobj); + } + return err; +} + void __exit pstore_exit_fs(void) { unregister_filesystem(&pstore_fs_type); diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h index 4b1c7ba27052..ffc86b04c5cc 100644 --- a/fs/pstore/internal.h +++ b/fs/pstore/internal.h @@ -47,6 +47,7 @@ extern void pstore_record_init(struct pstore_record *record, /* Called during pstore init/exit. */ int __init pstore_init_fs(void); +int __init pstore_init_entry(void); void __exit pstore_exit_fs(void); #endif diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index a1742b39fb88..5c10a546cdf0 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -841,7 +841,14 @@ static void pstore_timefunc(struct timer_list *unused) static int __init pstore_init(void) { - return pstore_init_fs(); + int ret; + + ret = pstore_init_fs(); + if (ret) + return ret; + + ret = pstore_init_entry(); + return ret; } late_initcall(pstore_init); -- 2.39.3