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>
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <linux/writeback.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/gfp.h>
|
||||
#include "internal.h"
|
||||
|
||||
/* A global variable is a bit ugly, but it keeps the code simple */
|
||||
int sysctl_drop_caches;
|
||||
@@ -16,7 +17,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
|
||||
{
|
||||
struct inode *inode, *toput_inode = NULL;
|
||||
|
||||
spin_lock(&inode_lock);
|
||||
spin_lock(&inode_sb_list_lock);
|
||||
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
|
||||
spin_lock(&inode->i_lock);
|
||||
if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
|
||||
@@ -26,13 +27,13 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
|
||||
}
|
||||
__iget(inode);
|
||||
spin_unlock(&inode->i_lock);
|
||||
spin_unlock(&inode_lock);
|
||||
spin_unlock(&inode_sb_list_lock);
|
||||
invalidate_mapping_pages(inode->i_mapping, 0, -1);
|
||||
iput(toput_inode);
|
||||
toput_inode = inode;
|
||||
spin_lock(&inode_lock);
|
||||
spin_lock(&inode_sb_list_lock);
|
||||
}
|
||||
spin_unlock(&inode_lock);
|
||||
spin_unlock(&inode_sb_list_lock);
|
||||
iput(toput_inode);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user