aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2009-11-20 19:08:57 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:24:54 -0500
commitca1bab38195d66bdf42320a99cc7359434a271d3 (patch)
tree4394403b4a85fb269d052b7852b41ee0f7ba8a88
parent832b6af198aefe6034310e124594cc8b833c0ef9 (diff)
sysfs: Factor out sysfs_rename from sysfs_rename_dir and sysfs_move_dir
These two functions do 90% of the same work and it doesn't significantly obfuscate the function to allow both the parent dir and the name to change at the same time. So merge them together to simplify maintenance, and increase testing. Acked-by: Tejun Heo <tj@kernel.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-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 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
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 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);
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) {