]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - fs/f2fs/shrinker.c
f2fs: introduce a shrinker for mounted fs
[mirror_ubuntu-hirsute-kernel.git] / fs / f2fs / shrinker.c
CommitLineData
2658e50d
JK
1/*
2 * f2fs shrinker support
3 * the basic infra was copied from fs/ubifs/shrinker.c
4 *
5 * Copyright (c) 2015 Motorola Mobility
6 * Copyright (c) 2015 Jaegeuk Kim <jaegeuk@kernel.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/fs.h>
13#include <linux/f2fs_fs.h>
14
15#include "f2fs.h"
16
17static LIST_HEAD(f2fs_list);
18static DEFINE_SPINLOCK(f2fs_list_lock);
19static unsigned int shrinker_run_no;
20
21unsigned long f2fs_shrink_count(struct shrinker *shrink,
22 struct shrink_control *sc)
23{
24 struct f2fs_sb_info *sbi;
25 struct list_head *p;
26 unsigned long count = 0;
27
28 spin_lock(&f2fs_list_lock);
29 p = f2fs_list.next;
30 while (p != &f2fs_list) {
31 sbi = list_entry(p, struct f2fs_sb_info, s_list);
32
33 /* stop f2fs_put_super */
34 if (!mutex_trylock(&sbi->umount_mutex)) {
35 p = p->next;
36 continue;
37 }
38 spin_unlock(&f2fs_list_lock);
39
40 /* TODO: count # of objects */
41
42 spin_lock(&f2fs_list_lock);
43 p = p->next;
44 mutex_unlock(&sbi->umount_mutex);
45 }
46 spin_unlock(&f2fs_list_lock);
47 return count;
48}
49
50unsigned long f2fs_shrink_scan(struct shrinker *shrink,
51 struct shrink_control *sc)
52{
53 unsigned long nr = sc->nr_to_scan;
54 struct f2fs_sb_info *sbi;
55 struct list_head *p;
56 unsigned int run_no;
57 unsigned long freed = 0;
58
59 spin_lock(&f2fs_list_lock);
60 do {
61 run_no = ++shrinker_run_no;
62 } while (run_no == 0);
63 p = f2fs_list.next;
64 while (p != &f2fs_list) {
65 sbi = list_entry(p, struct f2fs_sb_info, s_list);
66
67 if (sbi->shrinker_run_no == run_no)
68 break;
69
70 /* stop f2fs_put_super */
71 if (!mutex_trylock(&sbi->umount_mutex)) {
72 p = p->next;
73 continue;
74 }
75 spin_unlock(&f2fs_list_lock);
76
77 sbi->shrinker_run_no = run_no;
78
79 /* TODO: shrink caches */
80
81 spin_lock(&f2fs_list_lock);
82 p = p->next;
83 list_move_tail(&sbi->s_list, &f2fs_list);
84 mutex_unlock(&sbi->umount_mutex);
85 if (freed >= nr)
86 break;
87 }
88 spin_unlock(&f2fs_list_lock);
89 return freed;
90}
91
92void f2fs_join_shrinker(struct f2fs_sb_info *sbi)
93{
94 spin_lock(&f2fs_list_lock);
95 list_add_tail(&sbi->s_list, &f2fs_list);
96 spin_unlock(&f2fs_list_lock);
97}
98
99void f2fs_leave_shrinker(struct f2fs_sb_info *sbi)
100{
101 spin_lock(&f2fs_list_lock);
102 list_del(&sbi->s_list);
103 spin_unlock(&f2fs_list_lock);
104}