Root/fs/drop_caches.c

1/*
2 * Implement the manual drop-all-pagecache function
3 */
4
5#include <linux/kernel.h>
6#include <linux/mm.h>
7#include <linux/fs.h>
8#include <linux/writeback.h>
9#include <linux/sysctl.h>
10#include <linux/gfp.h>
11
12/* A global variable is a bit ugly, but it keeps the code simple */
13int sysctl_drop_caches;
14
15static void drop_pagecache_sb(struct super_block *sb)
16{
17    struct inode *inode, *toput_inode = NULL;
18
19    spin_lock(&inode_lock);
20    list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
21        if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
22            continue;
23        if (inode->i_mapping->nrpages == 0)
24            continue;
25        __iget(inode);
26        spin_unlock(&inode_lock);
27        invalidate_mapping_pages(inode->i_mapping, 0, -1);
28        iput(toput_inode);
29        toput_inode = inode;
30        spin_lock(&inode_lock);
31    }
32    spin_unlock(&inode_lock);
33    iput(toput_inode);
34}
35
36static void drop_pagecache(void)
37{
38    struct super_block *sb;
39
40    spin_lock(&sb_lock);
41restart:
42    list_for_each_entry(sb, &super_blocks, s_list) {
43        sb->s_count++;
44        spin_unlock(&sb_lock);
45        down_read(&sb->s_umount);
46        if (sb->s_root)
47            drop_pagecache_sb(sb);
48        up_read(&sb->s_umount);
49        spin_lock(&sb_lock);
50        if (__put_super_and_need_restart(sb))
51            goto restart;
52    }
53    spin_unlock(&sb_lock);
54}
55
56static void drop_slab(void)
57{
58    int nr_objects;
59
60    do {
61        nr_objects = shrink_slab(1000, GFP_KERNEL, 1000);
62    } while (nr_objects > 10);
63}
64
65int drop_caches_sysctl_handler(ctl_table *table, int write,
66    struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
67{
68    proc_dointvec_minmax(table, write, file, buffer, length, ppos);
69    if (write) {
70        if (sysctl_drop_caches & 1)
71            drop_pagecache();
72        if (sysctl_drop_caches & 2)
73            drop_slab();
74    }
75    return 0;
76}
77

Archive Download this file



interactive