aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c131
1 files changed, 81 insertions, 50 deletions
diff --git a/fs/super.c b/fs/super.c
index 68307c029228..0225c20f8770 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,46 +69,62 @@ 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 && 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, sc->nid);
76
77 total_objects = sb->s_nr_dentry_unused +
78 sb->s_nr_inodes_unused + fs_objects + 1;
79
80 if (sc->nr_to_scan) {
81 int dentries;
82 int inodes;
83
84 /* proportion the scan between the caches */
85 dentries = (sc->nr_to_scan * sb->s_nr_dentry_unused) /
86 total_objects;
87 inodes = (sc->nr_to_scan * sb->s_nr_inodes_unused) /
88 total_objects;
89 if (fs_objects)
90 fs_objects = (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 80
99 if (fs_objects && sb->s_op->free_cached_objects) { 81 inodes = list_lru_count_node(&sb->s_inode_lru, sc->nid);
100 sb->s_op->free_cached_objects(sb, fs_objects); 82 dentries = list_lru_count_node(&sb->s_dentry_lru, sc->nid);
101 fs_objects = sb->s_op->nr_cached_objects(sb); 83 total_objects = dentries + inodes + fs_objects + 1;
102 } 84
103 total_objects = sb->s_nr_dentry_unused + 85 /* proportion the scan between the caches */
104 sb->s_nr_inodes_unused + fs_objects; 86 dentries = mult_frac(sc->nr_to_scan, dentries, total_objects);
87 inodes = mult_frac(sc->nr_to_scan, inodes, total_objects);
88
89 /*
90 * prune the dcache first as the icache is pinned by it, then
91 * prune the icache, followed by the filesystem specific caches
92 */
93 freed = prune_dcache_sb(sb, dentries, sc->nid);
94 freed += prune_icache_sb(sb, inodes, sc->nid);
95
96 if (fs_objects) {
97 fs_objects = mult_frac(sc->nr_to_scan, fs_objects,
98 total_objects);
99 freed += sb->s_op->free_cached_objects(sb, fs_objects,
100 sc->nid);
105 } 101 }
106 102
107 total_objects = (total_objects / 100) * sysctl_vfs_cache_pressure; 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 sc->nid);
121
122 total_objects += list_lru_count_node(&sb->s_dentry_lru,
123 sc->nid);
124 total_objects += list_lru_count_node(&sb->s_inode_lru,
125 sc->nid);
126
127 total_objects = vfs_pressure_ratio(total_objects);
108 drop_super(sb); 128 drop_super(sb);
109 return total_objects; 129 return total_objects;
110} 130}
@@ -152,15 +172,9 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
152 static const struct super_operations default_op; 172 static const struct super_operations default_op;
153 173
154 if (s) { 174 if (s) {
155 if (security_sb_alloc(s)) { 175 if (security_sb_alloc(s))
156 /* 176 goto out_free_sb;
157 * We cannot call security_sb_free() without 177
158 * security_sb_alloc() succeeding. So bail out manually
159 */
160 kfree(s);
161 s = NULL;
162 goto out;
163 }
164#ifdef CONFIG_SMP 178#ifdef CONFIG_SMP
165 s->s_files = alloc_percpu(struct list_head); 179 s->s_files = alloc_percpu(struct list_head);
166 if (!s->s_files) 180 if (!s->s_files)
@@ -181,9 +195,12 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
181 INIT_HLIST_NODE(&s->s_instances); 195 INIT_HLIST_NODE(&s->s_instances);
182 INIT_HLIST_BL_HEAD(&s->s_anon); 196 INIT_HLIST_BL_HEAD(&s->s_anon);
183 INIT_LIST_HEAD(&s->s_inodes); 197 INIT_LIST_HEAD(&s->s_inodes);
184 INIT_LIST_HEAD(&s->s_dentry_lru); 198
185 INIT_LIST_HEAD(&s->s_inode_lru); 199 if (list_lru_init(&s->s_dentry_lru))
186 spin_lock_init(&s->s_inode_lru_lock); 200 goto err_out;
201 if (list_lru_init(&s->s_inode_lru))
202 goto err_out_dentry_lru;
203
187 INIT_LIST_HEAD(&s->s_mounts); 204 INIT_LIST_HEAD(&s->s_mounts);
188 init_rwsem(&s->s_umount); 205 init_rwsem(&s->s_umount);
189 lockdep_set_class(&s->s_umount, &type->s_umount_key); 206 lockdep_set_class(&s->s_umount, &type->s_umount_key);
@@ -216,11 +233,16 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
216 s->cleancache_poolid = -1; 233 s->cleancache_poolid = -1;
217 234
218 s->s_shrink.seeks = DEFAULT_SEEKS; 235 s->s_shrink.seeks = DEFAULT_SEEKS;
219 s->s_shrink.shrink = prune_super; 236 s->s_shrink.scan_objects = super_cache_scan;
237 s->s_shrink.count_objects = super_cache_count;
220 s->s_shrink.batch = 1024; 238 s->s_shrink.batch = 1024;
239 s->s_shrink.flags = SHRINKER_NUMA_AWARE;
221 } 240 }
222out: 241out:
223 return s; 242 return s;
243
244err_out_dentry_lru:
245 list_lru_destroy(&s->s_dentry_lru);
224err_out: 246err_out:
225 security_sb_free(s); 247 security_sb_free(s);
226#ifdef CONFIG_SMP 248#ifdef CONFIG_SMP
@@ -228,6 +250,7 @@ err_out:
228 free_percpu(s->s_files); 250 free_percpu(s->s_files);
229#endif 251#endif
230 destroy_sb_writers(s); 252 destroy_sb_writers(s);
253out_free_sb:
231 kfree(s); 254 kfree(s);
232 s = NULL; 255 s = NULL;
233 goto out; 256 goto out;
@@ -241,6 +264,8 @@ err_out:
241 */ 264 */
242static inline void destroy_super(struct super_block *s) 265static inline void destroy_super(struct super_block *s)
243{ 266{
267 list_lru_destroy(&s->s_dentry_lru);
268 list_lru_destroy(&s->s_inode_lru);
244#ifdef CONFIG_SMP 269#ifdef CONFIG_SMP
245 free_percpu(s->s_files); 270 free_percpu(s->s_files);
246#endif 271#endif
@@ -300,6 +325,7 @@ void deactivate_locked_super(struct super_block *s)
300 325
301 /* caches are now gone, we can safely kill the shrinker now */ 326 /* caches are now gone, we can safely kill the shrinker now */
302 unregister_shrinker(&s->s_shrink); 327 unregister_shrinker(&s->s_shrink);
328
303 put_filesystem(fs); 329 put_filesystem(fs);
304 put_super(s); 330 put_super(s);
305 } else { 331 } else {
@@ -414,6 +440,11 @@ void generic_shutdown_super(struct super_block *sb)
414 440
415 evict_inodes(sb); 441 evict_inodes(sb);
416 442
443 if (sb->s_dio_done_wq) {
444 destroy_workqueue(sb->s_dio_done_wq);
445 sb->s_dio_done_wq = NULL;
446 }
447
417 if (sop->put_super) 448 if (sop->put_super)
418 sop->put_super(sb); 449 sop->put_super(sb);
419 450