2 * dir.c - Operations for sysfs directories.
8 #include <linux/mount.h>
9 #include <linux/module.h>
10 #include <linux/kobject.h>
13 DECLARE_RWSEM(sysfs_rename_sem);
15 static int init_dir(struct inode * inode)
17 inode->i_op = &simple_dir_inode_operations;
18 inode->i_fop = &simple_dir_operations;
20 /* directory inodes start off with i_nlink == 2 (for "." entry) */
26 static int create_dir(struct kobject * k, struct dentry * p,
27 const char * n, struct dentry ** d)
31 down(&p->d_inode->i_sem);
32 *d = sysfs_get_dentry(p,n);
34 error = sysfs_create(*d,
35 S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO,
39 p->d_inode->i_nlink++;
44 up(&p->d_inode->i_sem);
49 int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
51 return create_dir(k,k->dentry,n,d);
55 * sysfs_create_dir - create a directory for an object.
56 * @parent: parent parent object.
57 * @kobj: object we're creating directory for.
60 int sysfs_create_dir(struct kobject * kobj)
62 struct dentry * dentry = NULL;
63 struct dentry * parent;
70 parent = kobj->parent->dentry;
71 else if (sysfs_mount && sysfs_mount->mnt_sb)
72 parent = sysfs_mount->mnt_sb->s_root;
76 error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
78 kobj->dentry = dentry;
83 static void remove_dir(struct dentry * d)
85 struct dentry * parent = dget(d->d_parent);
86 down(&parent->d_inode->i_sem);
89 simple_rmdir(parent->d_inode,d);
91 pr_debug(" o %s removing done (%d)\n",d->d_name.name,
92 atomic_read(&d->d_count));
94 up(&parent->d_inode->i_sem);
98 void sysfs_remove_subdir(struct dentry * d)
105 * sysfs_remove_dir - remove an object's directory.
108 * The only thing special about this is that we remove any files in
109 * the directory before we remove the directory, and we've inlined
110 * what used to be sysfs_rmdir() below, instead of calling separately.
113 void sysfs_remove_dir(struct kobject * kobj)
115 struct list_head * node;
116 struct dentry * dentry = dget(kobj->dentry);
121 pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
122 down(&dentry->d_inode->i_sem);
124 spin_lock(&dcache_lock);
126 node = dentry->d_subdirs.next;
127 while (node != &dentry->d_subdirs) {
128 struct dentry * d = list_entry(node,struct dentry,d_child);
131 pr_debug(" o %s (%d): ",d->d_name.name,atomic_read(&d->d_count));
132 if (!d_unhashed(d) && (d->d_inode)) {
134 pr_debug("removing");
140 spin_unlock(&dcache_lock);
141 /* release the target kobject in case of
144 if (S_ISLNK(d->d_inode->i_mode))
145 kobject_put(d->d_fsdata);
147 simple_unlink(dentry->d_inode,d);
150 spin_lock(&dcache_lock);
151 /* re-acquired dcache_lock, need to restart */
155 spin_unlock(&dcache_lock);
156 up(&dentry->d_inode->i_sem);
160 * Drop reference from dget() on entrance.
165 int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
168 struct dentry * new_dentry, * parent;
170 if (!strcmp(kobject_name(kobj), new_name))
176 down_write(&sysfs_rename_sem);
177 parent = kobj->parent->dentry;
179 down(&parent->d_inode->i_sem);
181 new_dentry = sysfs_get_dentry(parent, new_name);
182 if (!IS_ERR(new_dentry)) {
183 if (!new_dentry->d_inode) {
184 error = kobject_set_name(kobj,new_name);
186 d_move(kobj->dentry, new_dentry);
190 up(&parent->d_inode->i_sem);
191 up_write(&sysfs_rename_sem);
196 EXPORT_SYMBOL(sysfs_create_dir);
197 EXPORT_SYMBOL(sysfs_remove_dir);
198 EXPORT_SYMBOL(sysfs_rename_dir);