diff options
| author | Tejun Heo <htejun@gmail.com> | 2007-07-31 06:15:08 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-08-22 17:35:34 -0400 |
| commit | 6cb52147b254373364a2fef5df8b4aa3739c8bb6 (patch) | |
| tree | 423fa52521460ac39169397f637e2d9d9a2c8dab | |
| parent | 74e8f346d59074147c564d9c1ffd6caf18286516 (diff) | |
sysfs: fix locking in sysfs_lookup() and sysfs_rename_dir()
sd children list walking in sysfs_lookup() and sd renaming in
sysfs_rename_dir() were left out during i_mutex -> sysfs_mutex
conversion. Fix them.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | fs/sysfs/dir.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 048e6054c2fd..83e76b3813c9 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
| @@ -762,12 +762,15 @@ static int sysfs_count_nlink(struct sysfs_dirent *sd) | |||
| 762 | static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | 762 | static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, |
| 763 | struct nameidata *nd) | 763 | struct nameidata *nd) |
| 764 | { | 764 | { |
| 765 | struct dentry *ret = NULL; | ||
| 765 | struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata; | 766 | struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata; |
| 766 | struct sysfs_dirent * sd; | 767 | struct sysfs_dirent * sd; |
| 767 | struct bin_attribute *bin_attr; | 768 | struct bin_attribute *bin_attr; |
| 768 | struct inode *inode; | 769 | struct inode *inode; |
| 769 | int found = 0; | 770 | int found = 0; |
| 770 | 771 | ||
| 772 | mutex_lock(&sysfs_mutex); | ||
| 773 | |||
| 771 | for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) { | 774 | for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) { |
| 772 | if (sysfs_type(sd) && | 775 | if (sysfs_type(sd) && |
| 773 | !strcmp(sd->s_name, dentry->d_name.name)) { | 776 | !strcmp(sd->s_name, dentry->d_name.name)) { |
| @@ -778,14 +781,14 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 778 | 781 | ||
| 779 | /* no such entry */ | 782 | /* no such entry */ |
| 780 | if (!found) | 783 | if (!found) |
| 781 | return NULL; | 784 | goto out_unlock; |
| 782 | 785 | ||
| 783 | /* attach dentry and inode */ | 786 | /* attach dentry and inode */ |
| 784 | inode = sysfs_get_inode(sd); | 787 | inode = sysfs_get_inode(sd); |
| 785 | if (!inode) | 788 | if (!inode) { |
| 786 | return ERR_PTR(-ENOMEM); | 789 | ret = ERR_PTR(-ENOMEM); |
| 787 | 790 | goto out_unlock; | |
| 788 | mutex_lock(&sysfs_mutex); | 791 | } |
| 789 | 792 | ||
| 790 | if (inode->i_state & I_NEW) { | 793 | if (inode->i_state & I_NEW) { |
| 791 | /* initialize inode according to type */ | 794 | /* initialize inode according to type */ |
| @@ -815,9 +818,9 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 815 | sysfs_instantiate(dentry, inode); | 818 | sysfs_instantiate(dentry, inode); |
| 816 | sysfs_attach_dentry(sd, dentry); | 819 | sysfs_attach_dentry(sd, dentry); |
| 817 | 820 | ||
| 821 | out_unlock: | ||
| 818 | mutex_unlock(&sysfs_mutex); | 822 | mutex_unlock(&sysfs_mutex); |
| 819 | 823 | return ret; | |
| 820 | return NULL; | ||
| 821 | } | 824 | } |
| 822 | 825 | ||
| 823 | const struct inode_operations sysfs_dir_inode_operations = { | 826 | const struct inode_operations sysfs_dir_inode_operations = { |
| @@ -942,6 +945,8 @@ int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd, | |||
| 942 | if (error) | 945 | if (error) |
| 943 | goto out_drop; | 946 | goto out_drop; |
| 944 | 947 | ||
| 948 | mutex_lock(&sysfs_mutex); | ||
| 949 | |||
| 945 | dup_name = sd->s_name; | 950 | dup_name = sd->s_name; |
| 946 | sd->s_name = new_name; | 951 | sd->s_name = new_name; |
| 947 | 952 | ||
| @@ -949,8 +954,6 @@ int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd, | |||
| 949 | d_add(new_dentry, NULL); | 954 | d_add(new_dentry, NULL); |
| 950 | d_move(sd->s_dentry, new_dentry); | 955 | d_move(sd->s_dentry, new_dentry); |
| 951 | 956 | ||
| 952 | mutex_lock(&sysfs_mutex); | ||
| 953 | |||
| 954 | sysfs_unlink_sibling(sd); | 957 | sysfs_unlink_sibling(sd); |
| 955 | sysfs_get(new_parent_sd); | 958 | sysfs_get(new_parent_sd); |
| 956 | sysfs_put(sd->s_parent); | 959 | sysfs_put(sd->s_parent); |
