sysfs: Add sysfs_merge_group() and sysfs_unmerge_group()
authorAlan Stern <stern@rowland.harvard.edu>
Sat, 25 Sep 2010 21:34:22 +0000 (23:34 +0200)
committerRafael J. Wysocki <rjw@sisk.pl>
Sat, 16 Oct 2010 23:57:44 +0000 (01:57 +0200)
This patch (as1420) adds sysfs_merge_group() and sysfs_unmerge_group()
functions, allowing drivers easily to add and remove sets of
attributes to a pre-existing attribute group directory.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
fs/sysfs/group.c
include/linux/sysfs.h

index 23c1e598792a088cfdd757030f9d733251943fb7..442f34ff1af80178ee63e9a7d8ae2abe3df6154e 100644 (file)
@@ -148,6 +148,65 @@ void sysfs_remove_group(struct kobject * kobj,
        sysfs_put(sd);
 }
 
+/**
+ * sysfs_merge_group - merge files into a pre-existing attribute group.
+ * @kobj:      The kobject containing the group.
+ * @grp:       The files to create and the attribute group they belong to.
+ *
+ * This function returns an error if the group doesn't exist or any of the
+ * files already exist in that group, in which case none of the new files
+ * are created.
+ */
+int sysfs_merge_group(struct kobject *kobj,
+                      const struct attribute_group *grp)
+{
+       struct sysfs_dirent *dir_sd;
+       int error = 0;
+       struct attribute *const *attr;
+       int i;
+
+       if (grp)
+               dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
+       else
+               dir_sd = sysfs_get(kobj->sd);
+       if (!dir_sd)
+               return -ENOENT;
+
+       for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr))
+               error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
+       if (error) {
+               while (--i >= 0)
+                       sysfs_hash_and_remove(dir_sd, NULL, (*--attr)->name);
+       }
+       sysfs_put(dir_sd);
+
+       return error;
+}
+EXPORT_SYMBOL_GPL(sysfs_merge_group);
+
+/**
+ * sysfs_unmerge_group - remove files from a pre-existing attribute group.
+ * @kobj:      The kobject containing the group.
+ * @grp:       The files to remove and the attribute group they belong to.
+ */
+void sysfs_unmerge_group(struct kobject *kobj,
+                      const struct attribute_group *grp)
+{
+       struct sysfs_dirent *dir_sd;
+       struct attribute *const *attr;
+
+       if (grp)
+               dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
+       else
+               dir_sd = sysfs_get(kobj->sd);
+       if (dir_sd) {
+               for (attr = grp->attrs; *attr; ++attr)
+                       sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
+               sysfs_put(dir_sd);
+       }
+}
+EXPORT_SYMBOL_GPL(sysfs_unmerge_group);
+
 
 EXPORT_SYMBOL_GPL(sysfs_create_group);
 EXPORT_SYMBOL_GPL(sysfs_update_group);
index 96eb576d82fdadbd6a3cce0253325c733f6603f3..30b881555fa576fc4a0fb9a82f8418fac72aefa2 100644 (file)
@@ -164,6 +164,10 @@ int sysfs_add_file_to_group(struct kobject *kobj,
                        const struct attribute *attr, const char *group);
 void sysfs_remove_file_from_group(struct kobject *kobj,
                        const struct attribute *attr, const char *group);
+int sysfs_merge_group(struct kobject *kobj,
+                      const struct attribute_group *grp);
+void sysfs_unmerge_group(struct kobject *kobj,
+                      const struct attribute_group *grp);
 
 void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
 void sysfs_notify_dirent(struct sysfs_dirent *sd);
@@ -302,6 +306,17 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj,
 {
 }
 
+static inline int sysfs_merge_group(struct kobject *kobj,
+                      const struct attribute_group *grp)
+{
+       return 0;
+}
+
+static inline void sysfs_unmerge_group(struct kobject *kobj,
+                      const struct attribute_group *grp)
+{
+}
+
 static inline void sysfs_notify(struct kobject *kobj, const char *dir,
                                const char *attr)
 {