aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c80
1 files changed, 49 insertions, 31 deletions
diff --git a/fs/super.c b/fs/super.c
index 3c5318694ccd..8aa2660642b9 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -53,11 +53,15 @@ static char *sb_writers_name[SB_FREEZE_LEVELS] = {
53 * shrinker path and that leads to deadlock on the shrinker_rwsem. Hence we 53 * shrinker path and that leads to deadlock on the shrinker_rwsem. Hence we
54 * take a passive reference to the superblock to avoid this from occurring. 54 * take a passive reference to the superblock to avoid this from occurring.
55 */ 55 */
56static int prune_super(struct shrinker *shrink, struct shrink_control *sc) 56static unsigned long super_cache_scan(struct shrinker *shrink,
57 struct shrink_control *sc)
57{ 58{
58 struct super_block *sb; 59 struct super_block *sb;
59 int fs_objects = 0; 60 long fs_objects = 0;
60 int total_objects; 61 long total_objects;
62 long freed = 0;
63 long dentries;
64 long inodes;
61 65
62 sb = container_of(shrink, struct super_block, s_shrink); 66 sb = container_of(shrink, struct super_block, s_shrink);
63 67
@@ -65,11 +69,11 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
65 * Deadlock avoidance. We may hold various FS locks, and we don't want 69 * Deadlock avoidance. We may hold various FS locks, and we don't want
66 * to recurse into the FS that called us in clear_inode() and friends.. 70 * to recurse into the FS that called us in clear_inode() and friends..
67 */ 71 */
68 if (sc->nr_to_scan && !(sc->gfp_mask & __GFP_FS)) 72 if (!(sc->gfp_mask & __GFP_FS))
69 return -1; 73 return SHRINK_STOP;
70 74
71 if (!grab_super_passive(sb)) 75 if (!grab_super_passive(sb))
72 return -1; 76 return SHRINK_STOP;
73 77
74 if (sb->s_op->nr_cached_objects) 78 if (sb->s_op->nr_cached_objects)
75 fs_objects = sb->s_op->nr_cached_objects(sb); 79 fs_objects = sb->s_op->nr_cached_objects(sb);
@@ -77,33 +81,46 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
77 total_objects = sb->s_nr_dentry_unused + 81 total_objects = sb->s_nr_dentry_unused +
78 sb->s_nr_inodes_unused + fs_objects + 1; 82 sb->s_nr_inodes_unused + fs_objects + 1;
79 83
80 if (sc->nr_to_scan) { 84 /* proportion the scan between the caches */
81 int dentries; 85 dentries = mult_frac(sc->nr_to_scan, sb->s_nr_dentry_unused,
82 int inodes; 86 total_objects);
83 87 inodes = mult_frac(sc->nr_to_scan, sb->s_nr_inodes_unused,
84 /* proportion the scan between the caches */ 88 total_objects);
85 dentries = mult_frac(sc->nr_to_scan, sb->s_nr_dentry_unused,
86 total_objects);
87 inodes = mult_frac(sc->nr_to_scan, sb->s_nr_inodes_unused,
88 total_objects);
89 if (fs_objects)
90 fs_objects = mult_frac(sc->nr_to_scan, fs_objects,
91 total_objects);
92 /*
93 * prune the dcache first as the icache is pinned by it, then
94 * prune the icache, followed by the filesystem specific caches
95 */
96 prune_dcache_sb(sb, dentries);
97 prune_icache_sb(sb, inodes);
98 89
99 if (fs_objects && sb->s_op->free_cached_objects) { 90 /*
100 sb->s_op->free_cached_objects(sb, fs_objects); 91 * prune the dcache first as the icache is pinned by it, then
101 fs_objects = sb->s_op->nr_cached_objects(sb); 92 * prune the icache, followed by the filesystem specific caches
102 } 93 */
103 total_objects = sb->s_nr_dentry_unused + 94 freed = prune_dcache_sb(sb, dentries);
104 sb->s_nr_inodes_unused + fs_objects; 95 freed += prune_icache_sb(sb, inodes);
96
97 if (fs_objects) {
98 fs_objects = mult_frac(sc->nr_to_scan, fs_objects,
99 total_objects);
100 freed += sb->s_op->free_cached_objects(sb, fs_objects);
105 } 101 }
106 102
103 drop_super(sb);
104 return freed;
105}
106
107static unsigned long super_cache_count(struct shrinker *shrink,
108 struct shrink_control *sc)
109{
110 struct super_block *sb;
111 long total_objects = 0;
112
113 sb = container_of(shrink, struct super_block, s_shrink);
114
115 if (!grab_super_passive(sb))
116 return 0;
117
118 if (sb->s_op && sb->s_op->nr_cached_objects)
119 total_objects = sb->s_op->nr_cached_objects(sb);
120
121 total_objects += sb->s_nr_dentry_unused;
122 total_objects += sb->s_nr_inodes_unused;
123
107 total_objects = vfs_pressure_ratio(total_objects); 124 total_objects = vfs_pressure_ratio(total_objects);
108 drop_super(sb); 125 drop_super(sb);
109 return total_objects; 126 return total_objects;
@@ -211,7 +228,8 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
211 s->cleancache_poolid = -1; 228 s->cleancache_poolid = -1;
212 229
213 s->s_shrink.seeks = DEFAULT_SEEKS; 230 s->s_shrink.seeks = DEFAULT_SEEKS;
214 s->s_shrink.shrink = prune_super; 231 s->s_shrink.scan_objects = super_cache_scan;
232 s->s_shrink.count_objects = super_cache_count;
215 s->s_shrink.batch = 1024; 233 s->s_shrink.batch = 1024;
216 } 234 }
217out: 235out: