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 dentry * dir, 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,(*attr)->name); 26 } 27 28 static int create_files(struct dentry * dir, 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, *attr, SYSFS_KOBJ_ATTR); 36 } 37 if (error) 38 remove_files(dir,grp); 39 return error; 40 } 41 42 43 int sysfs_create_group(struct kobject * kobj, 44 const struct attribute_group * grp) 45 { 46 struct dentry * dir; 47 int error; 48 49 BUG_ON(!kobj || !kobj->dentry); 50 51 if (grp->name) { 52 error = sysfs_create_subdir(kobj,grp->name,&dir); 53 if (error) 54 return error; 55 } else 56 dir = kobj->dentry; 57 dir = dget(dir); 58 if ((error = create_files(dir,grp))) { 59 if (grp->name) 60 sysfs_remove_subdir(dir); 61 } 62 dput(dir); 63 return error; 64 } 65 66 void sysfs_remove_group(struct kobject * kobj, 67 const struct attribute_group * grp) 68 { 69 struct dentry * dir; 70 71 if (grp->name) 72 dir = lookup_one_len(grp->name, kobj->dentry, 73 strlen(grp->name)); 74 else 75 dir = dget(kobj->dentry); 76 77 remove_files(dir,grp); 78 if (grp->name) 79 sysfs_remove_subdir(dir); 80 /* release the ref. taken in this routine */ 81 dput(dir); 82 } 83 84 85 EXPORT_SYMBOL_GPL(sysfs_create_group); 86 EXPORT_SYMBOL_GPL(sysfs_remove_group); 87