2 * dir.c - Operations for sysfs directories.
8 #include <linux/mount.h>
9 #include <linux/module.h>
10 #include <linux/kobject.h>
11 #include <linux/namei.h>
12 #include <asm/semaphore.h>
15 DECLARE_RWSEM(sysfs_rename_sem
);
17 static void sysfs_d_iput(struct dentry
* dentry
, struct inode
* inode
)
19 struct sysfs_dirent
* sd
= dentry
->d_fsdata
;
22 BUG_ON(sd
->s_dentry
!= dentry
);
29 static struct dentry_operations sysfs_dentry_ops
= {
30 .d_iput
= sysfs_d_iput
,
34 * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
36 static struct sysfs_dirent
* sysfs_new_dirent(struct sysfs_dirent
* parent_sd
,
39 struct sysfs_dirent
* sd
;
41 sd
= kmem_cache_alloc(sysfs_dir_cachep
, GFP_KERNEL
);
45 memset(sd
, 0, sizeof(*sd
));
46 atomic_set(&sd
->s_count
, 1);
47 atomic_set(&sd
->s_event
, 1);
48 INIT_LIST_HEAD(&sd
->s_children
);
49 list_add(&sd
->s_sibling
, &parent_sd
->s_children
);
50 sd
->s_element
= element
;
57 * Return -EEXIST if there is already a sysfs element with the same name for
60 * called with parent inode's i_mutex held
62 int sysfs_dirent_exist(struct sysfs_dirent
*parent_sd
,
63 const unsigned char *new)
65 struct sysfs_dirent
* sd
;
67 list_for_each_entry(sd
, &parent_sd
->s_children
, s_sibling
) {
69 const unsigned char *existing
= sysfs_get_name(sd
);
70 if (strcmp(existing
, new))
81 int sysfs_make_dirent(struct sysfs_dirent
* parent_sd
, struct dentry
* dentry
,
82 void * element
, umode_t mode
, int type
)
84 struct sysfs_dirent
* sd
;
86 sd
= sysfs_new_dirent(parent_sd
, element
);
92 sd
->s_dentry
= dentry
;
94 dentry
->d_fsdata
= sysfs_get(sd
);
95 dentry
->d_op
= &sysfs_dentry_ops
;
101 static int init_dir(struct inode
* inode
)
103 inode
->i_op
= &sysfs_dir_inode_operations
;
104 inode
->i_fop
= &sysfs_dir_operations
;
106 /* directory inodes start off with i_nlink == 2 (for "." entry) */
111 static int init_file(struct inode
* inode
)
113 inode
->i_size
= PAGE_SIZE
;
114 inode
->i_fop
= &sysfs_file_operations
;
118 static int init_symlink(struct inode
* inode
)
120 inode
->i_op
= &sysfs_symlink_inode_operations
;
124 static int create_dir(struct kobject
* k
, struct dentry
* p
,
125 const char * n
, struct dentry
** d
)
128 umode_t mode
= S_IFDIR
| S_IRWXU
| S_IRUGO
| S_IXUGO
;
130 mutex_lock(&p
->d_inode
->i_mutex
);
131 *d
= lookup_one_len(n
, p
, strlen(n
));
133 if (sysfs_dirent_exist(p
->d_fsdata
, n
))
136 error
= sysfs_make_dirent(p
->d_fsdata
, *d
, k
, mode
,
139 error
= sysfs_create(*d
, mode
, init_dir
);
141 inc_nlink(p
->d_inode
);
142 (*d
)->d_op
= &sysfs_dentry_ops
;
146 if (error
&& (error
!= -EEXIST
)) {
147 struct sysfs_dirent
*sd
= (*d
)->d_fsdata
;
149 list_del_init(&sd
->s_sibling
);
157 mutex_unlock(&p
->d_inode
->i_mutex
);
162 int sysfs_create_subdir(struct kobject
* k
, const char * n
, struct dentry
** d
)
164 return create_dir(k
,k
->dentry
,n
,d
);
168 * sysfs_create_dir - create a directory for an object.
169 * @parent: parent parent object.
170 * @kobj: object we're creating directory for.
173 int sysfs_create_dir(struct kobject
* kobj
)
175 struct dentry
* dentry
= NULL
;
176 struct dentry
* parent
;
182 parent
= kobj
->parent
->dentry
;
183 else if (sysfs_mount
&& sysfs_mount
->mnt_sb
)
184 parent
= sysfs_mount
->mnt_sb
->s_root
;
188 error
= create_dir(kobj
,parent
,kobject_name(kobj
),&dentry
);
190 kobj
->dentry
= dentry
;
194 /* attaches attribute's sysfs_dirent to the dentry corresponding to the
197 static int sysfs_attach_attr(struct sysfs_dirent
* sd
, struct dentry
* dentry
)
199 struct attribute
* attr
= NULL
;
200 struct bin_attribute
* bin_attr
= NULL
;
201 int (* init
) (struct inode
*) = NULL
;
204 if (sd
->s_type
& SYSFS_KOBJ_BIN_ATTR
) {
205 bin_attr
= sd
->s_element
;
206 attr
= &bin_attr
->attr
;
208 attr
= sd
->s_element
;
212 dentry
->d_fsdata
= sysfs_get(sd
);
213 sd
->s_dentry
= dentry
;
214 error
= sysfs_create(dentry
, (attr
->mode
& S_IALLUGO
) | S_IFREG
, init
);
221 dentry
->d_inode
->i_size
= bin_attr
->size
;
222 dentry
->d_inode
->i_fop
= &bin_fops
;
224 dentry
->d_op
= &sysfs_dentry_ops
;
230 static int sysfs_attach_link(struct sysfs_dirent
* sd
, struct dentry
* dentry
)
234 dentry
->d_fsdata
= sysfs_get(sd
);
235 sd
->s_dentry
= dentry
;
236 err
= sysfs_create(dentry
, S_IFLNK
|S_IRWXUGO
, init_symlink
);
238 dentry
->d_op
= &sysfs_dentry_ops
;
246 static struct dentry
* sysfs_lookup(struct inode
*dir
, struct dentry
*dentry
,
247 struct nameidata
*nd
)
249 struct sysfs_dirent
* parent_sd
= dentry
->d_parent
->d_fsdata
;
250 struct sysfs_dirent
* sd
;
253 list_for_each_entry(sd
, &parent_sd
->s_children
, s_sibling
) {
254 if (sd
->s_type
& SYSFS_NOT_PINNED
) {
255 const unsigned char * name
= sysfs_get_name(sd
);
257 if (strcmp(name
, dentry
->d_name
.name
))
260 if (sd
->s_type
& SYSFS_KOBJ_LINK
)
261 err
= sysfs_attach_link(sd
, dentry
);
263 err
= sysfs_attach_attr(sd
, dentry
);
271 struct inode_operations sysfs_dir_inode_operations
= {
272 .lookup
= sysfs_lookup
,
273 .setattr
= sysfs_setattr
,
276 static void remove_dir(struct dentry
* d
)
278 struct dentry
* parent
= dget(d
->d_parent
);
279 struct sysfs_dirent
* sd
;
281 mutex_lock(&parent
->d_inode
->i_mutex
);
284 list_del_init(&sd
->s_sibling
);
287 simple_rmdir(parent
->d_inode
,d
);
289 pr_debug(" o %s removing done (%d)\n",d
->d_name
.name
,
290 atomic_read(&d
->d_count
));
292 mutex_unlock(&parent
->d_inode
->i_mutex
);
296 void sysfs_remove_subdir(struct dentry
* d
)
303 * sysfs_remove_dir - remove an object's directory.
306 * The only thing special about this is that we remove any files in
307 * the directory before we remove the directory, and we've inlined
308 * what used to be sysfs_rmdir() below, instead of calling separately.
311 void sysfs_remove_dir(struct kobject
* kobj
)
313 struct dentry
* dentry
= dget(kobj
->dentry
);
314 struct sysfs_dirent
* parent_sd
;
315 struct sysfs_dirent
* sd
, * tmp
;
320 pr_debug("sysfs %s: removing dir\n",dentry
->d_name
.name
);
321 mutex_lock(&dentry
->d_inode
->i_mutex
);
322 parent_sd
= dentry
->d_fsdata
;
323 list_for_each_entry_safe(sd
, tmp
, &parent_sd
->s_children
, s_sibling
) {
324 if (!sd
->s_element
|| !(sd
->s_type
& SYSFS_NOT_PINNED
))
326 list_del_init(&sd
->s_sibling
);
327 sysfs_drop_dentry(sd
, dentry
);
330 mutex_unlock(&dentry
->d_inode
->i_mutex
);
334 * Drop reference from dget() on entrance.
340 int sysfs_rename_dir(struct kobject
* kobj
, const char *new_name
)
343 struct dentry
* new_dentry
, * parent
;
345 if (!strcmp(kobject_name(kobj
), new_name
))
351 down_write(&sysfs_rename_sem
);
352 parent
= kobj
->parent
->dentry
;
354 mutex_lock(&parent
->d_inode
->i_mutex
);
356 new_dentry
= lookup_one_len(new_name
, parent
, strlen(new_name
));
357 if (!IS_ERR(new_dentry
)) {
358 if (!new_dentry
->d_inode
) {
359 error
= kobject_set_name(kobj
, "%s", new_name
);
361 d_add(new_dentry
, NULL
);
362 d_move(kobj
->dentry
, new_dentry
);
370 mutex_unlock(&parent
->d_inode
->i_mutex
);
371 up_write(&sysfs_rename_sem
);
376 int sysfs_move_dir(struct kobject
*kobj
, struct kobject
*new_parent
)
378 struct dentry
*old_parent_dentry
, *new_parent_dentry
, *new_dentry
;
379 struct sysfs_dirent
*new_parent_sd
, *sd
;
382 old_parent_dentry
= kobj
->parent
?
383 kobj
->parent
->dentry
: sysfs_mount
->mnt_sb
->s_root
;
384 new_parent_dentry
= new_parent
?
385 new_parent
->dentry
: sysfs_mount
->mnt_sb
->s_root
;
388 mutex_lock(&old_parent_dentry
->d_inode
->i_mutex
);
389 if (!mutex_trylock(&new_parent_dentry
->d_inode
->i_mutex
)) {
390 mutex_unlock(&old_parent_dentry
->d_inode
->i_mutex
);
394 new_parent_sd
= new_parent_dentry
->d_fsdata
;
395 sd
= kobj
->dentry
->d_fsdata
;
397 new_dentry
= lookup_one_len(kobj
->name
, new_parent_dentry
,
399 if (IS_ERR(new_dentry
)) {
400 error
= PTR_ERR(new_dentry
);
404 d_add(new_dentry
, NULL
);
405 d_move(kobj
->dentry
, new_dentry
);
408 /* Remove from old parent's list and insert into new parent's list. */
409 list_del_init(&sd
->s_sibling
);
410 list_add(&sd
->s_sibling
, &new_parent_sd
->s_children
);
413 mutex_unlock(&new_parent_dentry
->d_inode
->i_mutex
);
414 mutex_unlock(&old_parent_dentry
->d_inode
->i_mutex
);
419 static int sysfs_dir_open(struct inode
*inode
, struct file
*file
)
421 struct dentry
* dentry
= file
->f_path
.dentry
;
422 struct sysfs_dirent
* parent_sd
= dentry
->d_fsdata
;
424 mutex_lock(&dentry
->d_inode
->i_mutex
);
425 file
->private_data
= sysfs_new_dirent(parent_sd
, NULL
);
426 mutex_unlock(&dentry
->d_inode
->i_mutex
);
428 return file
->private_data
? 0 : -ENOMEM
;
432 static int sysfs_dir_close(struct inode
*inode
, struct file
*file
)
434 struct dentry
* dentry
= file
->f_path
.dentry
;
435 struct sysfs_dirent
* cursor
= file
->private_data
;
437 mutex_lock(&dentry
->d_inode
->i_mutex
);
438 list_del_init(&cursor
->s_sibling
);
439 mutex_unlock(&dentry
->d_inode
->i_mutex
);
441 release_sysfs_dirent(cursor
);
446 /* Relationship between s_mode and the DT_xxx types */
447 static inline unsigned char dt_type(struct sysfs_dirent
*sd
)
449 return (sd
->s_mode
>> 12) & 15;
452 static int sysfs_readdir(struct file
* filp
, void * dirent
, filldir_t filldir
)
454 struct dentry
*dentry
= filp
->f_path
.dentry
;
455 struct sysfs_dirent
* parent_sd
= dentry
->d_fsdata
;
456 struct sysfs_dirent
*cursor
= filp
->private_data
;
457 struct list_head
*p
, *q
= &cursor
->s_sibling
;
463 ino
= dentry
->d_inode
->i_ino
;
464 if (filldir(dirent
, ".", 1, i
, ino
, DT_DIR
) < 0)
470 ino
= parent_ino(dentry
);
471 if (filldir(dirent
, "..", 2, i
, ino
, DT_DIR
) < 0)
477 if (filp
->f_pos
== 2)
478 list_move(q
, &parent_sd
->s_children
);
480 for (p
=q
->next
; p
!= &parent_sd
->s_children
; p
=p
->next
) {
481 struct sysfs_dirent
*next
;
485 next
= list_entry(p
, struct sysfs_dirent
,
487 if (!next
->s_element
)
490 name
= sysfs_get_name(next
);
493 ino
= next
->s_dentry
->d_inode
->i_ino
;
495 ino
= iunique(sysfs_sb
, 2);
497 if (filldir(dirent
, name
, len
, filp
->f_pos
, ino
,
509 static loff_t
sysfs_dir_lseek(struct file
* file
, loff_t offset
, int origin
)
511 struct dentry
* dentry
= file
->f_path
.dentry
;
513 mutex_lock(&dentry
->d_inode
->i_mutex
);
516 offset
+= file
->f_pos
;
521 mutex_unlock(&file
->f_path
.dentry
->d_inode
->i_mutex
);
524 if (offset
!= file
->f_pos
) {
525 file
->f_pos
= offset
;
526 if (file
->f_pos
>= 2) {
527 struct sysfs_dirent
*sd
= dentry
->d_fsdata
;
528 struct sysfs_dirent
*cursor
= file
->private_data
;
530 loff_t n
= file
->f_pos
- 2;
532 list_del(&cursor
->s_sibling
);
533 p
= sd
->s_children
.next
;
534 while (n
&& p
!= &sd
->s_children
) {
535 struct sysfs_dirent
*next
;
536 next
= list_entry(p
, struct sysfs_dirent
,
542 list_add_tail(&cursor
->s_sibling
, p
);
545 mutex_unlock(&dentry
->d_inode
->i_mutex
);
549 const struct file_operations sysfs_dir_operations
= {
550 .open
= sysfs_dir_open
,
551 .release
= sysfs_dir_close
,
552 .llseek
= sysfs_dir_lseek
,
553 .read
= generic_read_dir
,
554 .readdir
= sysfs_readdir
,