diff options
-rw-r--r-- | fs/sysfs/dir.c | 62 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 3 |
2 files changed, 32 insertions, 33 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 97954c69ff0e..f05f2303a8b8 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -760,30 +760,42 @@ void sysfs_remove_dir(struct kobject * kobj) | |||
760 | __sysfs_remove_dir(sd); | 760 | __sysfs_remove_dir(sd); |
761 | } | 761 | } |
762 | 762 | ||
763 | int sysfs_rename_dir(struct kobject * kobj, const char *new_name) | 763 | int sysfs_rename(struct sysfs_dirent *sd, |
764 | struct sysfs_dirent *new_parent_sd, const char *new_name) | ||
764 | { | 765 | { |
765 | struct sysfs_dirent *sd = kobj->sd; | ||
766 | const char *dup_name = NULL; | 766 | const char *dup_name = NULL; |
767 | int error; | 767 | int error; |
768 | 768 | ||
769 | mutex_lock(&sysfs_mutex); | 769 | mutex_lock(&sysfs_mutex); |
770 | 770 | ||
771 | error = 0; | 771 | error = 0; |
772 | if (strcmp(sd->s_name, new_name) == 0) | 772 | if ((sd->s_parent == new_parent_sd) && |
773 | (strcmp(sd->s_name, new_name) == 0)) | ||
773 | goto out; /* nothing to rename */ | 774 | goto out; /* nothing to rename */ |
774 | 775 | ||
775 | error = -EEXIST; | 776 | error = -EEXIST; |
776 | if (sysfs_find_dirent(sd->s_parent, new_name)) | 777 | if (sysfs_find_dirent(new_parent_sd, new_name)) |
777 | goto out; | 778 | goto out; |
778 | 779 | ||
779 | /* rename sysfs_dirent */ | 780 | /* rename sysfs_dirent */ |
780 | error = -ENOMEM; | 781 | if (strcmp(sd->s_name, new_name) != 0) { |
781 | new_name = dup_name = kstrdup(new_name, GFP_KERNEL); | 782 | error = -ENOMEM; |
782 | if (!new_name) | 783 | new_name = dup_name = kstrdup(new_name, GFP_KERNEL); |
783 | goto out; | 784 | if (!new_name) |
785 | goto out; | ||
786 | |||
787 | dup_name = sd->s_name; | ||
788 | sd->s_name = new_name; | ||
789 | } | ||
784 | 790 | ||
785 | dup_name = sd->s_name; | 791 | /* Remove from old parent's list and insert into new parent's list. */ |
786 | sd->s_name = new_name; | 792 | if (sd->s_parent != new_parent_sd) { |
793 | sysfs_unlink_sibling(sd); | ||
794 | sysfs_get(new_parent_sd); | ||
795 | sysfs_put(sd->s_parent); | ||
796 | sd->s_parent = new_parent_sd; | ||
797 | sysfs_link_sibling(sd); | ||
798 | } | ||
787 | 799 | ||
788 | error = 0; | 800 | error = 0; |
789 | out: | 801 | out: |
@@ -792,37 +804,21 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name) | |||
792 | return error; | 804 | return error; |
793 | } | 805 | } |
794 | 806 | ||
807 | int sysfs_rename_dir(struct kobject *kobj, const char *new_name) | ||
808 | { | ||
809 | return sysfs_rename(kobj->sd, kobj->sd->s_parent, new_name); | ||
810 | } | ||
811 | |||
795 | int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) | 812 | int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) |
796 | { | 813 | { |
797 | struct sysfs_dirent *sd = kobj->sd; | 814 | struct sysfs_dirent *sd = kobj->sd; |
798 | struct sysfs_dirent *new_parent_sd; | 815 | struct sysfs_dirent *new_parent_sd; |
799 | int error; | ||
800 | 816 | ||
801 | BUG_ON(!sd->s_parent); | 817 | BUG_ON(!sd->s_parent); |
802 | 818 | new_parent_sd = new_parent_kobj && new_parent_kobj->sd ? | |
803 | mutex_lock(&sysfs_mutex); | ||
804 | new_parent_sd = (new_parent_kobj && new_parent_kobj->sd) ? | ||
805 | new_parent_kobj->sd : &sysfs_root; | 819 | new_parent_kobj->sd : &sysfs_root; |
806 | 820 | ||
807 | error = 0; | 821 | return sysfs_rename(sd, new_parent_sd, sd->s_name); |
808 | if (sd->s_parent == new_parent_sd) | ||
809 | goto out; /* nothing to move */ | ||
810 | |||
811 | error = -EEXIST; | ||
812 | if (sysfs_find_dirent(new_parent_sd, sd->s_name)) | ||
813 | goto out; | ||
814 | |||
815 | /* Remove from old parent's list and insert into new parent's list. */ | ||
816 | sysfs_unlink_sibling(sd); | ||
817 | sysfs_get(new_parent_sd); | ||
818 | sysfs_put(sd->s_parent); | ||
819 | sd->s_parent = new_parent_sd; | ||
820 | sysfs_link_sibling(sd); | ||
821 | |||
822 | error = 0; | ||
823 | out: | ||
824 | mutex_unlock(&sysfs_mutex); | ||
825 | return error; | ||
826 | } | 822 | } |
827 | 823 | ||
828 | /* Relationship between s_mode and the DT_xxx types */ | 824 | /* Relationship between s_mode and the DT_xxx types */ |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 98a15bf1efe1..ca52e7b9d8f8 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -130,6 +130,9 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name, | |||
130 | struct sysfs_dirent **p_sd); | 130 | struct sysfs_dirent **p_sd); |
131 | void sysfs_remove_subdir(struct sysfs_dirent *sd); | 131 | void sysfs_remove_subdir(struct sysfs_dirent *sd); |
132 | 132 | ||
133 | int sysfs_rename(struct sysfs_dirent *sd, | ||
134 | struct sysfs_dirent *new_parent_sd, const char *new_name); | ||
135 | |||
133 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) | 136 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) |
134 | { | 137 | { |
135 | if (sd) { | 138 | if (sd) { |