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) { |
