xref: /linux/fs/sysfs/dir.c (revision bf74b964775009071cf12f9d59d4dd5e388fbe0b)
1 /*
2  * dir.c - Operations for sysfs directories.
3  */
4 
5 #undef DEBUG
6 
7 #include <linux/fs.h>
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>
13 #include "sysfs.h"
14 
15 DECLARE_RWSEM(sysfs_rename_sem);
16 spinlock_t sysfs_lock = SPIN_LOCK_UNLOCKED;
17 
18 static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
19 {
20 	struct sysfs_dirent * sd = dentry->d_fsdata;
21 
22 	if (sd) {
23 		/* sd->s_dentry is protected with sysfs_lock.  This
24 		 * allows sysfs_drop_dentry() to dereference it.
25 		 */
26 		spin_lock(&sysfs_lock);
27 
28 		/* The dentry might have been deleted or another
29 		 * lookup could have happened updating sd->s_dentry to
30 		 * point the new dentry.  Ignore if it isn't pointing
31 		 * to this dentry.
32 		 */
33 		if (sd->s_dentry == dentry)
34 			sd->s_dentry = NULL;
35 		spin_unlock(&sysfs_lock);
36 		sysfs_put(sd);
37 	}
38 	iput(inode);
39 }
40 
41 static struct dentry_operations sysfs_dentry_ops = {
42 	.d_iput		= sysfs_d_iput,
43 };
44 
45 static unsigned int sysfs_inode_counter;
46 ino_t sysfs_get_inum(void)
47 {
48 	if (unlikely(sysfs_inode_counter < 3))
49 		sysfs_inode_counter = 3;
50 	return sysfs_inode_counter++;
51 }
52 
53 /*
54  * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
55  */
56 static struct sysfs_dirent * __sysfs_new_dirent(void * element)
57 {
58 	struct sysfs_dirent * sd;
59 
60 	sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL);
61 	if (!sd)
62 		return NULL;
63 
64 	sd->s_ino = sysfs_get_inum();
65 	atomic_set(&sd->s_count, 1);
66 	atomic_set(&sd->s_event, 1);
67 	INIT_LIST_HEAD(&sd->s_children);
68 	INIT_LIST_HEAD(&sd->s_sibling);
69 	sd->s_element = element;
70 
71 	return sd;
72 }
73 
74 static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd,
75 			      struct sysfs_dirent *sd)
76 {
77 	if (sd)
78 		list_add(&sd->s_sibling, &parent_sd->s_children);
79 }
80 
81 static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent *parent_sd,
82 						void * element)
83 {
84 	struct sysfs_dirent *sd;
85 	sd = __sysfs_new_dirent(element);
86 	__sysfs_list_dirent(parent_sd, sd);
87 	return sd;
88 }
89 
90 /*
91  *
92  * Return -EEXIST if there is already a sysfs element with the same name for
93  * the same parent.
94  *
95  * called with parent inode's i_mutex held
96  */
97 int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
98 			  const unsigned char *new)
99 {
100 	struct sysfs_dirent * sd;
101 
102 	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
103 		if (sd->s_element) {
104 			const unsigned char *existing = sysfs_get_name(sd);
105 			if (strcmp(existing, new))
106 				continue;
107 			else
108 				return -EEXIST;
109 		}
110 	}
111 
112 	return 0;
113 }
114 
115 
116 static struct sysfs_dirent *
117 __sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
118 {
119 	struct sysfs_dirent * sd;
120 
121 	sd = __sysfs_new_dirent(element);
122 	if (!sd)
123 		goto out;
124 
125 	sd->s_mode = mode;
126 	sd->s_type = type;
127 	sd->s_dentry = dentry;
128 	if (dentry) {
129 		dentry->d_fsdata = sysfs_get(sd);
130 		dentry->d_op = &sysfs_dentry_ops;
131 	}
132 
133 out:
134 	return sd;
135 }
136 
137 int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
138 			void * element, umode_t mode, int type)
139 {
140 	struct sysfs_dirent *sd;
141 
142 	sd = __sysfs_make_dirent(dentry, element, mode, type);
143 	__sysfs_list_dirent(parent_sd, sd);
144 
145 	return sd ? 0 : -ENOMEM;
146 }
147 
148 static int init_dir(struct inode * inode)
149 {
150 	inode->i_op = &sysfs_dir_inode_operations;
151 	inode->i_fop = &sysfs_dir_operations;
152 
153 	/* directory inodes start off with i_nlink == 2 (for "." entry) */
154 	inc_nlink(inode);
155 	return 0;
156 }
157 
158 static int init_file(struct inode * inode)
159 {
160 	inode->i_size = PAGE_SIZE;
161 	inode->i_fop = &sysfs_file_operations;
162 	return 0;
163 }
164 
165 static int init_symlink(struct inode * inode)
166 {
167 	inode->i_op = &sysfs_symlink_inode_operations;
168 	return 0;
169 }
170 
171 static int create_dir(struct kobject * k, struct dentry * p,
172 		      const char * n, struct dentry ** d)
173 {
174 	int error;
175 	umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
176 
177 	mutex_lock(&p->d_inode->i_mutex);
178 	*d = lookup_one_len(n, p, strlen(n));
179 	if (!IS_ERR(*d)) {
180  		if (sysfs_dirent_exist(p->d_fsdata, n))
181   			error = -EEXIST;
182   		else
183 			error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
184 								SYSFS_DIR);
185 		if (!error) {
186 			error = sysfs_create(*d, mode, init_dir);
187 			if (!error) {
188 				inc_nlink(p->d_inode);
189 				(*d)->d_op = &sysfs_dentry_ops;
190 				d_rehash(*d);
191 			}
192 		}
193 		if (error && (error != -EEXIST)) {
194 			struct sysfs_dirent *sd = (*d)->d_fsdata;
195 			if (sd) {
196  				list_del_init(&sd->s_sibling);
197 				sysfs_put(sd);
198 			}
199 			d_drop(*d);
200 		}
201 		dput(*d);
202 	} else
203 		error = PTR_ERR(*d);
204 	mutex_unlock(&p->d_inode->i_mutex);
205 	return error;
206 }
207 
208 
209 int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
210 {
211 	return create_dir(k,k->dentry,n,d);
212 }
213 
214 /**
215  *	sysfs_create_dir - create a directory for an object.
216  *	@kobj:		object we're creating directory for.
217  *	@shadow_parent:	parent parent object.
218  */
219 
220 int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent)
221 {
222 	struct dentry * dentry = NULL;
223 	struct dentry * parent;
224 	int error = 0;
225 
226 	BUG_ON(!kobj);
227 
228 	if (shadow_parent)
229 		parent = shadow_parent;
230 	else if (kobj->parent)
231 		parent = kobj->parent->dentry;
232 	else if (sysfs_mount && sysfs_mount->mnt_sb)
233 		parent = sysfs_mount->mnt_sb->s_root;
234 	else
235 		return -EFAULT;
236 
237 	error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
238 	if (!error)
239 		kobj->dentry = dentry;
240 	return error;
241 }
242 
243 /* attaches attribute's sysfs_dirent to the dentry corresponding to the
244  * attribute file
245  */
246 static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry)
247 {
248 	struct attribute * attr = NULL;
249 	struct bin_attribute * bin_attr = NULL;
250 	int (* init) (struct inode *) = NULL;
251 	int error = 0;
252 
253         if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) {
254                 bin_attr = sd->s_element;
255                 attr = &bin_attr->attr;
256         } else {
257                 attr = sd->s_element;
258                 init = init_file;
259         }
260 
261 	dentry->d_fsdata = sysfs_get(sd);
262 	/* protect sd->s_dentry against sysfs_d_iput */
263 	spin_lock(&sysfs_lock);
264 	sd->s_dentry = dentry;
265 	spin_unlock(&sysfs_lock);
266 	error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init);
267 	if (error) {
268 		sysfs_put(sd);
269 		return error;
270 	}
271 
272         if (bin_attr) {
273 		dentry->d_inode->i_size = bin_attr->size;
274 		dentry->d_inode->i_fop = &bin_fops;
275 	}
276 	dentry->d_op = &sysfs_dentry_ops;
277 	d_rehash(dentry);
278 
279 	return 0;
280 }
281 
282 static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry)
283 {
284 	int err = 0;
285 
286 	dentry->d_fsdata = sysfs_get(sd);
287 	/* protect sd->s_dentry against sysfs_d_iput */
288 	spin_lock(&sysfs_lock);
289 	sd->s_dentry = dentry;
290 	spin_unlock(&sysfs_lock);
291 	err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
292 	if (!err) {
293 		dentry->d_op = &sysfs_dentry_ops;
294 		d_rehash(dentry);
295 	} else
296 		sysfs_put(sd);
297 
298 	return err;
299 }
300 
301 static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
302 				struct nameidata *nd)
303 {
304 	struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
305 	struct sysfs_dirent * sd;
306 	int err = 0;
307 
308 	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
309 		if (sd->s_type & SYSFS_NOT_PINNED) {
310 			const unsigned char * name = sysfs_get_name(sd);
311 
312 			if (strcmp(name, dentry->d_name.name))
313 				continue;
314 
315 			if (sd->s_type & SYSFS_KOBJ_LINK)
316 				err = sysfs_attach_link(sd, dentry);
317 			else
318 				err = sysfs_attach_attr(sd, dentry);
319 			break;
320 		}
321 	}
322 
323 	return ERR_PTR(err);
324 }
325 
326 const struct inode_operations sysfs_dir_inode_operations = {
327 	.lookup		= sysfs_lookup,
328 	.setattr	= sysfs_setattr,
329 };
330 
331 static void remove_dir(struct dentry * d)
332 {
333 	struct dentry * parent = dget(d->d_parent);
334 	struct sysfs_dirent * sd;
335 
336 	mutex_lock(&parent->d_inode->i_mutex);
337 	d_delete(d);
338 	sd = d->d_fsdata;
339  	list_del_init(&sd->s_sibling);
340 	sysfs_put(sd);
341 	if (d->d_inode)
342 		simple_rmdir(parent->d_inode,d);
343 
344 	pr_debug(" o %s removing done (%d)\n",d->d_name.name,
345 		 atomic_read(&d->d_count));
346 
347 	mutex_unlock(&parent->d_inode->i_mutex);
348 	dput(parent);
349 }
350 
351 void sysfs_remove_subdir(struct dentry * d)
352 {
353 	remove_dir(d);
354 }
355 
356 
357 static void __sysfs_remove_dir(struct dentry *dentry)
358 {
359 	struct sysfs_dirent * parent_sd;
360 	struct sysfs_dirent * sd, * tmp;
361 
362 	dget(dentry);
363 	if (!dentry)
364 		return;
365 
366 	pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
367 	mutex_lock(&dentry->d_inode->i_mutex);
368 	parent_sd = dentry->d_fsdata;
369 	list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
370 		if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED))
371 			continue;
372 		list_del_init(&sd->s_sibling);
373 		sysfs_drop_dentry(sd, dentry);
374 		sysfs_put(sd);
375 	}
376 	mutex_unlock(&dentry->d_inode->i_mutex);
377 
378 	remove_dir(dentry);
379 	/**
380 	 * Drop reference from dget() on entrance.
381 	 */
382 	dput(dentry);
383 }
384 
385 /**
386  *	sysfs_remove_dir - remove an object's directory.
387  *	@kobj:	object.
388  *
389  *	The only thing special about this is that we remove any files in
390  *	the directory before we remove the directory, and we've inlined
391  *	what used to be sysfs_rmdir() below, instead of calling separately.
392  */
393 
394 void sysfs_remove_dir(struct kobject * kobj)
395 {
396 	__sysfs_remove_dir(kobj->dentry);
397 	kobj->dentry = NULL;
398 }
399 
400 int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent,
401 		     const char *new_name)
402 {
403 	int error = 0;
404 	struct dentry * new_dentry;
405 
406 	if (!new_parent)
407 		return -EFAULT;
408 
409 	down_write(&sysfs_rename_sem);
410 	mutex_lock(&new_parent->d_inode->i_mutex);
411 
412 	new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name));
413 	if (!IS_ERR(new_dentry)) {
414 		/* By allowing two different directories with the
415 		 * same d_parent we allow this routine to move
416 		 * between different shadows of the same directory
417 		 */
418 		if (kobj->dentry->d_parent->d_inode != new_parent->d_inode)
419 			return -EINVAL;
420 		else if (new_dentry->d_parent->d_inode != new_parent->d_inode)
421 			error = -EINVAL;
422 		else if (new_dentry == kobj->dentry)
423 			error = -EINVAL;
424 		else if (!new_dentry->d_inode) {
425 			error = kobject_set_name(kobj, "%s", new_name);
426 			if (!error) {
427 				struct sysfs_dirent *sd, *parent_sd;
428 
429 				d_add(new_dentry, NULL);
430 				d_move(kobj->dentry, new_dentry);
431 
432 				sd = kobj->dentry->d_fsdata;
433 				parent_sd = new_parent->d_fsdata;
434 
435 				list_del_init(&sd->s_sibling);
436 				list_add(&sd->s_sibling, &parent_sd->s_children);
437 			}
438 			else
439 				d_drop(new_dentry);
440 		} else
441 			error = -EEXIST;
442 		dput(new_dentry);
443 	}
444 	mutex_unlock(&new_parent->d_inode->i_mutex);
445 	up_write(&sysfs_rename_sem);
446 
447 	return error;
448 }
449 
450 int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
451 {
452 	struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry;
453 	struct sysfs_dirent *new_parent_sd, *sd;
454 	int error;
455 
456 	old_parent_dentry = kobj->parent ?
457 		kobj->parent->dentry : sysfs_mount->mnt_sb->s_root;
458 	new_parent_dentry = new_parent ?
459 		new_parent->dentry : sysfs_mount->mnt_sb->s_root;
460 
461 	if (old_parent_dentry->d_inode == new_parent_dentry->d_inode)
462 		return 0;	/* nothing to move */
463 again:
464 	mutex_lock(&old_parent_dentry->d_inode->i_mutex);
465 	if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) {
466 		mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
467 		goto again;
468 	}
469 
470 	new_parent_sd = new_parent_dentry->d_fsdata;
471 	sd = kobj->dentry->d_fsdata;
472 
473 	new_dentry = lookup_one_len(kobj->name, new_parent_dentry,
474 				    strlen(kobj->name));
475 	if (IS_ERR(new_dentry)) {
476 		error = PTR_ERR(new_dentry);
477 		goto out;
478 	} else
479 		error = 0;
480 	d_add(new_dentry, NULL);
481 	d_move(kobj->dentry, new_dentry);
482 	dput(new_dentry);
483 
484 	/* Remove from old parent's list and insert into new parent's list. */
485 	list_del_init(&sd->s_sibling);
486 	list_add(&sd->s_sibling, &new_parent_sd->s_children);
487 
488 out:
489 	mutex_unlock(&new_parent_dentry->d_inode->i_mutex);
490 	mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
491 
492 	return error;
493 }
494 
495 static int sysfs_dir_open(struct inode *inode, struct file *file)
496 {
497 	struct dentry * dentry = file->f_path.dentry;
498 	struct sysfs_dirent * parent_sd = dentry->d_fsdata;
499 
500 	mutex_lock(&dentry->d_inode->i_mutex);
501 	file->private_data = sysfs_new_dirent(parent_sd, NULL);
502 	mutex_unlock(&dentry->d_inode->i_mutex);
503 
504 	return file->private_data ? 0 : -ENOMEM;
505 
506 }
507 
508 static int sysfs_dir_close(struct inode *inode, struct file *file)
509 {
510 	struct dentry * dentry = file->f_path.dentry;
511 	struct sysfs_dirent * cursor = file->private_data;
512 
513 	mutex_lock(&dentry->d_inode->i_mutex);
514 	list_del_init(&cursor->s_sibling);
515 	mutex_unlock(&dentry->d_inode->i_mutex);
516 
517 	release_sysfs_dirent(cursor);
518 
519 	return 0;
520 }
521 
522 /* Relationship between s_mode and the DT_xxx types */
523 static inline unsigned char dt_type(struct sysfs_dirent *sd)
524 {
525 	return (sd->s_mode >> 12) & 15;
526 }
527 
528 static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
529 {
530 	struct dentry *dentry = filp->f_path.dentry;
531 	struct sysfs_dirent * parent_sd = dentry->d_fsdata;
532 	struct sysfs_dirent *cursor = filp->private_data;
533 	struct list_head *p, *q = &cursor->s_sibling;
534 	ino_t ino;
535 	int i = filp->f_pos;
536 
537 	switch (i) {
538 		case 0:
539 			ino = parent_sd->s_ino;
540 			if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
541 				break;
542 			filp->f_pos++;
543 			i++;
544 			/* fallthrough */
545 		case 1:
546 			ino = parent_ino(dentry);
547 			if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
548 				break;
549 			filp->f_pos++;
550 			i++;
551 			/* fallthrough */
552 		default:
553 			if (filp->f_pos == 2)
554 				list_move(q, &parent_sd->s_children);
555 
556 			for (p=q->next; p!= &parent_sd->s_children; p=p->next) {
557 				struct sysfs_dirent *next;
558 				const char * name;
559 				int len;
560 
561 				next = list_entry(p, struct sysfs_dirent,
562 						   s_sibling);
563 				if (!next->s_element)
564 					continue;
565 
566 				name = sysfs_get_name(next);
567 				len = strlen(name);
568 				ino = next->s_ino;
569 
570 				if (filldir(dirent, name, len, filp->f_pos, ino,
571 						 dt_type(next)) < 0)
572 					return 0;
573 
574 				list_move(q, p);
575 				p = q;
576 				filp->f_pos++;
577 			}
578 	}
579 	return 0;
580 }
581 
582 static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
583 {
584 	struct dentry * dentry = file->f_path.dentry;
585 
586 	mutex_lock(&dentry->d_inode->i_mutex);
587 	switch (origin) {
588 		case 1:
589 			offset += file->f_pos;
590 		case 0:
591 			if (offset >= 0)
592 				break;
593 		default:
594 			mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
595 			return -EINVAL;
596 	}
597 	if (offset != file->f_pos) {
598 		file->f_pos = offset;
599 		if (file->f_pos >= 2) {
600 			struct sysfs_dirent *sd = dentry->d_fsdata;
601 			struct sysfs_dirent *cursor = file->private_data;
602 			struct list_head *p;
603 			loff_t n = file->f_pos - 2;
604 
605 			list_del(&cursor->s_sibling);
606 			p = sd->s_children.next;
607 			while (n && p != &sd->s_children) {
608 				struct sysfs_dirent *next;
609 				next = list_entry(p, struct sysfs_dirent,
610 						   s_sibling);
611 				if (next->s_element)
612 					n--;
613 				p = p->next;
614 			}
615 			list_add_tail(&cursor->s_sibling, p);
616 		}
617 	}
618 	mutex_unlock(&dentry->d_inode->i_mutex);
619 	return offset;
620 }
621 
622 
623 /**
624  *	sysfs_make_shadowed_dir - Setup so a directory can be shadowed
625  *	@kobj:	object we're creating shadow of.
626  */
627 
628 int sysfs_make_shadowed_dir(struct kobject *kobj,
629 	void * (*follow_link)(struct dentry *, struct nameidata *))
630 {
631 	struct inode *inode;
632 	struct inode_operations *i_op;
633 
634 	inode = kobj->dentry->d_inode;
635 	if (inode->i_op != &sysfs_dir_inode_operations)
636 		return -EINVAL;
637 
638 	i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
639 	if (!i_op)
640 		return -ENOMEM;
641 
642 	memcpy(i_op, &sysfs_dir_inode_operations, sizeof(*i_op));
643 	i_op->follow_link = follow_link;
644 
645 	/* Locking of inode->i_op?
646 	 * Since setting i_op is a single word write and they
647 	 * are atomic we should be ok here.
648 	 */
649 	inode->i_op = i_op;
650 	return 0;
651 }
652 
653 /**
654  *	sysfs_create_shadow_dir - create a shadow directory for an object.
655  *	@kobj:	object we're creating directory for.
656  *
657  *	sysfs_make_shadowed_dir must already have been called on this
658  *	directory.
659  */
660 
661 struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
662 {
663 	struct sysfs_dirent *sd;
664 	struct dentry *parent, *dir, *shadow;
665 	struct inode *inode;
666 
667 	dir = kobj->dentry;
668 	inode = dir->d_inode;
669 	parent = dir->d_parent;
670 	shadow = ERR_PTR(-EINVAL);
671 	if (!sysfs_is_shadowed_inode(inode))
672 		goto out;
673 
674 	shadow = d_alloc(parent, &dir->d_name);
675 	if (!shadow)
676 		goto nomem;
677 
678 	sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR);
679 	if (!sd)
680 		goto nomem;
681 
682 	d_instantiate(shadow, igrab(inode));
683 	inc_nlink(inode);
684 	inc_nlink(parent->d_inode);
685 	shadow->d_op = &sysfs_dentry_ops;
686 
687 	dget(shadow);		/* Extra count - pin the dentry in core */
688 
689 out:
690 	return shadow;
691 nomem:
692 	dput(shadow);
693 	shadow = ERR_PTR(-ENOMEM);
694 	goto out;
695 }
696 
697 /**
698  *	sysfs_remove_shadow_dir - remove an object's directory.
699  *	@shadow: dentry of shadow directory
700  *
701  *	The only thing special about this is that we remove any files in
702  *	the directory before we remove the directory, and we've inlined
703  *	what used to be sysfs_rmdir() below, instead of calling separately.
704  */
705 
706 void sysfs_remove_shadow_dir(struct dentry *shadow)
707 {
708 	__sysfs_remove_dir(shadow);
709 }
710 
711 const struct file_operations sysfs_dir_operations = {
712 	.open		= sysfs_dir_open,
713 	.release	= sysfs_dir_close,
714 	.llseek		= sysfs_dir_lseek,
715 	.read		= generic_read_dir,
716 	.readdir	= sysfs_readdir,
717 };
718