--- linux-2.6.18/include/linux/fs.h 2006-09-19 23:42:06.000000000 -0400 +++ ups-kernel/include/linux/fs.h 2006-11-30 02:16:34.000000000 -0500 @@ -1625,7 +1625,8 @@ extern void remove_inode_hash(struct ino static inline void insert_inode_hash(struct inode *inode) { __insert_inode_hash(inode, inode->i_ino); } - +extern void void drop_pagecache_sb(struct super_block *sb, int nr_goal);:q + extern struct file * get_empty_filp(void); extern void file_move(struct file *f, struct list_head *list); extern void file_kill(struct file *f); --- linux-2.6.18/fs/drop_caches.c 2006-09-19 23:42:06.000000000 -0400 +++ ups-kernel/fs/drop_caches.c 2006-11-30 03:36:11.000000000 -0500 @@ -12,13 +12,20 @@ /* 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 drop_pagecache_sb(struct super_block *sb, int nr_goal) { struct inode *inode; + int nr_count=0; spin_lock(&inode_lock); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { - if (inode->i_state & (I_FREEING|I_WILL_FREE)) + if (nr_goal) { + if (nr_goal == nr_count) + break; + if ((inode->i_state || atomic_read(&inode->i_count)) + continue; + nr_count++; + } else if (inode->i_state & (I_FREEING|I_WILL_FREE)) continue; invalidate_inode_pages(inode->i_mapping); } @@ -36,7 +43,7 @@ restart: spin_unlock(&sb_lock); down_read(&sb->s_umount); if (sb->s_root) - drop_pagecache_sb(sb); + drop_pagecache_sb(sb, 0); up_read(&sb->s_umount); spin_lock(&sb_lock); if (__put_super_and_need_restart(sb)) @@ -66,3 +73,6 @@ int drop_caches_sysctl_handler(ctl_table } return 0; } + +EXPORT_SYMBOL(drop_pagecache_sb); +