diff options
author | Tejun Heo <htejun@gmail.com> | 2007-06-13 15:27:23 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-11 19:09:08 -0400 |
commit | 3007e997de91ec59af39a3f9c91595b31ae6e08b (patch) | |
tree | 4ed4df3ef3a249d2a4b562e36876fc8d4a3fabd9 /fs/sysfs/symlink.c | |
parent | 5f9953237f684ea1778adb9d26162da00b282225 (diff) |
sysfs: use sysfs_mutex to protect the sysfs_dirent tree
As kobj sysfs dentries and inodes are gonna be made reclaimable,
i_mutex can't be used to protect sysfs_dirent tree. Use sysfs_mutex
globally instead. As the whole tree is protected with sysfs_mutex,
there is no reason to keep sysfs_rename_sem. Drop it.
While at it, add docbook comments to functions which require
sysfs_mutex locking.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/sysfs/symlink.c')
-rw-r--r-- | fs/sysfs/symlink.c | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index cbd95a4109de..683316f0aa96 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -44,20 +44,6 @@ static void fill_object_path(struct sysfs_dirent *sd, char *buffer, int length) | |||
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
47 | static int sysfs_add_link(struct sysfs_dirent * parent_sd, const char * name, | ||
48 | struct sysfs_dirent * target_sd) | ||
49 | { | ||
50 | struct sysfs_dirent * sd; | ||
51 | |||
52 | sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); | ||
53 | if (!sd) | ||
54 | return -ENOMEM; | ||
55 | |||
56 | sd->s_elem.symlink.target_sd = target_sd; | ||
57 | sysfs_attach_dirent(sd, parent_sd, NULL); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | /** | 47 | /** |
62 | * sysfs_create_link - create symlink between two objects. | 48 | * sysfs_create_link - create symlink between two objects. |
63 | * @kobj: object whose directory we're creating the link in. | 49 | * @kobj: object whose directory we're creating the link in. |
@@ -68,7 +54,8 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
68 | { | 54 | { |
69 | struct sysfs_dirent *parent_sd = NULL; | 55 | struct sysfs_dirent *parent_sd = NULL; |
70 | struct sysfs_dirent *target_sd = NULL; | 56 | struct sysfs_dirent *target_sd = NULL; |
71 | int error = -EEXIST; | 57 | struct sysfs_dirent *sd = NULL; |
58 | int error; | ||
72 | 59 | ||
73 | BUG_ON(!name); | 60 | BUG_ON(!name); |
74 | 61 | ||
@@ -78,8 +65,9 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
78 | } else | 65 | } else |
79 | parent_sd = kobj->sd; | 66 | parent_sd = kobj->sd; |
80 | 67 | ||
68 | error = -EFAULT; | ||
81 | if (!parent_sd) | 69 | if (!parent_sd) |
82 | return -EFAULT; | 70 | goto out_put; |
83 | 71 | ||
84 | /* target->sd can go away beneath us but is protected with | 72 | /* target->sd can go away beneath us but is protected with |
85 | * sysfs_assoc_lock. Fetch target_sd from it. | 73 | * sysfs_assoc_lock. Fetch target_sd from it. |
@@ -89,17 +77,30 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
89 | target_sd = sysfs_get(target->sd); | 77 | target_sd = sysfs_get(target->sd); |
90 | spin_unlock(&sysfs_assoc_lock); | 78 | spin_unlock(&sysfs_assoc_lock); |
91 | 79 | ||
80 | error = -ENOENT; | ||
92 | if (!target_sd) | 81 | if (!target_sd) |
93 | return -ENOENT; | 82 | goto out_put; |
83 | |||
84 | error = -ENOMEM; | ||
85 | sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); | ||
86 | if (!sd) | ||
87 | goto out_put; | ||
88 | sd->s_elem.symlink.target_sd = target_sd; | ||
94 | 89 | ||
95 | mutex_lock(&parent_sd->s_dentry->d_inode->i_mutex); | 90 | mutex_lock(&sysfs_mutex); |
96 | if (!sysfs_find_dirent(parent_sd, name)) | 91 | error = -EEXIST; |
97 | error = sysfs_add_link(parent_sd, name, target_sd); | 92 | if (sysfs_find_dirent(parent_sd, name)) |
98 | mutex_unlock(&parent_sd->s_dentry->d_inode->i_mutex); | 93 | goto out_unlock; |
94 | sysfs_attach_dirent(sd, parent_sd, NULL); | ||
95 | mutex_unlock(&sysfs_mutex); | ||
99 | 96 | ||
100 | if (error) | 97 | return 0; |
101 | sysfs_put(target_sd); | ||
102 | 98 | ||
99 | out_unlock: | ||
100 | mutex_unlock(&sysfs_mutex); | ||
101 | out_put: | ||
102 | sysfs_put(target_sd); | ||
103 | sysfs_put(sd); | ||
103 | return error; | 104 | return error; |
104 | } | 105 | } |
105 | 106 | ||
@@ -144,9 +145,9 @@ static int sysfs_getlink(struct dentry *dentry, char * path) | |||
144 | struct sysfs_dirent *target_sd = sd->s_elem.symlink.target_sd; | 145 | struct sysfs_dirent *target_sd = sd->s_elem.symlink.target_sd; |
145 | int error; | 146 | int error; |
146 | 147 | ||
147 | down_read(&sysfs_rename_sem); | 148 | mutex_lock(&sysfs_mutex); |
148 | error = sysfs_get_target_path(parent_sd, target_sd, path); | 149 | error = sysfs_get_target_path(parent_sd, target_sd, path); |
149 | up_read(&sysfs_rename_sem); | 150 | mutex_unlock(&sysfs_mutex); |
150 | 151 | ||
151 | return error; | 152 | return error; |
152 | } | 153 | } |