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 */ 13 int sysctl_drop_caches; 14 15 static 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_WILL_FREE)) 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, true); 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 36 static void drop_pagecache(void) 37 { 38 struct super_block *sb; 39 40 spin_lock(&sb_lock); 41 restart: 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 56 static 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 65 int 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