diff options
author | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
commit | 871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch) | |
tree | 8718f573808810c2a1e8cb8fb6ac469093ca2784 /fs/drop_caches.c | |
parent | 9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff) | |
download | FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2 FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip |
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized.
Changes are basically to make it look like kernel structure.
Diffstat (limited to 'fs/drop_caches.c')
-rw-r--r-- | fs/drop_caches.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/fs/drop_caches.c b/fs/drop_caches.c new file mode 100644 index 00000000..c00e055b --- /dev/null +++ b/fs/drop_caches.c @@ -0,0 +1,67 @@ +/* + * Implement the manual drop-all-pagecache function + */ + +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/fs.h> +#include <linux/writeback.h> +#include <linux/sysctl.h> +#include <linux/gfp.h> +#include "internal.h" + +/* A global variable is a bit ugly, but it keeps the code simple */ +int sysctl_drop_caches; + +static void drop_pagecache_sb(struct super_block *sb, void *unused) +{ + struct inode *inode, *toput_inode = NULL; + + spin_lock(&inode_sb_list_lock); + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { + spin_lock(&inode->i_lock); + if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) || + (inode->i_mapping->nrpages == 0)) { + spin_unlock(&inode->i_lock); + continue; + } + __iget(inode); + spin_unlock(&inode->i_lock); + spin_unlock(&inode_sb_list_lock); + invalidate_mapping_pages(inode->i_mapping, 0, -1); + iput(toput_inode); + toput_inode = inode; + spin_lock(&inode_sb_list_lock); + } + spin_unlock(&inode_sb_list_lock); + iput(toput_inode); +} + +static void drop_slab(void) +{ + int nr_objects; + struct shrink_control shrink = { + .gfp_mask = GFP_KERNEL, + }; + + do { + nr_objects = shrink_slab(&shrink, 1000, 1000); + } while (nr_objects > 10); +} + +int drop_caches_sysctl_handler(ctl_table *table, int write, + void __user *buffer, size_t *length, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec_minmax(table, write, buffer, length, ppos); + if (ret) + return ret; + if (write) { + if (sysctl_drop_caches & 1) + iterate_supers(drop_pagecache_sb, NULL); + if (sysctl_drop_caches & 2) + drop_slab(); + } + return 0; +} |