diff options
author | Dave Chinner <dchinner@redhat.com> | 2011-03-22 07:23:40 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-24 21:16:32 -0400 |
commit | 55fa6091d83160ca772fc37cebae45d42695a708 (patch) | |
tree | 4df49f372032e30449e1a2dd64daf443e20b781c /fs/drop_caches.c | |
parent | f283c86afe6aa70b733d1ecebad5d9464943b774 (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/drop_caches.c')
-rw-r--r-- | fs/drop_caches.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/fs/drop_caches.c b/fs/drop_caches.c index 6c6f73ba0868..98b77c89494c 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/writeback.h> | 8 | #include <linux/writeback.h> |
9 | #include <linux/sysctl.h> | 9 | #include <linux/sysctl.h> |
10 | #include <linux/gfp.h> | 10 | #include <linux/gfp.h> |
11 | #include "internal.h" | ||
11 | 12 | ||
12 | /* A global variable is a bit ugly, but it keeps the code simple */ | 13 | /* A global variable is a bit ugly, but it keeps the code simple */ |
13 | int sysctl_drop_caches; | 14 | int sysctl_drop_caches; |
@@ -16,7 +17,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) | |||
16 | { | 17 | { |
17 | struct inode *inode, *toput_inode = NULL; | 18 | struct inode *inode, *toput_inode = NULL; |
18 | 19 | ||
19 | spin_lock(&inode_lock); | 20 | spin_lock(&inode_sb_list_lock); |
20 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { | 21 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { |
21 | spin_lock(&inode->i_lock); | 22 | spin_lock(&inode->i_lock); |
22 | if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) || | 23 | 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) | |||
26 | } | 27 | } |
27 | __iget(inode); | 28 | __iget(inode); |
28 | spin_unlock(&inode->i_lock); | 29 | spin_unlock(&inode->i_lock); |
29 | spin_unlock(&inode_lock); | 30 | spin_unlock(&inode_sb_list_lock); |
30 | invalidate_mapping_pages(inode->i_mapping, 0, -1); | 31 | invalidate_mapping_pages(inode->i_mapping, 0, -1); |
31 | iput(toput_inode); | 32 | iput(toput_inode); |
32 | toput_inode = inode; | 33 | toput_inode = inode; |
33 | spin_lock(&inode_lock); | 34 | spin_lock(&inode_sb_list_lock); |
34 | } | 35 | } |
35 | spin_unlock(&inode_lock); | 36 | spin_unlock(&inode_sb_list_lock); |
36 | iput(toput_inode); | 37 | iput(toput_inode); |
37 | } | 38 | } |
38 | 39 | ||