Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[linux-2.6.git] / fs / drop_caches.c
index 03ea769..31f4b0e 100644 (file)
@@ -14,18 +14,26 @@ 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))
+               if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
                        continue;
+               if (inode->i_mapping->nrpages == 0)
+                       continue;
+               __iget(inode);
+               spin_unlock(&inode_lock);
                invalidate_mapping_pages(inode->i_mapping, 0, -1);
+               iput(toput_inode);
+               toput_inode = inode;
+               spin_lock(&inode_lock);
        }
        spin_unlock(&inode_lock);
+       iput(toput_inode);
 }
 
-void drop_pagecache(void)
+static void drop_pagecache(void)
 {
        struct super_block *sb;
 
@@ -45,7 +53,7 @@ restart:
        spin_unlock(&sb_lock);
 }
 
-void drop_slab(void)
+static void drop_slab(void)
 {
        int nr_objects;
 
@@ -55,9 +63,9 @@ void drop_slab(void)
 }
 
 int drop_caches_sysctl_handler(ctl_table *table, int write,
-       struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
+       void __user *buffer, size_t *length, loff_t *ppos)
 {
-       proc_dointvec_minmax(table, write, file, buffer, length, ppos);
+       proc_dointvec_minmax(table, write, buffer, length, ppos);
        if (write) {
                if (sysctl_drop_caches & 1)
                        drop_pagecache();