summaryrefslogtreecommitdiffstats
path: root/testing
diff options
context:
space:
mode:
Diffstat (limited to 'testing')
-rw-r--r--testing/spl-grsec/linux-3.12.patch435
1 files changed, 435 insertions, 0 deletions
diff --git a/testing/spl-grsec/linux-3.12.patch b/testing/spl-grsec/linux-3.12.patch
new file mode 100644
index 000000000..105b0dcb2
--- /dev/null
+++ b/testing/spl-grsec/linux-3.12.patch
@@ -0,0 +1,435 @@
+From c3d9c0df3ee8d43db22815ebbfbe8b803fa46e46 Mon Sep 17 00:00:00 2001
+From: Richard Yao <ryao@gentoo.org>
+Date: Tue, 5 Nov 2013 11:35:54 -0500
+Subject: [PATCH] Linux 3.12 compat: New shrinker API
+
+torvalds/linux@24f7c6 introduced a new shrinker API while
+torvalds/linux@a0b021 dropped support for the old shrinker API.
+This patch adds support for the new shrinker API by wrapping
+the old one with the new one.
+
+This change also reorganizes the autotools checks on the shrinker
+API such that the configure script will fail early if an unknown
+API is encountered in the future.
+
+Support for the set_shrinker() API which was used by Linux 2.6.22
+and older has been dropped. As a general rule compatibility is
+only maintained back to Linux 2.6.26.
+
+Signed-off-by: Richard Yao <ryao@gentoo.org>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes zfsonlinux/zfs#1732
+Closes zfsonlinux/zfs#1822
+Closes #293
+Closes #307
+---
+ config/spl-build.m4 | 116 ++++++++++++++++++------
+ include/linux/mm_compat.h | 226 +++++++++++++++++++++++++++++-----------------
+ 2 files changed, 229 insertions(+), 113 deletions(-)
+
+diff --git a/config/spl-build.m4 b/config/spl-build.m4
+index b0e3348..7d744db 100644
+--- a/config/spl-build.m4
++++ b/config/spl-build.m4
+@@ -27,8 +27,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
+ SPL_AC_TYPE_ATOMIC64_XCHG
+ SPL_AC_TYPE_UINTPTR_T
+ SPL_AC_2ARGS_REGISTER_SYSCTL
+- SPL_AC_SET_SHRINKER
+- SPL_AC_3ARGS_SHRINKER_CALLBACK
++ SPL_AC_SHRINKER_CALLBACK
+ SPL_AC_PATH_IN_NAMEIDATA
+ SPL_AC_TASK_CURR
+ SPL_AC_CTL_UNNUMBERED
+@@ -885,37 +884,18 @@ AC_DEFUN([SPL_AC_2ARGS_REGISTER_SYSCTL],
+ ])
+ ])
+
+-dnl #
+-dnl # 2.6.23 API change
+-dnl # Old set_shrinker API replaced with register_shrinker
+-dnl #
+-AC_DEFUN([SPL_AC_SET_SHRINKER], [
+- AC_MSG_CHECKING([whether set_shrinker() available])
+- SPL_LINUX_TRY_COMPILE([
+- #include <linux/mm.h>
+- ],[
+- return set_shrinker(DEFAULT_SEEKS, NULL);
+- ],[
+- AC_MSG_RESULT([yes])
+- AC_DEFINE(HAVE_SET_SHRINKER, 1,
+- [set_shrinker() available])
+- ],[
+- AC_MSG_RESULT([no])
+- ])
+-])
+-
+-dnl #
+-dnl # 2.6.35 API change,
+-dnl # Add context to shrinker callback
+-dnl #
+-AC_DEFUN([SPL_AC_3ARGS_SHRINKER_CALLBACK],
+- [AC_MSG_CHECKING([whether shrinker callback wants 3 args])
++AC_DEFUN([SPL_AC_SHRINKER_CALLBACK],[
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
++ dnl #
++ dnl # 2.6.23 to 2.6.34 API change
++ dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask)
++ dnl #
++ AC_MSG_CHECKING([whether old 2-argument shrinker exists])
+ SPL_LINUX_TRY_COMPILE([
+ #include <linux/mm.h>
+
+- int shrinker_cb(struct shrinker *, int, unsigned int);
++ int shrinker_cb(int nr_to_scan, gfp_t gfp_mask);
+ ],[
+ struct shrinker cache_shrinker = {
+ .shrink = shrinker_cb,
+@@ -924,10 +904,86 @@ AC_DEFUN([SPL_AC_3ARGS_SHRINKER_CALLBACK],
+ register_shrinker(&cache_shrinker);
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1,
+- [shrinker callback wants 3 args])
++ AC_DEFINE(HAVE_2ARGS_OLD_SHRINKER_CALLBACK, 1,
++ [old shrinker callback wants 2 args])
+ ],[
+ AC_MSG_RESULT(no)
++ dnl #
++ dnl # 2.6.35 - 2.6.39 API change
++ dnl # ->shrink(struct shrinker *,
++ dnl # int nr_to_scan, gfp_t gfp_mask)
++ dnl #
++ AC_MSG_CHECKING([whether old 3-argument shrinker exists])
++ SPL_LINUX_TRY_COMPILE([
++ #include <linux/mm.h>
++
++ int shrinker_cb(struct shrinker *, int nr_to_scan,
++ gfp_t gfp_mask);
++ ],[
++ struct shrinker cache_shrinker = {
++ .shrink = shrinker_cb,
++ .seeks = DEFAULT_SEEKS,
++ };
++ register_shrinker(&cache_shrinker);
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1,
++ [old shrinker callback wants 3 args])
++ ],[
++ AC_MSG_RESULT(no)
++ dnl #
++ dnl # 3.0 - 3.11 API change
++ dnl # ->shrink(struct shrinker *,
++ dnl # struct shrink_control *sc)
++ dnl #
++ AC_MSG_CHECKING(
++ [whether new 2-argument shrinker exists])
++ SPL_LINUX_TRY_COMPILE([
++ #include <linux/mm.h>
++
++ int shrinker_cb(struct shrinker *,
++ struct shrink_control *sc);
++ ],[
++ struct shrinker cache_shrinker = {
++ .shrink = shrinker_cb,
++ .seeks = DEFAULT_SEEKS,
++ };
++ register_shrinker(&cache_shrinker);
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_2ARGS_NEW_SHRINKER_CALLBACK, 1,
++ [new shrinker callback wants 2 args])
++ ],[
++ AC_MSG_RESULT(no)
++ dnl #
++ dnl # 3.12 API change,
++ dnl # ->shrink() is logically split in to
++ dnl # ->count_objects() and ->scan_objects()
++ dnl #
++ AC_MSG_CHECKING(
++ [whether ->count_objects callback exists])
++ SPL_LINUX_TRY_COMPILE([
++ #include <linux/mm.h>
++
++ unsigned long shrinker_cb(
++ struct shrinker *,
++ struct shrink_control *sc);
++ ],[
++ struct shrinker cache_shrinker = {
++ .count_objects = shrinker_cb,
++ .scan_objects = shrinker_cb,
++ .seeks = DEFAULT_SEEKS,
++ };
++ register_shrinker(&cache_shrinker);
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK,
++ 1, [->count_objects exists])
++ ],[
++ AC_MSG_ERROR(error)
++ ])
++ ])
++ ])
+ ])
+ EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/include/linux/mm_compat.h b/include/linux/mm_compat.h
+index cb1bef9..37c9b08 100644
+--- a/include/linux/mm_compat.h
++++ b/include/linux/mm_compat.h
+@@ -148,107 +148,167 @@ typedef int (*shrink_icache_memory_t)(struct shrinker *,
+ #endif /* HAVE_SHRINK_ICACHE_MEMORY */
+
+ /*
+- * Linux 2.6. - 2.6. Shrinker API Compatibility.
++ * Due to frequent changes in the shrinker API the following
++ * compatibility wrappers should be used. They are as follows:
++ *
++ * SPL_SHRINKER_DECLARE is used to declare the shrinker which is
++ * passed to spl_register_shrinker()/spl_unregister_shrinker(). Use
++ * shrinker_name to set the shrinker variable name, shrinker_callback
++ * to set the callback function, and seek_cost to define the cost of
++ * reclaiming an object.
++ *
++ * SPL_SHRINKER_DECLARE(shrinker_name, shrinker_callback, seek_cost);
++ *
++ * SPL_SHRINKER_CALLBACK_FWD_DECLARE is used when a forward declaration
++ * of the shrinker callback function is required. Only the callback
++ * function needs to be passed.
++ *
++ * SPL_SHRINKER_CALLBACK_FWD_DECLARE(shrinker_callback);
++ *
++ * SPL_SHRINKER_CALLBACK_WRAPPER is used to declare the callback function
++ * which is registered with the shrinker. This function will call your
++ * custom shrinker which must use the following prototype. Notice the
++ * leading __'s, these must be appended to the callback_function name.
++ *
++ * int __shrinker_callback(struct shrinker *, struct shrink_control *)
++ * SPL_SHRINKER_CALLBACK_WRAPPER(shrinker_callback);a
++ *
++ *
++ * Example:
++ *
++ * SPL_SHRINKER_CALLBACK_FWD_DECLARE(my_shrinker_fn);
++ * SPL_SHRINKER_DECLARE(my_shrinker, my_shrinker_fn, 1);
++ *
++ * static int
++ * __my_shrinker_fn(struct shrinker *shrink, struct shrink_control *sc)
++ * {
++ * if (sc->nr_to_scan) {
++ * ...scan objects in the cache and reclaim them...
++ * }
++ *
++ * ...calculate number of objects in the cache...
++ *
++ * return (number of objects in the cache);
++ * }
++ * SPL_SHRINKER_CALLBACK_WRAPPER(my_shrinker_fn);
+ */
+-#ifdef HAVE_SET_SHRINKER
+-typedef struct spl_shrinker {
+- struct shrinker *shrinker;
+- shrinker_t fn;
+- int seeks;
+-} spl_shrinker_t;
+-
+-static inline void
+-spl_register_shrinker(spl_shrinker_t *ss)
+-{
+- ss->shrinker = set_shrinker(ss->seeks, ss->fn);
+-}
+
+-static inline void
+-spl_unregister_shrinker(spl_shrinker_t *ss)
+-{
+- remove_shrinker(ss->shrinker);
+-}
++#define spl_register_shrinker(x) register_shrinker(x)
++#define spl_unregister_shrinker(x) unregister_shrinker(x)
+
+-# define SPL_SHRINKER_DECLARE(s, x, y) \
+- static spl_shrinker_t s = { \
+- .shrinker = NULL, \
+- .fn = x, \
+- .seeks = y \
+- }
+-
+-# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
+- static int fn(int, unsigned int)
+-# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
+-static int \
+-fn(int nr_to_scan, unsigned int gfp_mask) \
+-{ \
+- struct shrink_control sc; \
+- \
+- sc.nr_to_scan = nr_to_scan; \
+- sc.gfp_mask = gfp_mask; \
+- \
+- return __ ## fn(NULL, &sc); \
++/*
++ * Linux 2.6.23 - 2.6.34 Shrinker API Compatibility.
++ */
++#if defined(HAVE_2ARGS_OLD_SHRINKER_CALLBACK)
++#define SPL_SHRINKER_DECLARE(s, x, y) \
++static struct shrinker s = { \
++ .shrink = x, \
++ .seeks = y \
+ }
+
+-#else
++#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
++static int fn(int nr_to_scan, unsigned int gfp_mask)
+
+-# define spl_register_shrinker(x) register_shrinker(x)
+-# define spl_unregister_shrinker(x) unregister_shrinker(x)
+-# define SPL_SHRINKER_DECLARE(s, x, y) \
+- static struct shrinker s = { \
+- .shrink = x, \
+- .seeks = y \
+- }
++#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
++static int \
++fn(int nr_to_scan, unsigned int gfp_mask) \
++{ \
++ struct shrink_control sc; \
++ \
++ sc.nr_to_scan = nr_to_scan; \
++ sc.gfp_mask = gfp_mask; \
++ \
++ return (__ ## fn(NULL, &sc)); \
++}
+
+ /*
+- * Linux 2.6. - 2.6. Shrinker API Compatibility.
++ * Linux 2.6.35 to 2.6.39 Shrinker API Compatibility.
+ */
+-# if defined(HAVE_SHRINK_CONTROL_STRUCT)
+-# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
+- static int fn(struct shrinker *, struct shrink_control *)
+-# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
+-static int \
+-fn(struct shrinker *shrink, struct shrink_control *sc) { \
+- return __ ## fn(shrink, sc); \
++#elif defined(HAVE_3ARGS_SHRINKER_CALLBACK)
++#define SPL_SHRINKER_DECLARE(s, x, y) \
++static struct shrinker s = { \
++ .shrink = x, \
++ .seeks = y \
++}
++
++#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
++static int fn(struct shrinker *, int, unsigned int)
++
++#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
++static int \
++fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask) \
++{ \
++ struct shrink_control sc; \
++ \
++ sc.nr_to_scan = nr_to_scan; \
++ sc.gfp_mask = gfp_mask; \
++ \
++ return (__ ## fn(shrink, &sc)); \
+ }
+
+ /*
+- * Linux 2.6. - 2.6. Shrinker API Compatibility.
++ * Linux 3.0 to 3.11 Shrinker API Compatibility.
+ */
+-# elif defined(HAVE_3ARGS_SHRINKER_CALLBACK)
+-# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
+- static int fn(struct shrinker *, int, unsigned int)
+-# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
+-static int \
+-fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask) \
+-{ \
+- struct shrink_control sc; \
+- \
+- sc.nr_to_scan = nr_to_scan; \
+- sc.gfp_mask = gfp_mask; \
+- \
+- return __ ## fn(shrink, &sc); \
++#elif defined(HAVE_2ARGS_NEW_SHRINKER_CALLBACK)
++#define SPL_SHRINKER_DECLARE(s, x, y) \
++static struct shrinker s = { \
++ .shrink = x, \
++ .seeks = y \
++}
++
++#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
++static int fn(struct shrinker *, struct shrink_control *)
++
++#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
++static int \
++fn(struct shrinker *shrink, struct shrink_control *sc) \
++{ \
++ return (__ ## fn(shrink, sc)); \
+ }
+
+ /*
+- * Linux 2.6. - 2.6. Shrinker API Compatibility.
++ * Linux 3.12 and later Shrinker API Compatibility.
+ */
+-# else
+-# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
+- static int fn(int, unsigned int)
+-# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
+-static int \
+-fn(int nr_to_scan, unsigned int gfp_mask) \
+-{ \
+- struct shrink_control sc; \
+- \
+- sc.nr_to_scan = nr_to_scan; \
+- sc.gfp_mask = gfp_mask; \
+- \
+- return __ ## fn(NULL, &sc); \
++#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK)
++#define SPL_SHRINKER_DECLARE(s, x, y) \
++static struct shrinker s = { \
++ .count_objects = x ## _count_objects, \
++ .scan_objects = x ## _scan_objects, \
++ .seeks = y \
+ }
+
+-# endif
+-#endif /* HAVE_SET_SHRINKER */
++#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
++static unsigned long fn ## _count_objects(struct shrinker *, \
++ struct shrink_control *); \
++static unsigned long fn ## _scan_objects(struct shrinker *, \
++ struct shrink_control *)
++
++#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
++static unsigned long \
++fn ## _count_objects(struct shrinker *shrink, struct shrink_control *sc)\
++{ \
++ int __ret__; \
++ \
++ sc->nr_to_scan = 0; \
++ __ret__ = __ ## fn(NULL, sc); \
++ \
++ /* Errors may not be returned and must be converted to zeros */ \
++ return ((__ret__ < 0) ? 0 : __ret__); \
++} \
++ \
++static unsigned long \
++fn ## _scan_objects(struct shrinker *shrink, struct shrink_control *sc) \
++{ \
++ int __ret__; \
++ \
++ __ret__ = __ ## fn(NULL, sc); \
++ return ((__ret__ < 0) ? SHRINK_STOP : __ret__); \
++}
++#else
++/*
++ * Linux 2.x to 2.6.22, or a newer shrinker API has been introduced.
++ */
++#error "Unknown shrinker callback"
++#endif
+
+ #endif /* SPL_MM_COMPAT_H */
+--
+1.8.5.1
+