From 07d45da616f8514651360b502314fc9554223a03 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 29 Apr 2008 00:58:57 -0700 Subject: fs/drop_caches.c: make 2 functions static Make the following needlessly global functions static: - drop_pagecache() - drop_slab() Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/drop_caches.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/drop_caches.c') diff --git a/fs/drop_caches.c b/fs/drop_caches.c index 59375efcf39..e2c6b6500c7 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c @@ -25,7 +25,7 @@ static void drop_pagecache_sb(struct super_block *sb) spin_unlock(&inode_lock); } -void drop_pagecache(void) +static void drop_pagecache(void) { struct super_block *sb; @@ -45,7 +45,7 @@ restart: spin_unlock(&sb_lock); } -void drop_slab(void) +static void drop_slab(void) { int nr_objects; -- cgit v1.2.3 From eccb95cee4f0d56faa46ef22fb94dd4a3578d3eb Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 29 Apr 2008 00:59:37 -0700 Subject: vfs: fix lock inversion in drop_pagecache_sb() Fix longstanding lock inversion in drop_pagecache_sb by dropping inode_lock before calling __invalidate_mapping_pages(). We just have to make sure inode won't go away from under us by keeping reference to it and putting the reference only after we have safely resumed the scan of the inode list. A bit tricky but not too bad... Signed-off-by: Jan Kara Cc: Fengguang Wu Cc: David Chinner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/drop_caches.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'fs/drop_caches.c') diff --git a/fs/drop_caches.c b/fs/drop_caches.c index e2c6b6500c7..50f9087635d 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c @@ -14,15 +14,21 @@ int sysctl_drop_caches; static void drop_pagecache_sb(struct super_block *sb) { - struct inode *inode; + struct inode *inode, *toput_inode = NULL; spin_lock(&inode_lock); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { if (inode->i_state & (I_FREEING|I_WILL_FREE)) continue; + __iget(inode); + spin_unlock(&inode_lock); __invalidate_mapping_pages(inode->i_mapping, 0, -1, true); + iput(toput_inode); + toput_inode = inode; + spin_lock(&inode_lock); } spin_unlock(&inode_lock); + iput(toput_inode); } static void drop_pagecache(void) -- cgit v1.2.3 From af065b8a19041554196971d8b6ae1459798d3b14 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 29 Apr 2008 00:59:39 -0700 Subject: vfs: skip inodes without pages to free in drop_pagecache_sb() Many inodes have no pagecache, so we can avoid lots of lock-takings. Signed-off-by: Jan Kara Cc: Fengguang Wu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/drop_caches.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/drop_caches.c') diff --git a/fs/drop_caches.c b/fs/drop_caches.c index 50f9087635d..3e5637fc377 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c @@ -20,6 +20,8 @@ static void drop_pagecache_sb(struct super_block *sb) list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { if (inode->i_state & (I_FREEING|I_WILL_FREE)) continue; + if (inode->i_mapping->nrpages == 0) + continue; __iget(inode); spin_unlock(&inode_lock); __invalidate_mapping_pages(inode->i_mapping, 0, -1, true); -- cgit v1.2.3