sysfs: Add sysfs_merge_group() and sysfs_unmerge_group()

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>

authored by Alan Stern and committed by Rafael J. Wysocki 69d44ffb 098dff73

+74
+59
fs/sysfs/group.c
··· 148 148 sysfs_put(sd); 149 149 } 150 150 151 + /** 152 + * sysfs_merge_group - merge files into a pre-existing attribute group. 153 + * @kobj: The kobject containing the group. 154 + * @grp: The files to create and the attribute group they belong to. 155 + * 156 + * This function returns an error if the group doesn't exist or any of the 157 + * files already exist in that group, in which case none of the new files 158 + * are created. 159 + */ 160 + int sysfs_merge_group(struct kobject *kobj, 161 + const struct attribute_group *grp) 162 + { 163 + struct sysfs_dirent *dir_sd; 164 + int error = 0; 165 + struct attribute *const *attr; 166 + int i; 167 + 168 + if (grp) 169 + dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name); 170 + else 171 + dir_sd = sysfs_get(kobj->sd); 172 + if (!dir_sd) 173 + return -ENOENT; 174 + 175 + for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr)) 176 + error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); 177 + if (error) { 178 + while (--i >= 0) 179 + sysfs_hash_and_remove(dir_sd, NULL, (*--attr)->name); 180 + } 181 + sysfs_put(dir_sd); 182 + 183 + return error; 184 + } 185 + EXPORT_SYMBOL_GPL(sysfs_merge_group); 186 + 187 + /** 188 + * sysfs_unmerge_group - remove files from a pre-existing attribute group. 189 + * @kobj: The kobject containing the group. 190 + * @grp: The files to remove and the attribute group they belong to. 191 + */ 192 + void sysfs_unmerge_group(struct kobject *kobj, 193 + const struct attribute_group *grp) 194 + { 195 + struct sysfs_dirent *dir_sd; 196 + struct attribute *const *attr; 197 + 198 + if (grp) 199 + dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name); 200 + else 201 + dir_sd = sysfs_get(kobj->sd); 202 + if (dir_sd) { 203 + for (attr = grp->attrs; *attr; ++attr) 204 + sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); 205 + sysfs_put(dir_sd); 206 + } 207 + } 208 + EXPORT_SYMBOL_GPL(sysfs_unmerge_group); 209 + 151 210 152 211 EXPORT_SYMBOL_GPL(sysfs_create_group); 153 212 EXPORT_SYMBOL_GPL(sysfs_update_group);
+15
include/linux/sysfs.h
··· 164 164 const struct attribute *attr, const char *group); 165 165 void sysfs_remove_file_from_group(struct kobject *kobj, 166 166 const struct attribute *attr, const char *group); 167 + int sysfs_merge_group(struct kobject *kobj, 168 + const struct attribute_group *grp); 169 + void sysfs_unmerge_group(struct kobject *kobj, 170 + const struct attribute_group *grp); 167 171 168 172 void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr); 169 173 void sysfs_notify_dirent(struct sysfs_dirent *sd); ··· 303 299 304 300 static inline void sysfs_remove_file_from_group(struct kobject *kobj, 305 301 const struct attribute *attr, const char *group) 302 + { 303 + } 304 + 305 + static inline int sysfs_merge_group(struct kobject *kobj, 306 + const struct attribute_group *grp) 307 + { 308 + return 0; 309 + } 310 + 311 + static inline void sysfs_unmerge_group(struct kobject *kobj, 312 + const struct attribute_group *grp) 306 313 { 307 314 } 308 315