aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2011-03-22 07:23:40 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-03-24 21:16:32 -0400
commit55fa6091d83160ca772fc37cebae45d42695a708 (patch)
tree4df49f372032e30449e1a2dd64daf443e20b781c /fs/notify
parentf283c86afe6aa70b733d1ecebad5d9464943b774 (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.c20
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 */
244void fsnotify_unmount_inodes(struct list_head *list) 245void 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}