The __compat_only_sysfs_link_entry_to_kobj function creates a symlink to a
kobject but doesn't provide an option to change the symlink file name.

This patch adds a wrapper function compat_only_sysfs_link_entry_to_kobj
that extends the __compat_only_sysfs_link_entry_to_kobj functionality
which allows function caller to customize the symlink name.

Signed-off-by: Sourabh Jain <sourabhj...@linux.ibm.com>
---
 fs/sysfs/group.c      | 28 +++++++++++++++++++++++++---
 include/linux/sysfs.h | 12 ++++++++++++
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index d41c21fef138..0993645f0b59 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -424,6 +424,25 @@ EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group);
 int __compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj,
                                      struct kobject *target_kobj,
                                      const char *target_name)
+{
+       return compat_only_sysfs_link_entry_to_kobj(kobj, target_kobj,
+                                               target_name, NULL);
+}
+EXPORT_SYMBOL_GPL(__compat_only_sysfs_link_entry_to_kobj);
+
+/**
+ * compat_only_sysfs_link_entry_to_kobj - add a symlink to a kobject pointing
+ * to a group or an attribute
+ * @kobj:              The kobject containing the group.
+ * @target_kobj:       The target kobject.
+ * @target_name:       The name of the target group or attribute.
+ * @symlink_name:      The name of the symlink file (target_name will be
+ *                     considered if symlink_name is NULL).
+ */
+int compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj,
+                                        struct kobject *target_kobj,
+                                        const char *target_name,
+                                        const char *symlink_name)
 {
        struct kernfs_node *target;
        struct kernfs_node *entry;
@@ -448,12 +467,15 @@ int __compat_only_sysfs_link_entry_to_kobj(struct kobject 
*kobj,
                return -ENOENT;
        }
 
-       link = kernfs_create_link(kobj->sd, target_name, entry);
+       if (!symlink_name)
+               symlink_name = target_name;
+
+       link = kernfs_create_link(kobj->sd, symlink_name, entry);
        if (IS_ERR(link) && PTR_ERR(link) == -EEXIST)
-               sysfs_warn_dup(kobj->sd, target_name);
+               sysfs_warn_dup(kobj->sd, symlink_name);
 
        kernfs_put(entry);
        kernfs_put(target);
        return PTR_ERR_OR_ZERO(link);
 }
-EXPORT_SYMBOL_GPL(__compat_only_sysfs_link_entry_to_kobj);
+EXPORT_SYMBOL_GPL(compat_only_sysfs_link_entry_to_kobj);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 5420817ed317..15b195a4529d 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -300,6 +300,10 @@ void sysfs_remove_link_from_group(struct kobject *kobj, 
const char *group_name,
 int __compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj,
                                      struct kobject *target_kobj,
                                      const char *target_name);
+int compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj,
+                                        struct kobject *target_kobj,
+                                        const char *target_name,
+                                        const char *symlink_name);
 
 void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
 
@@ -508,6 +512,14 @@ static inline int __compat_only_sysfs_link_entry_to_kobj(
        return 0;
 }
 
+static int compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj,
+                                               struct kobject *target_kobj,
+                                               const char *target_name,
+                                               const char *symlink_name)
+{
+       return 0;
+}
+
 static inline void sysfs_notify(struct kobject *kobj, const char *dir,
                                const char *attr)
 {
-- 
2.17.2

Reply via email to