diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/super.c | 45 |
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); | |||
48 | static int prune_super(struct shrinker *shrink, struct shrink_control *sc) | 48 | static 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 | /** |