Merge branch 'fixes-jgarzik' of git://git.kernel.org/pub/scm/linux/kernel/git/linvill...
[linux-2.6] / fs / sysfs / group.c
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);