1 /* 2 * fs/sysfs/group.c - Operations for adding/removing multiple files at once. 3 * 4 * Copyright (c) 2003 Patrick Mochel 5 * Copyright (c) 2003 Open Source Development Lab 6 * 7 * This file is released undert the GPL v2. 8 * 9 */ 10 11 #include <linux/kobject.h> 12 #include <linux/module.h> 13 #include <linux/dcache.h> 14 #include <linux/namei.h> 15 #include <linux/err.h> 16 #include "sysfs.h" 17 18 19 static void remove_files(struct sysfs_dirent *dir_sd, 20 const struct attribute_group *grp) 21 { 22 struct attribute *const* attr; 23 24 for (attr = grp->attrs; *attr; attr++) 25 sysfs_hash_and_remove(dir_sd, (*attr)->name); 26 } 27 28 static int create_files(struct sysfs_dirent *dir_sd, 29 const struct attribute_group *grp) 30 { 31 struct attribute *const* attr; 32 int error = 0; 33 34 for (attr = grp->attrs; *attr && !error; attr++) 35 error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); 36 if (error) 37 remove_files(dir_sd, grp); 38 return error; 39 } 40 41 42 int sysfs_create_group(struct kobject * kobj, 43 const struct attribute_group * grp) 44 { 45 struct sysfs_dirent *sd; 46 int error; 47 48 BUG_ON(!kobj || !kobj->sd); 49 50 if (grp->name) { 51 error = sysfs_create_subdir(kobj, grp->name, &sd); 52 if (error) 53 return error; 54 } else 55 sd = kobj->sd; 56 sysfs_get(sd); 57 error = create_files(sd, grp); 58 if (error) { 59 if (grp->name) 60 sysfs_remove_subdir(sd); 61 } 62 sysfs_put(sd); 63 return error; 64 } 65 66 void sysfs_remove_group(struct kobject * kobj, 67 const struct attribute_group * grp) 68 { 69 struct sysfs_dirent *dir_sd = kobj->sd; 70 struct sysfs_dirent *sd; 71 72 if (grp->name) { 73 sd = sysfs_get_dirent(dir_sd, grp->name); 74 BUG_ON(!sd); 75 } else 76 sd = sysfs_get(dir_sd); 77 78 remove_files(sd, grp); 79 if (grp->name) 80 sysfs_remove_subdir(sd); 81 82 sysfs_put(sd); 83 } 84 85 86 EXPORT_SYMBOL_GPL(sysfs_create_group); 87 EXPORT_SYMBOL_GPL(sysfs_remove_group); 88