[PATCH] Fix up 'linux-dvb' maintainers entry
[linux-2.6/history.git] / fs / sysfs / dir.c
blobebaf6c40671af75962c4c946f5ff8898f9ee3cd3
1 /*
2 * dir.c - Operations for sysfs directories.
3 */
5 #undef DEBUG
7 #include <linux/fs.h>
8 #include <linux/mount.h>
9 #include <linux/module.h>
10 #include <linux/kobject.h>
11 #include "sysfs.h"
13 static int init_dir(struct inode * inode)
15 inode->i_op = &simple_dir_inode_operations;
16 inode->i_fop = &simple_dir_operations;
18 /* directory inodes start off with i_nlink == 2 (for "." entry) */
19 inode->i_nlink++;
20 return 0;
24 static int create_dir(struct kobject * k, struct dentry * p,
25 const char * n, struct dentry ** d)
27 int error;
29 down(&p->d_inode->i_sem);
30 *d = sysfs_get_dentry(p,n);
31 if (!IS_ERR(*d)) {
32 error = sysfs_create(*d,
33 S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO,
34 init_dir);
35 if (!error) {
36 (*d)->d_fsdata = k;
37 p->d_inode->i_nlink++;
39 dput(*d);
40 } else
41 error = PTR_ERR(*d);
42 up(&p->d_inode->i_sem);
43 return error;
47 int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
49 return create_dir(k,k->dentry,n,d);
52 /**
53 * sysfs_create_dir - create a directory for an object.
54 * @parent: parent parent object.
55 * @kobj: object we're creating directory for.
58 int sysfs_create_dir(struct kobject * kobj)
60 struct dentry * dentry = NULL;
61 struct dentry * parent;
62 int error = 0;
64 if (!kobj)
65 return -EINVAL;
67 if (kobj->parent)
68 parent = kobj->parent->dentry;
69 else if (sysfs_mount && sysfs_mount->mnt_sb)
70 parent = sysfs_mount->mnt_sb->s_root;
71 else
72 return -EFAULT;
74 error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
75 if (!error)
76 kobj->dentry = dentry;
77 return error;
81 static void remove_dir(struct dentry * d)
83 struct dentry * parent = dget(d->d_parent);
84 down(&parent->d_inode->i_sem);
85 d_delete(d);
86 if (d->d_inode)
87 simple_rmdir(parent->d_inode,d);
89 pr_debug(" o %s removing done (%d)\n",d->d_name.name,
90 atomic_read(&d->d_count));
92 up(&parent->d_inode->i_sem);
93 dput(parent);
96 void sysfs_remove_subdir(struct dentry * d)
98 remove_dir(d);
103 * sysfs_remove_dir - remove an object's directory.
104 * @kobj: object.
106 * The only thing special about this is that we remove any files in
107 * the directory before we remove the directory, and we've inlined
108 * what used to be sysfs_rmdir() below, instead of calling separately.
111 void sysfs_remove_dir(struct kobject * kobj)
113 struct list_head * node;
114 struct dentry * dentry = dget(kobj->dentry);
116 if (!dentry)
117 return;
119 pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
120 down(&dentry->d_inode->i_sem);
122 spin_lock(&dcache_lock);
123 node = dentry->d_subdirs.next;
124 while (node != &dentry->d_subdirs) {
125 struct dentry * d = list_entry(node,struct dentry,d_child);
126 list_del_init(node);
128 pr_debug(" o %s (%d): ",d->d_name.name,atomic_read(&d->d_count));
129 if (d->d_inode) {
130 d = dget_locked(d);
131 pr_debug("removing");
134 * Unlink and unhash.
136 spin_unlock(&dcache_lock);
137 d_delete(d);
138 simple_unlink(dentry->d_inode,d);
139 dput(d);
140 spin_lock(&dcache_lock);
142 pr_debug(" done\n");
143 node = dentry->d_subdirs.next;
145 list_del_init(&dentry->d_child);
146 spin_unlock(&dcache_lock);
147 up(&dentry->d_inode->i_sem);
149 remove_dir(dentry);
151 * Drop reference from dget() on entrance.
153 dput(dentry);
156 void sysfs_rename_dir(struct kobject * kobj, const char *new_name)
158 struct dentry * new_dentry, * parent;
160 if (!strcmp(kobject_name(kobj), new_name))
161 return;
163 if (!kobj->parent)
164 return;
166 parent = kobj->parent->dentry;
168 down(&parent->d_inode->i_sem);
170 new_dentry = sysfs_get_dentry(parent, new_name);
171 d_move(kobj->dentry, new_dentry);
172 kobject_set_name(kobj,new_name);
173 up(&parent->d_inode->i_sem);
176 EXPORT_SYMBOL(sysfs_create_dir);
177 EXPORT_SYMBOL(sysfs_remove_dir);
178 EXPORT_SYMBOL(sysfs_rename_dir);