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