diff options
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r-- | fs/sysfs/dir.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index f05f2303a8b8..699f371b9f12 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -106,8 +106,10 @@ static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) | |||
106 | return NULL; | 106 | return NULL; |
107 | 107 | ||
108 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); | 108 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); |
109 | if (likely(t == v)) | 109 | if (likely(t == v)) { |
110 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); | ||
110 | return sd; | 111 | return sd; |
112 | } | ||
111 | if (t < 0) | 113 | if (t < 0) |
112 | return NULL; | 114 | return NULL; |
113 | 115 | ||
@@ -130,6 +132,7 @@ static void sysfs_put_active(struct sysfs_dirent *sd) | |||
130 | if (unlikely(!sd)) | 132 | if (unlikely(!sd)) |
131 | return; | 133 | return; |
132 | 134 | ||
135 | rwsem_release(&sd->dep_map, 1, _RET_IP_); | ||
133 | v = atomic_dec_return(&sd->s_active); | 136 | v = atomic_dec_return(&sd->s_active); |
134 | if (likely(v != SD_DEACTIVATED_BIAS)) | 137 | if (likely(v != SD_DEACTIVATED_BIAS)) |
135 | return; | 138 | return; |
@@ -194,15 +197,21 @@ static void sysfs_deactivate(struct sysfs_dirent *sd) | |||
194 | BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED)); | 197 | BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED)); |
195 | sd->s_sibling = (void *)&wait; | 198 | sd->s_sibling = (void *)&wait; |
196 | 199 | ||
200 | rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_); | ||
197 | /* atomic_add_return() is a mb(), put_active() will always see | 201 | /* atomic_add_return() is a mb(), put_active() will always see |
198 | * the updated sd->s_sibling. | 202 | * the updated sd->s_sibling. |
199 | */ | 203 | */ |
200 | v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active); | 204 | v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active); |
201 | 205 | ||
202 | if (v != SD_DEACTIVATED_BIAS) | 206 | if (v != SD_DEACTIVATED_BIAS) { |
207 | lock_contended(&sd->dep_map, _RET_IP_); | ||
203 | wait_for_completion(&wait); | 208 | wait_for_completion(&wait); |
209 | } | ||
204 | 210 | ||
205 | sd->s_sibling = NULL; | 211 | sd->s_sibling = NULL; |
212 | |||
213 | lock_acquired(&sd->dep_map, _RET_IP_); | ||
214 | rwsem_release(&sd->dep_map, 1, _RET_IP_); | ||
206 | } | 215 | } |
207 | 216 | ||
208 | static int sysfs_alloc_ino(ino_t *pino) | 217 | static int sysfs_alloc_ino(ino_t *pino) |
@@ -345,6 +354,7 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) | |||
345 | 354 | ||
346 | atomic_set(&sd->s_count, 1); | 355 | atomic_set(&sd->s_count, 1); |
347 | atomic_set(&sd->s_active, 0); | 356 | atomic_set(&sd->s_active, 0); |
357 | sysfs_dirent_init_lockdep(sd); | ||
348 | 358 | ||
349 | sd->s_name = name; | 359 | sd->s_name = name; |
350 | sd->s_mode = mode; | 360 | sd->s_mode = mode; |