diff options
Diffstat (limited to 'fs/notify')
-rw-r--r-- | fs/notify/mark.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 0e93d90bb753..fc6b49bf7360 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c | |||
@@ -150,6 +150,8 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark, | |||
150 | 150 | ||
151 | spin_unlock(&mark->lock); | 151 | spin_unlock(&mark->lock); |
152 | 152 | ||
153 | if (inode && (mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) | ||
154 | iput(inode); | ||
153 | /* release lock temporarily */ | 155 | /* release lock temporarily */ |
154 | mutex_unlock(&group->mark_mutex); | 156 | mutex_unlock(&group->mark_mutex); |
155 | 157 | ||
@@ -157,6 +159,11 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark, | |||
157 | list_add(&mark->destroy_list, &destroy_list); | 159 | list_add(&mark->destroy_list, &destroy_list); |
158 | spin_unlock(&destroy_lock); | 160 | spin_unlock(&destroy_lock); |
159 | wake_up(&destroy_waitq); | 161 | wake_up(&destroy_waitq); |
162 | /* | ||
163 | * We don't necessarily have a ref on mark from caller so the above destroy | ||
164 | * may have actually freed it, unless this group provides a 'freeing_mark' | ||
165 | * function which must be holding a reference. | ||
166 | */ | ||
160 | 167 | ||
161 | /* | 168 | /* |
162 | * Some groups like to know that marks are being freed. This is a | 169 | * Some groups like to know that marks are being freed. This is a |
@@ -178,22 +185,15 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark, | |||
178 | * is just a lazy update (and could be a perf win...) | 185 | * is just a lazy update (and could be a perf win...) |
179 | */ | 186 | */ |
180 | 187 | ||
181 | if (inode && (mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) | ||
182 | iput(inode); | ||
183 | /* | ||
184 | * We don't necessarily have a ref on mark from caller so the above iput | ||
185 | * may have already destroyed it. Don't touch from now on. | ||
186 | */ | ||
187 | |||
188 | atomic_dec(&group->num_marks); | 188 | atomic_dec(&group->num_marks); |
189 | 189 | ||
190 | mutex_lock(&group->mark_mutex); | 190 | mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); |
191 | } | 191 | } |
192 | 192 | ||
193 | void fsnotify_destroy_mark(struct fsnotify_mark *mark, | 193 | void fsnotify_destroy_mark(struct fsnotify_mark *mark, |
194 | struct fsnotify_group *group) | 194 | struct fsnotify_group *group) |
195 | { | 195 | { |
196 | mutex_lock(&group->mark_mutex); | 196 | mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); |
197 | fsnotify_destroy_mark_locked(mark, group); | 197 | fsnotify_destroy_mark_locked(mark, group); |
198 | mutex_unlock(&group->mark_mutex); | 198 | mutex_unlock(&group->mark_mutex); |
199 | } | 199 | } |
@@ -300,7 +300,7 @@ void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, | |||
300 | { | 300 | { |
301 | struct fsnotify_mark *lmark, *mark; | 301 | struct fsnotify_mark *lmark, *mark; |
302 | 302 | ||
303 | mutex_lock(&group->mark_mutex); | 303 | mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); |
304 | list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) { | 304 | list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) { |
305 | if (mark->flags & flags) { | 305 | if (mark->flags & flags) { |
306 | fsnotify_get_mark(mark); | 306 | fsnotify_get_mark(mark); |