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.
7 AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK], [
8 ZFS_LINUX_TEST_SRC([super_block_s_shrink], [
11 int shrink(struct shrinker *s, struct shrink_control *sc)
14 static const struct super_block
15 sb __attribute__ ((unused)) = {
16 .s_shrink.shrink = shrink,
17 .s_shrink.seeks = DEFAULT_SEEKS,
23 AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK], [
24 AC_MSG_CHECKING([whether super_block has s_shrink])
25 ZFS_LINUX_TEST_RESULT([super_block_s_shrink], [
27 AC_DEFINE(HAVE_SHRINK, 1, [struct super_block has s_shrink])
36 dnl # The super_block structure was changed to use an hlist_node instead
37 dnl # of a list_head for the .s_instance linkage.
39 dnl # This was done in part to resolve a race in the iterate_supers_type()
40 dnl # function which was introduced in Linux 3.0 kernel. The iterator
41 dnl # was supposed to provide a safe way to call an arbitrary function on
42 dnl # all super blocks of a specific type. Unfortunately, because a
43 dnl # list_head was used it was possible for iterate_supers_type() to
44 dnl # get stuck spinning a super block which was just deactivated.
46 dnl # This can occur because when the list head is removed from the
47 dnl # fs_supers list it is reinitialized to point to itself. If the
48 dnl # iterate_supers_type() function happened to be processing the
49 dnl # removed list_head it will get stuck spinning on that list_head.
51 dnl # To resolve the issue for existing 3.0 - 3.2 kernels we detect when
52 dnl # a list_head is used. Then to prevent the spinning from occurring
53 dnl # the .next pointer is set to the fs_supers list_head which ensures
54 dnl # the iterate_supers_type() function will always terminate.
56 AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_INSTANCES_LIST_HEAD], [
57 ZFS_LINUX_TEST_SRC([super_block_s_instances_list_head], [
60 struct super_block sb __attribute__ ((unused));
61 INIT_LIST_HEAD(&sb.s_instances);
65 AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_INSTANCES_LIST_HEAD], [
66 AC_MSG_CHECKING([whether super_block has s_instances list_head])
67 ZFS_LINUX_TEST_RESULT([super_block_s_instances_list_head], [
69 AC_DEFINE(HAVE_S_INSTANCES_LIST_HEAD, 1,
70 [struct super_block has s_instances list_head])
76 AC_DEFUN([ZFS_AC_KERNEL_SRC_NR_CACHED_OBJECTS], [
77 ZFS_LINUX_TEST_SRC([nr_cached_objects], [
80 int nr_cached_objects(struct super_block *sb) { return 0; }
82 static const struct super_operations
83 sops __attribute__ ((unused)) = {
84 .nr_cached_objects = nr_cached_objects,
89 AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [
90 AC_MSG_CHECKING([whether sops->nr_cached_objects() exists])
91 ZFS_LINUX_TEST_RESULT([nr_cached_objects], [
93 AC_DEFINE(HAVE_NR_CACHED_OBJECTS, 1,
94 [sops->nr_cached_objects() exists])
100 AC_DEFUN([ZFS_AC_KERNEL_SRC_FREE_CACHED_OBJECTS], [
101 ZFS_LINUX_TEST_SRC([free_cached_objects], [
102 #include <linux/fs.h>
104 void free_cached_objects(struct super_block *sb, int x)
107 static const struct super_operations
108 sops __attribute__ ((unused)) = {
109 .free_cached_objects = free_cached_objects,
114 AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [
115 AC_MSG_CHECKING([whether sops->free_cached_objects() exists])
116 ZFS_LINUX_TEST_RESULT([free_cached_objects], [
118 AC_DEFINE(HAVE_FREE_CACHED_OBJECTS, 1,
119 [sops->free_cached_objects() exists])
126 dnl # 3.12 API change
127 dnl # The nid member was added to struct shrink_control to support
128 dnl # NUMA-aware shrinkers.
130 AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID], [
131 ZFS_LINUX_TEST_SRC([shrink_control_nid], [
132 #include <linux/fs.h>
134 struct shrink_control sc __attribute__ ((unused));
135 unsigned long scnidsize __attribute__ ((unused)) =
140 AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
141 AC_MSG_CHECKING([whether shrink_control has nid])
142 ZFS_LINUX_TEST_RESULT([shrink_control_nid], [
144 AC_DEFINE(SHRINK_CONTROL_HAS_NID, 1,
145 [struct shrink_control has nid])
151 AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [
152 ZFS_LINUX_TEST_SRC([shrinker_cb_2arg], [
153 #include <linux/mm.h>
154 int shrinker_cb(int nr_to_scan, gfp_t gfp_mask) { return 0; }
156 struct shrinker cache_shrinker = {
157 .shrink = shrinker_cb,
158 .seeks = DEFAULT_SEEKS,
160 register_shrinker(&cache_shrinker);
163 ZFS_LINUX_TEST_SRC([shrinker_cb_3arg], [
164 #include <linux/mm.h>
165 int shrinker_cb(struct shrinker *shrink, int nr_to_scan,
166 gfp_t gfp_mask) { return 0; }
168 struct shrinker cache_shrinker = {
169 .shrink = shrinker_cb,
170 .seeks = DEFAULT_SEEKS,
172 register_shrinker(&cache_shrinker);
175 ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control], [
176 #include <linux/mm.h>
177 int shrinker_cb(struct shrinker *shrink,
178 struct shrink_control *sc) { return 0; }
180 struct shrinker cache_shrinker = {
181 .shrink = shrinker_cb,
182 .seeks = DEFAULT_SEEKS,
184 register_shrinker(&cache_shrinker);
187 ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control_split], [
188 #include <linux/mm.h>
189 unsigned long shrinker_cb(struct shrinker *shrink,
190 struct shrink_control *sc) { return 0; }
192 struct shrinker cache_shrinker = {
193 .count_objects = shrinker_cb,
194 .scan_objects = shrinker_cb,
195 .seeks = DEFAULT_SEEKS,
197 register_shrinker(&cache_shrinker);
201 AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
203 dnl # 2.6.23 to 2.6.34 API change
204 dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask)
206 AC_MSG_CHECKING([whether old 2-argument shrinker exists])
207 ZFS_LINUX_TEST_RESULT([shrinker_cb_2arg], [
209 AC_DEFINE(HAVE_2ARGS_OLD_SHRINKER_CALLBACK, 1,
210 [old shrinker callback wants 2 args])
215 dnl # 2.6.35 - 2.6.39 API change
216 dnl # ->shrink(struct shrinker *,
217 dnl # int nr_to_scan, gfp_t gfp_mask)
219 AC_MSG_CHECKING([whether old 3-argument shrinker exists])
220 ZFS_LINUX_TEST_RESULT([shrinker_cb_3arg], [
222 AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1,
223 [old shrinker callback wants 3 args])
228 dnl # 3.0 - 3.11 API change
229 dnl # ->shrink(struct shrinker *,
230 dnl # struct shrink_control *sc)
233 [whether new 2-argument shrinker exists])
234 ZFS_LINUX_TEST_RESULT([shrinker_cb_shrink_control], [
236 AC_DEFINE(HAVE_2ARGS_NEW_SHRINKER_CALLBACK, 1,
237 [new shrinker callback wants 2 args])
242 dnl # 3.12 API change,
243 dnl # ->shrink() is logically split in to
244 dnl # ->count_objects() and ->scan_objects()
247 [whether ->count_objects callback exists])
248 ZFS_LINUX_TEST_RESULT(
249 [shrinker_cb_shrink_control_split], [
251 AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK,
252 1, [->count_objects exists])
254 ZFS_LINUX_TEST_ERROR([shrinker])
262 dnl # 2.6.39 API change,
263 dnl # Shrinker adjust to use common shrink_control structure.
265 AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT], [
266 ZFS_LINUX_TEST_SRC([shrink_control_struct], [
267 #include <linux/mm.h>
269 struct shrink_control sc __attribute__ ((unused));
272 sc.gfp_mask = GFP_KERNEL;
276 AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT], [
277 AC_MSG_CHECKING([whether struct shrink_control exists])
278 ZFS_LINUX_TEST_RESULT([shrink_control_struct], [
280 AC_DEFINE(HAVE_SHRINK_CONTROL_STRUCT, 1,
281 [struct shrink_control exists])
287 AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER], [
288 ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK
289 ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_INSTANCES_LIST_HEAD
290 ZFS_AC_KERNEL_SRC_NR_CACHED_OBJECTS
291 ZFS_AC_KERNEL_SRC_FREE_CACHED_OBJECTS
292 ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID
293 ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK
294 ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT
297 AC_DEFUN([ZFS_AC_KERNEL_SHRINKER], [
298 ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK
299 ZFS_AC_KERNEL_SUPER_BLOCK_S_INSTANCES_LIST_HEAD
300 ZFS_AC_KERNEL_NR_CACHED_OBJECTS
301 ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
302 ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID
303 ZFS_AC_KERNEL_SHRINKER_CALLBACK
304 ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT