[PATCH] autofs4: fix infamous "Busy inodes after umount ..." message
[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 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);