fs: move i_wb_list out from under inode_lock

Protect the inode writeback list with a new global lock
inode_wb_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 <[email protected]>
Signed-off-by: Al Viro <[email protected]>
This commit is contained in:
Dave Chinner 2011-03-22 22:23:41 +11:00 • committed by Al Viro
commit a66979abad
8 changed files with 70 additions and 48 deletions

View file

@ -26,6 +26,7 @@
#include <linux/posix_acl.h>
#include <linux/ima.h>
#include <linux/cred.h>
#include "internal.h"
/*
* inode locking rules.
@ -36,6 +37,8 @@
* inode_lru, inode->i_lru
* inode_sb_list_lock protects:
* sb->s_inodes, inode->i_sb_list
* inode_wb_list_lock protects:
* bdi->wb.b_{dirty,io,more_io}, inode->i_wb_list
*
* Lock ordering:
* inode_lock
@ -44,6 +47,9 @@
* inode_sb_list_lock
* inode->i_lock
* inode_lru_lock
*
* inode_wb_list_lock
* inode->i_lock
*/
/*
@ -105,6 +111,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
DEFINE_SPINLOCK(inode_lock);
__cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
__cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_wb_list_lock);
/*
* iprune_sem provides exclusion between the icache shrinking and the
@ -483,10 +490,7 @@ static void evict(struct inode *inode)
BUG_ON(!(inode->i_state & I_FREEING));
BUG_ON(!list_empty(&inode->i_lru));
spin_lock(&inode_lock);
list_del_init(&inode->i_wb_list);
spin_unlock(&inode_lock);
inode_wb_list_del(inode);
inode_sb_list_del(inode);
if (op->evict_inode) {