aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r--fs/sysfs/dir.c350
1 files changed, 222 insertions, 128 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 4d83cedb9fcb..5e73d6626e50 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -26,21 +26,21 @@
26#include "sysfs.h" 26#include "sysfs.h"
27 27
28DEFINE_MUTEX(sysfs_mutex); 28DEFINE_MUTEX(sysfs_mutex);
29DEFINE_SPINLOCK(sysfs_assoc_lock); 29DEFINE_SPINLOCK(sysfs_symlink_target_lock);
30 30
31#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb); 31#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb)
32 32
33static DEFINE_SPINLOCK(sysfs_ino_lock); 33static DEFINE_SPINLOCK(sysfs_ino_lock);
34static DEFINE_IDA(sysfs_ino_ida); 34static DEFINE_IDA(sysfs_ino_ida);
35 35
36/** 36/**
37 * sysfs_name_hash 37 * sysfs_name_hash
38 * @ns: Namespace tag to hash
39 * @name: Null terminated string to hash 38 * @name: Null terminated string to hash
39 * @ns: Namespace tag to hash
40 * 40 *
41 * Returns 31 bit hash of ns + name (so it fits in an off_t ) 41 * Returns 31 bit hash of ns + name (so it fits in an off_t )
42 */ 42 */
43static unsigned int sysfs_name_hash(const void *ns, const char *name) 43static unsigned int sysfs_name_hash(const char *name, const void *ns)
44{ 44{
45 unsigned long hash = init_name_hash(); 45 unsigned long hash = init_name_hash();
46 unsigned int len = strlen(name); 46 unsigned int len = strlen(name);
@@ -56,8 +56,8 @@ static unsigned int sysfs_name_hash(const void *ns, const char *name)
56 return hash; 56 return hash;
57} 57}
58 58
59static int sysfs_name_compare(unsigned int hash, const void *ns, 59static int sysfs_name_compare(unsigned int hash, const char *name,
60 const char *name, const struct sysfs_dirent *sd) 60 const void *ns, const struct sysfs_dirent *sd)
61{ 61{
62 if (hash != sd->s_hash) 62 if (hash != sd->s_hash)
63 return hash - sd->s_hash; 63 return hash - sd->s_hash;
@@ -69,7 +69,7 @@ static int sysfs_name_compare(unsigned int hash, const void *ns,
69static int sysfs_sd_compare(const struct sysfs_dirent *left, 69static int sysfs_sd_compare(const struct sysfs_dirent *left,
70 const struct sysfs_dirent *right) 70 const struct sysfs_dirent *right)
71{ 71{
72 return sysfs_name_compare(left->s_hash, left->s_ns, left->s_name, 72 return sysfs_name_compare(left->s_hash, left->s_name, left->s_ns,
73 right); 73 right);
74} 74}
75 75
@@ -132,24 +132,6 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
132 rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children); 132 rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children);
133} 133}
134 134
135#ifdef CONFIG_DEBUG_LOCK_ALLOC
136
137/* Test for attributes that want to ignore lockdep for read-locking */
138static bool ignore_lockdep(struct sysfs_dirent *sd)
139{
140 return sysfs_type(sd) == SYSFS_KOBJ_ATTR &&
141 sd->s_attr.attr->ignore_lockdep;
142}
143
144#else
145
146static inline bool ignore_lockdep(struct sysfs_dirent *sd)
147{
148 return true;
149}
150
151#endif
152
153/** 135/**
154 * sysfs_get_active - get an active reference to sysfs_dirent 136 * sysfs_get_active - get an active reference to sysfs_dirent
155 * @sd: sysfs_dirent to get an active reference to 137 * @sd: sysfs_dirent to get an active reference to
@@ -168,7 +150,7 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
168 if (!atomic_inc_unless_negative(&sd->s_active)) 150 if (!atomic_inc_unless_negative(&sd->s_active))
169 return NULL; 151 return NULL;
170 152
171 if (likely(!ignore_lockdep(sd))) 153 if (likely(!sysfs_ignore_lockdep(sd)))
172 rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); 154 rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_);
173 return sd; 155 return sd;
174} 156}
@@ -187,7 +169,7 @@ void sysfs_put_active(struct sysfs_dirent *sd)
187 if (unlikely(!sd)) 169 if (unlikely(!sd))
188 return; 170 return;
189 171
190 if (likely(!ignore_lockdep(sd))) 172 if (likely(!sysfs_ignore_lockdep(sd)))
191 rwsem_release(&sd->dep_map, 1, _RET_IP_); 173 rwsem_release(&sd->dep_map, 1, _RET_IP_);
192 v = atomic_dec_return(&sd->s_active); 174 v = atomic_dec_return(&sd->s_active);
193 if (likely(v != SD_DEACTIVATED_BIAS)) 175 if (likely(v != SD_DEACTIVATED_BIAS))
@@ -400,22 +382,19 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
400/** 382/**
401 * sysfs_addrm_start - prepare for sysfs_dirent add/remove 383 * sysfs_addrm_start - prepare for sysfs_dirent add/remove
402 * @acxt: pointer to sysfs_addrm_cxt to be used 384 * @acxt: pointer to sysfs_addrm_cxt to be used
403 * @parent_sd: parent sysfs_dirent
404 * 385 *
405 * This function is called when the caller is about to add or 386 * This function is called when the caller is about to add or remove
406 * remove sysfs_dirent under @parent_sd. This function acquires 387 * sysfs_dirent. This function acquires sysfs_mutex. @acxt is used
407 * sysfs_mutex. @acxt is used to keep and pass context to 388 * to keep and pass context to other addrm functions.
408 * other addrm functions.
409 * 389 *
410 * LOCKING: 390 * LOCKING:
411 * Kernel thread context (may sleep). sysfs_mutex is locked on 391 * Kernel thread context (may sleep). sysfs_mutex is locked on
412 * return. 392 * return.
413 */ 393 */
414void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, 394void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt)
415 struct sysfs_dirent *parent_sd) 395 __acquires(sysfs_mutex)
416{ 396{
417 memset(acxt, 0, sizeof(*acxt)); 397 memset(acxt, 0, sizeof(*acxt));
418 acxt->parent_sd = parent_sd;
419 398
420 mutex_lock(&sysfs_mutex); 399 mutex_lock(&sysfs_mutex);
421} 400}
@@ -424,10 +403,11 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
424 * __sysfs_add_one - add sysfs_dirent to parent without warning 403 * __sysfs_add_one - add sysfs_dirent to parent without warning
425 * @acxt: addrm context to use 404 * @acxt: addrm context to use
426 * @sd: sysfs_dirent to be added 405 * @sd: sysfs_dirent to be added
406 * @parent_sd: the parent sysfs_dirent to add @sd to
427 * 407 *
428 * Get @acxt->parent_sd and set sd->s_parent to it and increment 408 * Get @parent_sd and set @sd->s_parent to it and increment nlink of
429 * nlink of parent inode if @sd is a directory and link into the 409 * the parent inode if @sd is a directory and link into the children
430 * children list of the parent. 410 * list of the parent.
431 * 411 *
432 * This function should be called between calls to 412 * This function should be called between calls to
433 * sysfs_addrm_start() and sysfs_addrm_finish() and should be 413 * sysfs_addrm_start() and sysfs_addrm_finish() and should be
@@ -440,27 +420,28 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
440 * 0 on success, -EEXIST if entry with the given name already 420 * 0 on success, -EEXIST if entry with the given name already
441 * exists. 421 * exists.
442 */ 422 */
443int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 423int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
424 struct sysfs_dirent *parent_sd)
444{ 425{
445 struct sysfs_inode_attrs *ps_iattr; 426 struct sysfs_inode_attrs *ps_iattr;
446 int ret; 427 int ret;
447 428
448 if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) { 429 if (!!sysfs_ns_type(parent_sd) != !!sd->s_ns) {
449 WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", 430 WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
450 sysfs_ns_type(acxt->parent_sd) ? "required" : "invalid", 431 sysfs_ns_type(parent_sd) ? "required" : "invalid",
451 acxt->parent_sd->s_name, sd->s_name); 432 parent_sd->s_name, sd->s_name);
452 return -EINVAL; 433 return -EINVAL;
453 } 434 }
454 435
455 sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); 436 sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
456 sd->s_parent = sysfs_get(acxt->parent_sd); 437 sd->s_parent = sysfs_get(parent_sd);
457 438
458 ret = sysfs_link_sibling(sd); 439 ret = sysfs_link_sibling(sd);
459 if (ret) 440 if (ret)
460 return ret; 441 return ret;
461 442
462 /* Update timestamps on the parent */ 443 /* Update timestamps on the parent */
463 ps_iattr = acxt->parent_sd->s_iattr; 444 ps_iattr = parent_sd->s_iattr;
464 if (ps_iattr) { 445 if (ps_iattr) {
465 struct iattr *ps_iattrs = &ps_iattr->ia_iattr; 446 struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
466 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; 447 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
@@ -490,14 +471,32 @@ static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
490 return path; 471 return path;
491} 472}
492 473
474void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name)
475{
476 char *path;
477
478 path = kzalloc(PATH_MAX, GFP_KERNEL);
479 if (path) {
480 sysfs_pathname(parent, path);
481 strlcat(path, "/", PATH_MAX);
482 strlcat(path, name, PATH_MAX);
483 }
484
485 WARN(1, KERN_WARNING "sysfs: cannot create duplicate filename '%s'\n",
486 path ? path : name);
487
488 kfree(path);
489}
490
493/** 491/**
494 * sysfs_add_one - add sysfs_dirent to parent 492 * sysfs_add_one - add sysfs_dirent to parent
495 * @acxt: addrm context to use 493 * @acxt: addrm context to use
496 * @sd: sysfs_dirent to be added 494 * @sd: sysfs_dirent to be added
495 * @parent_sd: the parent sysfs_dirent to add @sd to
497 * 496 *
498 * Get @acxt->parent_sd and set sd->s_parent to it and increment 497 * Get @parent_sd and set @sd->s_parent to it and increment nlink of
499 * nlink of parent inode if @sd is a directory and link into the 498 * the parent inode if @sd is a directory and link into the children
500 * children list of the parent. 499 * list of the parent.
501 * 500 *
502 * This function should be called between calls to 501 * This function should be called between calls to
503 * sysfs_addrm_start() and sysfs_addrm_finish() and should be 502 * sysfs_addrm_start() and sysfs_addrm_finish() and should be
@@ -510,23 +509,15 @@ static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
510 * 0 on success, -EEXIST if entry with the given name already 509 * 0 on success, -EEXIST if entry with the given name already
511 * exists. 510 * exists.
512 */ 511 */
513int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 512int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
513 struct sysfs_dirent *parent_sd)
514{ 514{
515 int ret; 515 int ret;
516 516
517 ret = __sysfs_add_one(acxt, sd); 517 ret = __sysfs_add_one(acxt, sd, parent_sd);
518 if (ret == -EEXIST) {
519 char *path = kzalloc(PATH_MAX, GFP_KERNEL);
520 WARN(1, KERN_WARNING
521 "sysfs: cannot create duplicate filename '%s'\n",
522 (path == NULL) ? sd->s_name
523 : (sysfs_pathname(acxt->parent_sd, path),
524 strlcat(path, "/", PATH_MAX),
525 strlcat(path, sd->s_name, PATH_MAX),
526 path));
527 kfree(path);
528 }
529 518
519 if (ret == -EEXIST)
520 sysfs_warn_dup(parent_sd, sd->s_name);
530 return ret; 521 return ret;
531} 522}
532 523
@@ -545,16 +536,22 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
545 * LOCKING: 536 * LOCKING:
546 * Determined by sysfs_addrm_start(). 537 * Determined by sysfs_addrm_start().
547 */ 538 */
548void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 539static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
540 struct sysfs_dirent *sd)
549{ 541{
550 struct sysfs_inode_attrs *ps_iattr; 542 struct sysfs_inode_attrs *ps_iattr;
551 543
552 BUG_ON(sd->s_flags & SYSFS_FLAG_REMOVED); 544 /*
545 * Removal can be called multiple times on the same node. Only the
546 * first invocation is effective and puts the base ref.
547 */
548 if (sd->s_flags & SYSFS_FLAG_REMOVED)
549 return;
553 550
554 sysfs_unlink_sibling(sd); 551 sysfs_unlink_sibling(sd);
555 552
556 /* Update timestamps on the parent */ 553 /* Update timestamps on the parent */
557 ps_iattr = acxt->parent_sd->s_iattr; 554 ps_iattr = sd->s_parent->s_iattr;
558 if (ps_iattr) { 555 if (ps_iattr) {
559 struct iattr *ps_iattrs = &ps_iattr->ia_iattr; 556 struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
560 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; 557 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
@@ -577,6 +574,7 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
577 * sysfs_mutex is released. 574 * sysfs_mutex is released.
578 */ 575 */
579void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt) 576void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
577 __releases(sysfs_mutex)
580{ 578{
581 /* release resources acquired by sysfs_addrm_start() */ 579 /* release resources acquired by sysfs_addrm_start() */
582 mutex_unlock(&sysfs_mutex); 580 mutex_unlock(&sysfs_mutex);
@@ -588,7 +586,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
588 acxt->removed = sd->u.removed_list; 586 acxt->removed = sd->u.removed_list;
589 587
590 sysfs_deactivate(sd); 588 sysfs_deactivate(sd);
591 unmap_bin_file(sd); 589 sysfs_unmap_bin_file(sd);
592 sysfs_put(sd); 590 sysfs_put(sd);
593 } 591 }
594} 592}
@@ -597,6 +595,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
597 * sysfs_find_dirent - find sysfs_dirent with the given name 595 * sysfs_find_dirent - find sysfs_dirent with the given name
598 * @parent_sd: sysfs_dirent to search under 596 * @parent_sd: sysfs_dirent to search under
599 * @name: name to look for 597 * @name: name to look for
598 * @ns: the namespace tag to use
600 * 599 *
601 * Look for sysfs_dirent with name @name under @parent_sd. 600 * Look for sysfs_dirent with name @name under @parent_sd.
602 * 601 *
@@ -607,8 +606,8 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
607 * Pointer to sysfs_dirent if found, NULL if not. 606 * Pointer to sysfs_dirent if found, NULL if not.
608 */ 607 */
609struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, 608struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
610 const void *ns, 609 const unsigned char *name,
611 const unsigned char *name) 610 const void *ns)
612{ 611{
613 struct rb_node *node = parent_sd->s_dir.children.rb_node; 612 struct rb_node *node = parent_sd->s_dir.children.rb_node;
614 unsigned int hash; 613 unsigned int hash;
@@ -620,13 +619,13 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
620 return NULL; 619 return NULL;
621 } 620 }
622 621
623 hash = sysfs_name_hash(ns, name); 622 hash = sysfs_name_hash(name, ns);
624 while (node) { 623 while (node) {
625 struct sysfs_dirent *sd; 624 struct sysfs_dirent *sd;
626 int result; 625 int result;
627 626
628 sd = to_sysfs_dirent(node); 627 sd = to_sysfs_dirent(node);
629 result = sysfs_name_compare(hash, ns, name, sd); 628 result = sysfs_name_compare(hash, name, ns, sd);
630 if (result < 0) 629 if (result < 0)
631 node = node->rb_left; 630 node = node->rb_left;
632 else if (result > 0) 631 else if (result > 0)
@@ -638,9 +637,10 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
638} 637}
639 638
640/** 639/**
641 * sysfs_get_dirent - find and get sysfs_dirent with the given name 640 * sysfs_get_dirent_ns - find and get sysfs_dirent with the given name
642 * @parent_sd: sysfs_dirent to search under 641 * @parent_sd: sysfs_dirent to search under
643 * @name: name to look for 642 * @name: name to look for
643 * @ns: the namespace tag to use
644 * 644 *
645 * Look for sysfs_dirent with name @name under @parent_sd and get 645 * Look for sysfs_dirent with name @name under @parent_sd and get
646 * it if found. 646 * it if found.
@@ -651,24 +651,25 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
651 * RETURNS: 651 * RETURNS:
652 * Pointer to sysfs_dirent if found, NULL if not. 652 * Pointer to sysfs_dirent if found, NULL if not.
653 */ 653 */
654struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, 654struct sysfs_dirent *sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd,
655 const void *ns, 655 const unsigned char *name,
656 const unsigned char *name) 656 const void *ns)
657{ 657{
658 struct sysfs_dirent *sd; 658 struct sysfs_dirent *sd;
659 659
660 mutex_lock(&sysfs_mutex); 660 mutex_lock(&sysfs_mutex);
661 sd = sysfs_find_dirent(parent_sd, ns, name); 661 sd = sysfs_find_dirent(parent_sd, name, ns);
662 sysfs_get(sd); 662 sysfs_get(sd);
663 mutex_unlock(&sysfs_mutex); 663 mutex_unlock(&sysfs_mutex);
664 664
665 return sd; 665 return sd;
666} 666}
667EXPORT_SYMBOL_GPL(sysfs_get_dirent); 667EXPORT_SYMBOL_GPL(sysfs_get_dirent_ns);
668 668
669static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, 669static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
670 enum kobj_ns_type type, const void *ns, const char *name, 670 enum kobj_ns_type type,
671 struct sysfs_dirent **p_sd) 671 const char *name, const void *ns,
672 struct sysfs_dirent **p_sd)
672{ 673{
673 umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; 674 umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
674 struct sysfs_addrm_cxt acxt; 675 struct sysfs_addrm_cxt acxt;
@@ -685,8 +686,8 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
685 sd->s_dir.kobj = kobj; 686 sd->s_dir.kobj = kobj;
686 687
687 /* link in */ 688 /* link in */
688 sysfs_addrm_start(&acxt, parent_sd); 689 sysfs_addrm_start(&acxt);
689 rc = sysfs_add_one(&acxt, sd); 690 rc = sysfs_add_one(&acxt, sd, parent_sd);
690 sysfs_addrm_finish(&acxt); 691 sysfs_addrm_finish(&acxt);
691 692
692 if (rc == 0) 693 if (rc == 0)
@@ -701,7 +702,7 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
701 struct sysfs_dirent **p_sd) 702 struct sysfs_dirent **p_sd)
702{ 703{
703 return create_dir(kobj, kobj->sd, 704 return create_dir(kobj, kobj->sd,
704 KOBJ_NS_TYPE_NONE, NULL, name, p_sd); 705 KOBJ_NS_TYPE_NONE, name, NULL, p_sd);
705} 706}
706 707
707/** 708/**
@@ -730,14 +731,14 @@ static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
730} 731}
731 732
732/** 733/**
733 * sysfs_create_dir - create a directory for an object. 734 * sysfs_create_dir_ns - create a directory for an object with a namespace tag
734 * @kobj: object we're creating directory for. 735 * @kobj: object we're creating directory for
736 * @ns: the namespace tag to use
735 */ 737 */
736int sysfs_create_dir(struct kobject *kobj) 738int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
737{ 739{
738 enum kobj_ns_type type; 740 enum kobj_ns_type type;
739 struct sysfs_dirent *parent_sd, *sd; 741 struct sysfs_dirent *parent_sd, *sd;
740 const void *ns = NULL;
741 int error = 0; 742 int error = 0;
742 743
743 BUG_ON(!kobj); 744 BUG_ON(!kobj);
@@ -750,11 +751,9 @@ int sysfs_create_dir(struct kobject *kobj)
750 if (!parent_sd) 751 if (!parent_sd)
751 return -ENOENT; 752 return -ENOENT;
752 753
753 if (sysfs_ns_type(parent_sd))
754 ns = kobj->ktype->namespace(kobj);
755 type = sysfs_read_ns_type(kobj); 754 type = sysfs_read_ns_type(kobj);
756 755
757 error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd); 756 error = create_dir(kobj, parent_sd, type, kobject_name(kobj), ns, &sd);
758 if (!error) 757 if (!error)
759 kobj->sd = sd; 758 kobj->sd = sd;
760 return error; 759 return error;
@@ -776,7 +775,7 @@ static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry,
776 type = sysfs_ns_type(parent_sd); 775 type = sysfs_ns_type(parent_sd);
777 ns = sysfs_info(dir->i_sb)->ns[type]; 776 ns = sysfs_info(dir->i_sb)->ns[type];
778 777
779 sd = sysfs_find_dirent(parent_sd, ns, dentry->d_name.name); 778 sd = sysfs_find_dirent(parent_sd, dentry->d_name.name, ns);
780 779
781 /* no such entry */ 780 /* no such entry */
782 if (!sd) { 781 if (!sd) {
@@ -807,41 +806,128 @@ const struct inode_operations sysfs_dir_inode_operations = {
807 .setxattr = sysfs_setxattr, 806 .setxattr = sysfs_setxattr,
808}; 807};
809 808
810static void remove_dir(struct sysfs_dirent *sd) 809static struct sysfs_dirent *sysfs_leftmost_descendant(struct sysfs_dirent *pos)
811{ 810{
812 struct sysfs_addrm_cxt acxt; 811 struct sysfs_dirent *last;
813 812
814 sysfs_addrm_start(&acxt, sd->s_parent); 813 while (true) {
815 sysfs_remove_one(&acxt, sd); 814 struct rb_node *rbn;
816 sysfs_addrm_finish(&acxt); 815
816 last = pos;
817
818 if (sysfs_type(pos) != SYSFS_DIR)
819 break;
820
821 rbn = rb_first(&pos->s_dir.children);
822 if (!rbn)
823 break;
824
825 pos = to_sysfs_dirent(rbn);
826 }
827
828 return last;
817} 829}
818 830
819void sysfs_remove_subdir(struct sysfs_dirent *sd) 831/**
832 * sysfs_next_descendant_post - find the next descendant for post-order walk
833 * @pos: the current position (%NULL to initiate traversal)
834 * @root: sysfs_dirent whose descendants to walk
835 *
836 * Find the next descendant to visit for post-order traversal of @root's
837 * descendants. @root is included in the iteration and the last node to be
838 * visited.
839 */
840static struct sysfs_dirent *sysfs_next_descendant_post(struct sysfs_dirent *pos,
841 struct sysfs_dirent *root)
820{ 842{
821 remove_dir(sd); 843 struct rb_node *rbn;
844
845 lockdep_assert_held(&sysfs_mutex);
846
847 /* if first iteration, visit leftmost descendant which may be root */
848 if (!pos)
849 return sysfs_leftmost_descendant(root);
850
851 /* if we visited @root, we're done */
852 if (pos == root)
853 return NULL;
854
855 /* if there's an unvisited sibling, visit its leftmost descendant */
856 rbn = rb_next(&pos->s_rb);
857 if (rbn)
858 return sysfs_leftmost_descendant(to_sysfs_dirent(rbn));
859
860 /* no sibling left, visit parent */
861 return pos->s_parent;
822} 862}
823 863
864static void __sysfs_remove(struct sysfs_addrm_cxt *acxt,
865 struct sysfs_dirent *sd)
866{
867 struct sysfs_dirent *pos, *next;
868
869 if (!sd)
870 return;
824 871
825static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd) 872 pr_debug("sysfs %s: removing\n", sd->s_name);
873
874 next = NULL;
875 do {
876 pos = next;
877 next = sysfs_next_descendant_post(pos, sd);
878 if (pos)
879 sysfs_remove_one(acxt, pos);
880 } while (next);
881}
882
883/**
884 * sysfs_remove - remove a sysfs_dirent recursively
885 * @sd: the sysfs_dirent to remove
886 *
887 * Remove @sd along with all its subdirectories and files.
888 */
889void sysfs_remove(struct sysfs_dirent *sd)
826{ 890{
827 struct sysfs_addrm_cxt acxt; 891 struct sysfs_addrm_cxt acxt;
828 struct rb_node *pos;
829 892
830 if (!dir_sd) 893 sysfs_addrm_start(&acxt);
831 return; 894 __sysfs_remove(&acxt, sd);
895 sysfs_addrm_finish(&acxt);
896}
832 897
833 pr_debug("sysfs %s: removing dir\n", dir_sd->s_name); 898/**
834 sysfs_addrm_start(&acxt, dir_sd); 899 * sysfs_hash_and_remove - find a sysfs_dirent by name and remove it
835 pos = rb_first(&dir_sd->s_dir.children); 900 * @dir_sd: parent of the target
836 while (pos) { 901 * @name: name of the sysfs_dirent to remove
837 struct sysfs_dirent *sd = to_sysfs_dirent(pos); 902 * @ns: namespace tag of the sysfs_dirent to remove
838 pos = rb_next(pos); 903 *
839 if (sysfs_type(sd) != SYSFS_DIR) 904 * Look for the sysfs_dirent with @name and @ns under @dir_sd and remove
840 sysfs_remove_one(&acxt, sd); 905 * it. Returns 0 on success, -ENOENT if such entry doesn't exist.
906 */
907int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name,
908 const void *ns)
909{
910 struct sysfs_addrm_cxt acxt;
911 struct sysfs_dirent *sd;
912
913 if (!dir_sd) {
914 WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n",
915 name);
916 return -ENOENT;
841 } 917 }
918
919 sysfs_addrm_start(&acxt);
920
921 sd = sysfs_find_dirent(dir_sd, name, ns);
922 if (sd)
923 __sysfs_remove(&acxt, sd);
924
842 sysfs_addrm_finish(&acxt); 925 sysfs_addrm_finish(&acxt);
843 926
844 remove_dir(dir_sd); 927 if (sd)
928 return 0;
929 else
930 return -ENOENT;
845} 931}
846 932
847/** 933/**
@@ -852,21 +938,34 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
852 * the directory before we remove the directory, and we've inlined 938 * the directory before we remove the directory, and we've inlined
853 * what used to be sysfs_rmdir() below, instead of calling separately. 939 * what used to be sysfs_rmdir() below, instead of calling separately.
854 */ 940 */
855
856void sysfs_remove_dir(struct kobject *kobj) 941void sysfs_remove_dir(struct kobject *kobj)
857{ 942{
858 struct sysfs_dirent *sd = kobj->sd; 943 struct sysfs_dirent *sd = kobj->sd;
859 944
860 spin_lock(&sysfs_assoc_lock); 945 /*
946 * In general, kboject owner is responsible for ensuring removal
947 * doesn't race with other operations and sysfs doesn't provide any
948 * protection; however, when @kobj is used as a symlink target, the
949 * symlinking entity usually doesn't own @kobj and thus has no
950 * control over removal. @kobj->sd may be removed anytime and
951 * symlink code may end up dereferencing an already freed sd.
952 *
953 * sysfs_symlink_target_lock synchronizes @kobj->sd disassociation
954 * against symlink operations so that symlink code can safely
955 * dereference @kobj->sd.
956 */
957 spin_lock(&sysfs_symlink_target_lock);
861 kobj->sd = NULL; 958 kobj->sd = NULL;
862 spin_unlock(&sysfs_assoc_lock); 959 spin_unlock(&sysfs_symlink_target_lock);
863 960
864 __sysfs_remove_dir(sd); 961 if (sd) {
962 WARN_ON_ONCE(sysfs_type(sd) != SYSFS_DIR);
963 sysfs_remove(sd);
964 }
865} 965}
866 966
867int sysfs_rename(struct sysfs_dirent *sd, 967int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,
868 struct sysfs_dirent *new_parent_sd, const void *new_ns, 968 const char *new_name, const void *new_ns)
869 const char *new_name)
870{ 969{
871 int error; 970 int error;
872 971
@@ -878,7 +977,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
878 goto out; /* nothing to rename */ 977 goto out; /* nothing to rename */
879 978
880 error = -EEXIST; 979 error = -EEXIST;
881 if (sysfs_find_dirent(new_parent_sd, new_ns, new_name)) 980 if (sysfs_find_dirent(new_parent_sd, new_name, new_ns))
882 goto out; 981 goto out;
883 982
884 /* rename sysfs_dirent */ 983 /* rename sysfs_dirent */
@@ -899,7 +998,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
899 sysfs_get(new_parent_sd); 998 sysfs_get(new_parent_sd);
900 sysfs_put(sd->s_parent); 999 sysfs_put(sd->s_parent);
901 sd->s_ns = new_ns; 1000 sd->s_ns = new_ns;
902 sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); 1001 sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
903 sd->s_parent = new_parent_sd; 1002 sd->s_parent = new_parent_sd;
904 sysfs_link_sibling(sd); 1003 sysfs_link_sibling(sd);
905 1004
@@ -909,30 +1008,25 @@ int sysfs_rename(struct sysfs_dirent *sd,
909 return error; 1008 return error;
910} 1009}
911 1010
912int sysfs_rename_dir(struct kobject *kobj, const char *new_name) 1011int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
1012 const void *new_ns)
913{ 1013{
914 struct sysfs_dirent *parent_sd = kobj->sd->s_parent; 1014 struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
915 const void *new_ns = NULL;
916
917 if (sysfs_ns_type(parent_sd))
918 new_ns = kobj->ktype->namespace(kobj);
919 1015
920 return sysfs_rename(kobj->sd, parent_sd, new_ns, new_name); 1016 return sysfs_rename(kobj->sd, parent_sd, new_name, new_ns);
921} 1017}
922 1018
923int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) 1019int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
1020 const void *new_ns)
924{ 1021{
925 struct sysfs_dirent *sd = kobj->sd; 1022 struct sysfs_dirent *sd = kobj->sd;
926 struct sysfs_dirent *new_parent_sd; 1023 struct sysfs_dirent *new_parent_sd;
927 const void *new_ns = NULL;
928 1024
929 BUG_ON(!sd->s_parent); 1025 BUG_ON(!sd->s_parent);
930 if (sysfs_ns_type(sd->s_parent))
931 new_ns = kobj->ktype->namespace(kobj);
932 new_parent_sd = new_parent_kobj && new_parent_kobj->sd ? 1026 new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
933 new_parent_kobj->sd : &sysfs_root; 1027 new_parent_kobj->sd : &sysfs_root;
934 1028
935 return sysfs_rename(sd, new_parent_sd, new_ns, sd->s_name); 1029 return sysfs_rename(sd, new_parent_sd, sd->s_name, new_ns);
936} 1030}
937 1031
938/* Relationship between s_mode and the DT_xxx types */ 1032/* Relationship between s_mode and the DT_xxx types */