Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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_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 
 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 
  This page was automatically generated by the LXR engine.