aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/sysfs/dir.c62
-rw-r--r--fs/sysfs/sysfs.h3
2 files changed, 32 insertions, 33 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 97954c69ff0..f05f2303a8b 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
763int sysfs_rename_dir(struct kobject * kobj, const char *new_name) 763int 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
807int 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
795int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) 812int 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;
823out:
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 98a15bf1efe..ca52e7b9d8f 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);
131void sysfs_remove_subdir(struct sysfs_dirent *sd); 131void sysfs_remove_subdir(struct sysfs_dirent *sd);
132 132
133int sysfs_rename(struct sysfs_dirent *sd,
134 struct sysfs_dirent *new_parent_sd, const char *new_name);
135
133static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) 136static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
134{ 137{
135 if (sd) { 138 if (sd) {