]>
Commit | Line | Data |
---|---|---|
ab26409d BB |
1 | dnl # |
2 | dnl # 3.1 API change | |
3 | dnl # The super_block structure now stores a per-filesystem shrinker. | |
4 | dnl # This interface is preferable because it can be used to specifically | |
5 | dnl # target only the zfs filesystem for pruning. | |
6 | dnl # | |
7 | AC_DEFUN([ZFS_AC_KERNEL_SHRINK], [ | |
8 | AC_MSG_CHECKING([whether super_block has s_shrink]) | |
9 | ZFS_LINUX_TRY_COMPILE([ | |
10 | #include <linux/fs.h> | |
c38367c7 RY |
11 | |
12 | int shrink(struct shrinker *s, struct shrink_control *sc) | |
13 | { return 0; } | |
14 | ||
15 | static const struct super_block | |
16 | sb __attribute__ ((unused)) = { | |
ab26409d BB |
17 | .s_shrink.shrink = shrink, |
18 | .s_shrink.seeks = DEFAULT_SEEKS, | |
19 | .s_shrink.batch = 0, | |
20 | }; | |
c38367c7 | 21 | ],[ |
ab26409d BB |
22 | ],[ |
23 | AC_MSG_RESULT(yes) | |
24 | AC_DEFINE(HAVE_SHRINK, 1, [struct super_block has s_shrink]) | |
25 | ||
26 | ],[ | |
27 | AC_MSG_RESULT(no) | |
dba1d705 BB |
28 | ]) |
29 | ]) | |
30 | ||
31 | dnl # | |
32 | dnl # 3.3 API change | |
33 | dnl # The super_block structure was changed to use an hlist_node instead | |
34 | dnl # of a list_head for the .s_instance linkage. | |
35 | dnl # | |
36 | dnl # This was done in part to resolve a race in the iterate_supers_type() | |
37 | dnl # function which was introduced in Linux 3.0 kernel. The iterator | |
38 | dnl # was supposed to provide a safe way to call an arbitrary function on | |
39 | dnl # all super blocks of a specific type. Unfortunately, because a | |
40 | dnl # list_head was used it was possible for iterate_supers_type() to | |
41 | dnl # get stuck spinning a super block which was just deactivated. | |
42 | dnl # | |
43 | dnl # This can occur because when the list head is removed from the | |
44 | dnl # fs_supers list it is reinitialized to point to itself. If the | |
45 | dnl # iterate_supers_type() function happened to be processing the | |
46 | dnl # removed list_head it will get stuck spinning on that list_head. | |
47 | dnl # | |
48 | dnl # To resolve the issue for existing 3.0 - 3.2 kernels we detect when | |
49 | dnl # a list_head is used. Then to prevent the spinning from occurring | |
50 | dnl # the .next pointer is set to the fs_supers list_head which ensures | |
51 | dnl # the iterate_supers_type() function will always terminate. | |
52 | dnl # | |
53 | AC_DEFUN([ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD], [ | |
54 | AC_MSG_CHECKING([whether super_block has s_instances list_head]) | |
55 | ZFS_LINUX_TRY_COMPILE([ | |
56 | #include <linux/fs.h> | |
57 | ],[ | |
58 | struct super_block sb __attribute__ ((unused)); | |
59 | ||
60 | INIT_LIST_HEAD(&sb.s_instances); | |
61 | ],[ | |
62 | AC_MSG_RESULT(yes) | |
63 | AC_DEFINE(HAVE_S_INSTANCES_LIST_HEAD, 1, | |
64 | [struct super_block has s_instances list_head]) | |
65 | ],[ | |
66 | AC_MSG_RESULT(no) | |
ab26409d BB |
67 | ]) |
68 | ]) | |
69 | ||
70 | AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [ | |
71 | AC_MSG_CHECKING([whether sops->nr_cached_objects() exists]) | |
72 | ZFS_LINUX_TRY_COMPILE([ | |
73 | #include <linux/fs.h> | |
c38367c7 RY |
74 | |
75 | int nr_cached_objects(struct super_block *sb) { return 0; } | |
76 | ||
77 | static const struct super_operations | |
78 | sops __attribute__ ((unused)) = { | |
ab26409d BB |
79 | .nr_cached_objects = nr_cached_objects, |
80 | }; | |
c38367c7 | 81 | ],[ |
ab26409d BB |
82 | ],[ |
83 | AC_MSG_RESULT(yes) | |
84 | AC_DEFINE(HAVE_NR_CACHED_OBJECTS, 1, | |
85 | [sops->nr_cached_objects() exists]) | |
86 | ],[ | |
87 | AC_MSG_RESULT(no) | |
88 | ]) | |
89 | ]) | |
90 | ||
91 | AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [ | |
92 | AC_MSG_CHECKING([whether sops->free_cached_objects() exists]) | |
93 | ZFS_LINUX_TRY_COMPILE([ | |
94 | #include <linux/fs.h> | |
c38367c7 RY |
95 | |
96 | void free_cached_objects(struct super_block *sb, int x) | |
97 | { return; } | |
98 | ||
99 | static const struct super_operations | |
100 | sops __attribute__ ((unused)) = { | |
ab26409d BB |
101 | .free_cached_objects = free_cached_objects, |
102 | }; | |
c38367c7 | 103 | ],[ |
ab26409d BB |
104 | ],[ |
105 | AC_MSG_RESULT(yes) | |
106 | AC_DEFINE(HAVE_FREE_CACHED_OBJECTS, 1, | |
107 | [sops->free_cached_objects() exists]) | |
108 | ],[ | |
109 | AC_MSG_RESULT(no) | |
110 | ]) | |
111 | ]) | |
90947b23 TC |
112 | |
113 | dnl # | |
114 | dnl # 3.12 API change | |
115 | dnl # The nid member was added to struct shrink_control to support | |
116 | dnl # NUMA-aware shrinkers. | |
117 | dnl # | |
118 | AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [ | |
119 | AC_MSG_CHECKING([whether shrink_control has nid]) | |
120 | ZFS_LINUX_TRY_COMPILE([ | |
121 | #include <linux/fs.h> | |
122 | ],[ | |
123 | struct shrink_control sc __attribute__ ((unused)); | |
124 | unsigned long scnidsize __attribute__ ((unused)) = | |
125 | sizeof(sc.nid); | |
126 | ],[ | |
127 | AC_MSG_RESULT(yes) | |
128 | AC_DEFINE(SHRINK_CONTROL_HAS_NID, 1, | |
129 | [struct shrink_control has nid]) | |
130 | ],[ | |
131 | AC_MSG_RESULT(no) | |
132 | ]) | |
133 | ]) | |
93ce2b4c BB |
134 | |
135 | ||
136 | AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[ | |
137 | tmp_flags="$EXTRA_KCFLAGS" | |
138 | EXTRA_KCFLAGS="-Werror" | |
139 | dnl # | |
140 | dnl # 2.6.23 to 2.6.34 API change | |
141 | dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask) | |
142 | dnl # | |
143 | AC_MSG_CHECKING([whether old 2-argument shrinker exists]) | |
144 | ZFS_LINUX_TRY_COMPILE([ | |
145 | #include <linux/mm.h> | |
146 | ||
147 | int shrinker_cb(int nr_to_scan, gfp_t gfp_mask); | |
148 | ],[ | |
149 | struct shrinker cache_shrinker = { | |
150 | .shrink = shrinker_cb, | |
151 | .seeks = DEFAULT_SEEKS, | |
152 | }; | |
153 | register_shrinker(&cache_shrinker); | |
154 | ],[ | |
155 | AC_MSG_RESULT(yes) | |
156 | AC_DEFINE(HAVE_2ARGS_OLD_SHRINKER_CALLBACK, 1, | |
157 | [old shrinker callback wants 2 args]) | |
158 | ],[ | |
159 | AC_MSG_RESULT(no) | |
160 | dnl # | |
161 | dnl # 2.6.35 - 2.6.39 API change | |
162 | dnl # ->shrink(struct shrinker *, | |
163 | dnl # int nr_to_scan, gfp_t gfp_mask) | |
164 | dnl # | |
165 | AC_MSG_CHECKING([whether old 3-argument shrinker exists]) | |
166 | ZFS_LINUX_TRY_COMPILE([ | |
167 | #include <linux/mm.h> | |
168 | ||
169 | int shrinker_cb(struct shrinker *, int nr_to_scan, | |
170 | gfp_t gfp_mask); | |
171 | ],[ | |
172 | struct shrinker cache_shrinker = { | |
173 | .shrink = shrinker_cb, | |
174 | .seeks = DEFAULT_SEEKS, | |
175 | }; | |
176 | register_shrinker(&cache_shrinker); | |
177 | ],[ | |
178 | AC_MSG_RESULT(yes) | |
179 | AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1, | |
180 | [old shrinker callback wants 3 args]) | |
181 | ],[ | |
182 | AC_MSG_RESULT(no) | |
183 | dnl # | |
184 | dnl # 3.0 - 3.11 API change | |
185 | dnl # ->shrink(struct shrinker *, | |
186 | dnl # struct shrink_control *sc) | |
187 | dnl # | |
188 | AC_MSG_CHECKING( | |
189 | [whether new 2-argument shrinker exists]) | |
190 | ZFS_LINUX_TRY_COMPILE([ | |
191 | #include <linux/mm.h> | |
192 | ||
193 | int shrinker_cb(struct shrinker *, | |
194 | struct shrink_control *sc); | |
195 | ],[ | |
196 | struct shrinker cache_shrinker = { | |
197 | .shrink = shrinker_cb, | |
198 | .seeks = DEFAULT_SEEKS, | |
199 | }; | |
200 | register_shrinker(&cache_shrinker); | |
201 | ],[ | |
202 | AC_MSG_RESULT(yes) | |
203 | AC_DEFINE(HAVE_2ARGS_NEW_SHRINKER_CALLBACK, 1, | |
204 | [new shrinker callback wants 2 args]) | |
205 | ],[ | |
206 | AC_MSG_RESULT(no) | |
207 | dnl # | |
208 | dnl # 3.12 API change, | |
209 | dnl # ->shrink() is logically split in to | |
210 | dnl # ->count_objects() and ->scan_objects() | |
211 | dnl # | |
212 | AC_MSG_CHECKING( | |
213 | [whether ->count_objects callback exists]) | |
214 | ZFS_LINUX_TRY_COMPILE([ | |
215 | #include <linux/mm.h> | |
216 | ||
217 | unsigned long shrinker_cb( | |
218 | struct shrinker *, | |
219 | struct shrink_control *sc); | |
220 | ],[ | |
221 | struct shrinker cache_shrinker = { | |
222 | .count_objects = shrinker_cb, | |
223 | .scan_objects = shrinker_cb, | |
224 | .seeks = DEFAULT_SEEKS, | |
225 | }; | |
226 | register_shrinker(&cache_shrinker); | |
227 | ],[ | |
228 | AC_MSG_RESULT(yes) | |
229 | AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK, | |
230 | 1, [->count_objects exists]) | |
231 | ],[ | |
232 | AC_MSG_ERROR(error) | |
233 | ]) | |
234 | ]) | |
235 | ]) | |
236 | ]) | |
237 | EXTRA_KCFLAGS="$tmp_flags" | |
238 | ]) | |
239 | ||
240 | dnl # | |
241 | dnl # 2.6.39 API change, | |
242 | dnl # Shrinker adjust to use common shrink_control structure. | |
243 | dnl # | |
244 | AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT], [ | |
245 | AC_MSG_CHECKING([whether struct shrink_control exists]) | |
246 | ZFS_LINUX_TRY_COMPILE([ | |
247 | #include <linux/mm.h> | |
248 | ],[ | |
249 | struct shrink_control sc __attribute__ ((unused)); | |
250 | ||
251 | sc.nr_to_scan = 0; | |
252 | sc.gfp_mask = GFP_KERNEL; | |
253 | ],[ | |
254 | AC_MSG_RESULT(yes) | |
255 | AC_DEFINE(HAVE_SHRINK_CONTROL_STRUCT, 1, | |
256 | [struct shrink_control exists]) | |
257 | ],[ | |
258 | AC_MSG_RESULT(no) | |
259 | ]) | |
260 | ]) |