diff options
author | Dave Chinner <dchinner@redhat.com> | 2011-03-22 07:23:41 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-24 21:17:51 -0400 |
commit | a66979abad090b2765a6c6790c9fdeab996833f2 (patch) | |
tree | e48b2d0fac8f96456286a503aeeb952620234961 /fs/inode.c | |
parent | 55fa6091d83160ca772fc37cebae45d42695a708 (diff) |
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 <dchinner@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/inode.c b/fs/inode.c index 785b1ab23ff0..239fdc08719e 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/posix_acl.h> | 26 | #include <linux/posix_acl.h> |
27 | #include <linux/ima.h> | 27 | #include <linux/ima.h> |
28 | #include <linux/cred.h> | 28 | #include <linux/cred.h> |
29 | #include "internal.h" | ||
29 | 30 | ||
30 | /* | 31 | /* |
31 | * inode locking rules. | 32 | * inode locking rules. |
@@ -36,6 +37,8 @@ | |||
36 | * inode_lru, inode->i_lru | 37 | * inode_lru, inode->i_lru |
37 | * inode_sb_list_lock protects: | 38 | * inode_sb_list_lock protects: |
38 | * sb->s_inodes, inode->i_sb_list | 39 | * sb->s_inodes, inode->i_sb_list |
40 | * inode_wb_list_lock protects: | ||
41 | * bdi->wb.b_{dirty,io,more_io}, inode->i_wb_list | ||
39 | * | 42 | * |
40 | * Lock ordering: | 43 | * Lock ordering: |
41 | * inode_lock | 44 | * inode_lock |
@@ -44,6 +47,9 @@ | |||
44 | * inode_sb_list_lock | 47 | * inode_sb_list_lock |
45 | * inode->i_lock | 48 | * inode->i_lock |
46 | * inode_lru_lock | 49 | * inode_lru_lock |
50 | * | ||
51 | * inode_wb_list_lock | ||
52 | * inode->i_lock | ||
47 | */ | 53 | */ |
48 | 54 | ||
49 | /* | 55 | /* |
@@ -105,6 +111,7 @@ static struct hlist_head *inode_hashtable __read_mostly; | |||
105 | DEFINE_SPINLOCK(inode_lock); | 111 | DEFINE_SPINLOCK(inode_lock); |
106 | 112 | ||
107 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock); | 113 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock); |
114 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_wb_list_lock); | ||
108 | 115 | ||
109 | /* | 116 | /* |
110 | * iprune_sem provides exclusion between the icache shrinking and the | 117 | * iprune_sem provides exclusion between the icache shrinking and the |
@@ -483,10 +490,7 @@ static void evict(struct inode *inode) | |||
483 | BUG_ON(!(inode->i_state & I_FREEING)); | 490 | BUG_ON(!(inode->i_state & I_FREEING)); |
484 | BUG_ON(!list_empty(&inode->i_lru)); | 491 | BUG_ON(!list_empty(&inode->i_lru)); |
485 | 492 | ||
486 | spin_lock(&inode_lock); | 493 | inode_wb_list_del(inode); |
487 | list_del_init(&inode->i_wb_list); | ||
488 | spin_unlock(&inode_lock); | ||
489 | |||
490 | inode_sb_list_del(inode); | 494 | inode_sb_list_del(inode); |
491 | 495 | ||
492 | if (op->evict_inode) { | 496 | if (op->evict_inode) { |