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
)
30 down(&p
->d_inode
->i_sem
);
31 *d
= sysfs_get_dentry(p
,n
);
33 error
= sysfs_create(*d
,
34 S_IFDIR
| S_IRWXU
| S_IRUGO
| S_IXUGO
,
38 p
->d_inode
->i_nlink
++;
43 up(&p
->d_inode
->i_sem
);
48 int sysfs_create_subdir(struct kobject
* k
, const char * n
, struct dentry
** d
)
50 return create_dir(k
,k
->dentry
,n
,d
);
54 * sysfs_create_dir - create a directory for an object.
55 * @parent: parent parent object.
56 * @kobj: object we're creating directory for.
59 int sysfs_create_dir(struct kobject
* kobj
)
61 struct dentry
* dentry
= NULL
;
62 struct dentry
* parent
;
69 parent
= kobj
->parent
->dentry
;
70 else if (sysfs_mount
&& sysfs_mount
->mnt_sb
)
71 parent
= sysfs_mount
->mnt_sb
->s_root
;
75 error
= create_dir(kobj
,parent
,kobject_name(kobj
),&dentry
);
77 kobj
->dentry
= dentry
;
82 static void remove_dir(struct dentry
* d
)
84 struct dentry
* parent
= dget(d
->d_parent
);
85 down(&parent
->d_inode
->i_sem
);
88 simple_rmdir(parent
->d_inode
,d
);
90 pr_debug(" o %s removing done (%d)\n",d
->d_name
.name
,
91 atomic_read(&d
->d_count
));
93 up(&parent
->d_inode
->i_sem
);
97 void sysfs_remove_subdir(struct dentry
* d
)
104 * sysfs_remove_dir - remove an object's directory.
107 * The only thing special about this is that we remove any files in
108 * the directory before we remove the directory, and we've inlined
109 * what used to be sysfs_rmdir() below, instead of calling separately.
112 void sysfs_remove_dir(struct kobject
* kobj
)
114 struct list_head
* node
;
115 struct dentry
* dentry
= dget(kobj
->dentry
);
120 pr_debug("sysfs %s: removing dir\n",dentry
->d_name
.name
);
121 down(&dentry
->d_inode
->i_sem
);
123 spin_lock(&dcache_lock
);
125 node
= dentry
->d_subdirs
.next
;
126 while (node
!= &dentry
->d_subdirs
) {
127 struct dentry
* d
= list_entry(node
,struct dentry
,d_child
);
130 pr_debug(" o %s (%d): ",d
->d_name
.name
,atomic_read(&d
->d_count
));
131 if (!d_unhashed(d
) && (d
->d_inode
)) {
133 pr_debug("removing");
139 spin_unlock(&dcache_lock
);
140 /* release the target kobject in case of
143 if (S_ISLNK(d
->d_inode
->i_mode
))
144 kobject_put(d
->d_fsdata
);
146 simple_unlink(dentry
->d_inode
,d
);
149 spin_lock(&dcache_lock
);
150 /* re-acquired dcache_lock, need to restart */
154 spin_unlock(&dcache_lock
);
155 up(&dentry
->d_inode
->i_sem
);
159 * Drop reference from dget() on entrance.
164 int sysfs_rename_dir(struct kobject
* kobj
, const char *new_name
)
167 struct dentry
* new_dentry
, * parent
;
169 if (!strcmp(kobject_name(kobj
), new_name
))
175 down_write(&sysfs_rename_sem
);
176 parent
= kobj
->parent
->dentry
;
178 down(&parent
->d_inode
->i_sem
);
180 new_dentry
= sysfs_get_dentry(parent
, new_name
);
181 if (!IS_ERR(new_dentry
)) {
182 if (!new_dentry
->d_inode
) {
183 error
= kobject_set_name(kobj
,new_name
);
185 d_move(kobj
->dentry
, new_dentry
);
189 up(&parent
->d_inode
->i_sem
);
190 up_write(&sysfs_rename_sem
);
195 EXPORT_SYMBOL(sysfs_create_dir
);
196 EXPORT_SYMBOL(sysfs_remove_dir
);
197 EXPORT_SYMBOL(sysfs_rename_dir
);