diff options
author | Dave Chinner <dchinner@redhat.com> | 2011-03-22 07:23:40 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-24 21:16:32 -0400 |
commit | 55fa6091d83160ca772fc37cebae45d42695a708 (patch) | |
tree | 4df49f372032e30449e1a2dd64daf443e20b781c /fs/notify | |
parent | f283c86afe6aa70b733d1ecebad5d9464943b774 (diff) |
fs: move i_sb_list out from under inode_lock
Protect the per-sb inode list with a new global lock
inode_sb_list_lock and use it to protect the list manipulations and
traversals. This lock replaces the inode_lock as the inodes on the
list can be validity checked while holding the inode->i_lock and
hence the inode_lock is no longer needed to protect the list.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/notify')
-rw-r--r-- | fs/notify/inode_mark.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index 4dd53fb44124..fb3b3c5ef0ee 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/fsnotify_backend.h> | 29 | #include <linux/fsnotify_backend.h> |
30 | #include "fsnotify.h" | 30 | #include "fsnotify.h" |
31 | 31 | ||
32 | #include "../internal.h" | ||
33 | |||
32 | /* | 34 | /* |
33 | * Recalculate the mask of events relevant to a given inode locked. | 35 | * Recalculate the mask of events relevant to a given inode locked. |
34 | */ | 36 | */ |
@@ -237,15 +239,14 @@ out: | |||
237 | * fsnotify_unmount_inodes - an sb is unmounting. handle any watched inodes. | 239 | * fsnotify_unmount_inodes - an sb is unmounting. handle any watched inodes. |
238 | * @list: list of inodes being unmounted (sb->s_inodes) | 240 | * @list: list of inodes being unmounted (sb->s_inodes) |
239 | * | 241 | * |
240 | * Called with inode_lock held, protecting the unmounting super block's list | 242 | * Called during unmount with no locks held, so needs to be safe against |
241 | * of inodes, and with iprune_mutex held, keeping shrink_icache_memory() at bay. | 243 | * concurrent modifiers. We temporarily drop inode_sb_list_lock and CAN block. |
242 | * We temporarily drop inode_lock, however, and CAN block. | ||
243 | */ | 244 | */ |
244 | void fsnotify_unmount_inodes(struct list_head *list) | 245 | void fsnotify_unmount_inodes(struct list_head *list) |
245 | { | 246 | { |
246 | struct inode *inode, *next_i, *need_iput = NULL; | 247 | struct inode *inode, *next_i, *need_iput = NULL; |
247 | 248 | ||
248 | spin_lock(&inode_lock); | 249 | spin_lock(&inode_sb_list_lock); |
249 | list_for_each_entry_safe(inode, next_i, list, i_sb_list) { | 250 | list_for_each_entry_safe(inode, next_i, list, i_sb_list) { |
250 | struct inode *need_iput_tmp; | 251 | struct inode *need_iput_tmp; |
251 | 252 | ||
@@ -293,12 +294,11 @@ void fsnotify_unmount_inodes(struct list_head *list) | |||
293 | } | 294 | } |
294 | 295 | ||
295 | /* | 296 | /* |
296 | * We can safely drop inode_lock here because we hold | 297 | * We can safely drop inode_sb_list_lock here because we hold |
297 | * references on both inode and next_i. Also no new inodes | 298 | * references on both inode and next_i. Also no new inodes |
298 | * will be added since the umount has begun. Finally, | 299 | * will be added since the umount has begun. |
299 | * iprune_mutex keeps shrink_icache_memory() away. | ||
300 | */ | 300 | */ |
301 | spin_unlock(&inode_lock); | 301 | spin_unlock(&inode_sb_list_lock); |
302 | 302 | ||
303 | if (need_iput_tmp) | 303 | if (need_iput_tmp) |
304 | iput(need_iput_tmp); | 304 | iput(need_iput_tmp); |
@@ -310,7 +310,7 @@ void fsnotify_unmount_inodes(struct list_head *list) | |||
310 | 310 | ||
311 | iput(inode); | 311 | iput(inode); |
312 | 312 | ||
313 | spin_lock(&inode_lock); | 313 | spin_lock(&inode_sb_list_lock); |
314 | } | 314 | } |
315 | spin_unlock(&inode_lock); | 315 | spin_unlock(&inode_sb_list_lock); |
316 | } | 316 | } |