aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/super.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/fs/super.c b/fs/super.c
index 37a75410079e..5101f0544960 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -48,7 +48,8 @@ DEFINE_SPINLOCK(sb_lock);
48static int prune_super(struct shrinker *shrink, struct shrink_control *sc) 48static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
49{ 49{
50 struct super_block *sb; 50 struct super_block *sb;
51 int count; 51 int fs_objects = 0;
52 int total_objects;
52 53
53 sb = container_of(shrink, struct super_block, s_shrink); 54 sb = container_of(shrink, struct super_block, s_shrink);
54 55
@@ -62,22 +63,42 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
62 if (!grab_super_passive(sb)) 63 if (!grab_super_passive(sb))
63 return -1; 64 return -1;
64 65
65 if (sc->nr_to_scan) { 66 if (sb->s_op && sb->s_op->nr_cached_objects)
66 /* proportion the scan between the two caches */ 67 fs_objects = sb->s_op->nr_cached_objects(sb);
67 int total; 68
69 total_objects = sb->s_nr_dentry_unused +
70 sb->s_nr_inodes_unused + fs_objects + 1;
68 71
69 total = sb->s_nr_dentry_unused + sb->s_nr_inodes_unused + 1; 72 if (sc->nr_to_scan) {
70 count = (sc->nr_to_scan * sb->s_nr_dentry_unused) / total; 73 int dentries;
74 int inodes;
75
76 /* proportion the scan between the caches */
77 dentries = (sc->nr_to_scan * sb->s_nr_dentry_unused) /
78 total_objects;
79 inodes = (sc->nr_to_scan * sb->s_nr_inodes_unused) /
80 total_objects;
81 if (fs_objects)
82 fs_objects = (sc->nr_to_scan * fs_objects) /
83 total_objects;
84 /*
85 * prune the dcache first as the icache is pinned by it, then
86 * prune the icache, followed by the filesystem specific caches
87 */
88 prune_dcache_sb(sb, dentries);
89 prune_icache_sb(sb, inodes);
71 90
72 /* prune dcache first as icache is pinned by it */ 91 if (fs_objects && sb->s_op->free_cached_objects) {
73 prune_dcache_sb(sb, count); 92 sb->s_op->free_cached_objects(sb, fs_objects);
74 prune_icache_sb(sb, sc->nr_to_scan - count); 93 fs_objects = sb->s_op->nr_cached_objects(sb);
94 }
95 total_objects = sb->s_nr_dentry_unused +
96 sb->s_nr_inodes_unused + fs_objects;
75 } 97 }
76 98
77 count = ((sb->s_nr_dentry_unused + sb->s_nr_inodes_unused) / 100) 99 total_objects = (total_objects / 100) * sysctl_vfs_cache_pressure;
78 * sysctl_vfs_cache_pressure;
79 drop_super(sb); 100 drop_super(sb);
80 return count; 101 return total_objects;
81} 102}
82 103
83/** 104/**