0001
0002
0003
0004
0005
0006 #include <linux/pagemap.h>
0007 #include <linux/kernel.h>
0008 #include <linux/mm.h>
0009 #include <linux/fs.h>
0010 #include <linux/writeback.h>
0011 #include <linux/sysctl.h>
0012 #include <linux/gfp.h>
0013 #include "internal.h"
0014
0015
0016 int sysctl_drop_caches;
0017
0018 static void drop_pagecache_sb(struct super_block *sb, void *unused)
0019 {
0020 struct inode *inode, *toput_inode = NULL;
0021
0022 spin_lock(&sb->s_inode_list_lock);
0023 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
0024 spin_lock(&inode->i_lock);
0025
0026
0027
0028
0029
0030 if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
0031 (mapping_empty(inode->i_mapping) && !need_resched())) {
0032 spin_unlock(&inode->i_lock);
0033 continue;
0034 }
0035 __iget(inode);
0036 spin_unlock(&inode->i_lock);
0037 spin_unlock(&sb->s_inode_list_lock);
0038
0039 invalidate_mapping_pages(inode->i_mapping, 0, -1);
0040 iput(toput_inode);
0041 toput_inode = inode;
0042
0043 cond_resched();
0044 spin_lock(&sb->s_inode_list_lock);
0045 }
0046 spin_unlock(&sb->s_inode_list_lock);
0047 iput(toput_inode);
0048 }
0049
0050 int drop_caches_sysctl_handler(struct ctl_table *table, int write,
0051 void *buffer, size_t *length, loff_t *ppos)
0052 {
0053 int ret;
0054
0055 ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
0056 if (ret)
0057 return ret;
0058 if (write) {
0059 static int stfu;
0060
0061 if (sysctl_drop_caches & 1) {
0062 iterate_supers(drop_pagecache_sb, NULL);
0063 count_vm_event(DROP_PAGECACHE);
0064 }
0065 if (sysctl_drop_caches & 2) {
0066 drop_slab();
0067 count_vm_event(DROP_SLAB);
0068 }
0069 if (!stfu) {
0070 pr_info("%s (%d): drop_caches: %d\n",
0071 current->comm, task_pid_nr(current),
0072 sysctl_drop_caches);
0073 }
0074 stfu |= sysctl_drop_caches & 4;
0075 }
0076 return 0;
0077 }