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:
Dave Chinner 2011-03-22 22:23:40 +11:00 committed by Al Viro
parent f283c86afe
commit 55fa6091d8
6 changed files with 67 additions and 56 deletions

View file

@ -1123,7 +1123,7 @@ static void wait_sb_inodes(struct super_block *sb)
*/
WARN_ON(!rwsem_is_locked(&sb->s_umount));
spin_lock(&inode_lock);
spin_lock(&inode_sb_list_lock);
/*
* Data integrity sync. Must wait for all pages under writeback,
@ -1143,14 +1143,15 @@ static void wait_sb_inodes(struct super_block *sb)
}
__iget(inode);
spin_unlock(&inode->i_lock);
spin_unlock(&inode_lock);
spin_unlock(&inode_sb_list_lock);
/*
* We hold a reference to 'inode' so it couldn't have
* been removed from s_inodes list while we dropped the
* inode_lock. We cannot iput the inode now as we can
* be holding the last reference and we cannot iput it
* under inode_lock. So we keep the reference and iput
* it later.
* We hold a reference to 'inode' so it couldn't have been
* removed from s_inodes list while we dropped the
* inode_sb_list_lock. We cannot iput the inode now as we can
* be holding the last reference and we cannot iput it under
* inode_sb_list_lock. So we keep the reference and iput it
* later.
*/
iput(old_inode);
old_inode = inode;
@ -1159,9 +1160,9 @@ static void wait_sb_inodes(struct super_block *sb)
cond_resched();
spin_lock(&inode_lock);
spin_lock(&inode_sb_list_lock);
}
spin_unlock(&inode_lock);
spin_unlock(&inode_sb_list_lock);
iput(old_inode);
}