summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2014-03-14 19:40:34 -0400
committerShea Levy <shea@shealevy.com>2014-03-14 19:40:34 -0400
commit602cf8d78c2ed90ceabc5866c4c1697fd72a6782 (patch)
tree93689e4b8234ee8104f2e50c20da40807dbc69f5 /pkgs
parent0c12dd3ded6088febb43cd69dea531eff220d5b1 (diff)
parenta7e65a8a957ceb752dd44d0447acee6c20309fe5 (diff)
downloadnixpkgs-602cf8d78c2ed90ceabc5866c4c1697fd72a6782.tar
nixpkgs-602cf8d78c2ed90ceabc5866c4c1697fd72a6782.tar.gz
nixpkgs-602cf8d78c2ed90ceabc5866c4c1697fd72a6782.tar.bz2
nixpkgs-602cf8d78c2ed90ceabc5866c4c1697fd72a6782.tar.lz
nixpkgs-602cf8d78c2ed90ceabc5866c4c1697fd72a6782.tar.xz
nixpkgs-602cf8d78c2ed90ceabc5866c4c1697fd72a6782.tar.zst
nixpkgs-602cf8d78c2ed90ceabc5866c4c1697fd72a6782.zip
Merge branch 'u/zfs-import' of git://github.com/wizeman/nixpkgs
zfs: Misc fixes
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/os-specific/linux/spl/3_12-compat.patch429
-rw-r--r--pkgs/os-specific/linux/spl/3_13-compat-1.patch61
-rw-r--r--pkgs/os-specific/linux/spl/3_13-compat-2.patch168
-rw-r--r--pkgs/os-specific/linux/spl/default.nix4
-rw-r--r--pkgs/os-specific/linux/zfs/3.13-compat.patch43
-rw-r--r--pkgs/os-specific/linux/zfs/default.nix2
-rw-r--r--pkgs/os-specific/linux/zfs/gcc-4.8.patch114
-rw-r--r--pkgs/os-specific/linux/zfs/libblkid-1db7b9b.patch118
8 files changed, 936 insertions, 3 deletions
diff --git a/pkgs/os-specific/linux/spl/3_12-compat.patch b/pkgs/os-specific/linux/spl/3_12-compat.patch
new file mode 100644
index 00000000000..b196098b7df
--- /dev/null
+++ b/pkgs/os-specific/linux/spl/3_12-compat.patch
@@ -0,0 +1,429 @@
+commit c3d9c0df3ee8d43db22815ebbfbe8b803fa46e46
+Author: Richard Yao <ryao@gentoo.org>
+Date:   Tue Nov 5 11:35:54 2013 -0500
+
+    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
+
+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 @@ extern shrink_icache_memory_t shrink_icache_memory_fn;
+ #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 */
diff --git a/pkgs/os-specific/linux/spl/3_13-compat-1.patch b/pkgs/os-specific/linux/spl/3_13-compat-1.patch
new file mode 100644
index 00000000000..40946931c80
--- /dev/null
+++ b/pkgs/os-specific/linux/spl/3_13-compat-1.patch
@@ -0,0 +1,61 @@
+From 3e96de17d723d6f6c9e2fd04b059b50d4e0bbef0 Mon Sep 17 00:00:00 2001
+From: Richard Yao <ryao@gentoo.org>
+Date: Thu, 8 Aug 2013 04:30:55 -0400
+Subject: [PATCH] Linux 3.13 compat: Remove unused flags variable from
+ __cv_init()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+GCC 4.8.1 complained about an unused flags variable when building
+against Linux 2.6.26.8:
+
+/var/tmp/portage/sys-kernel/spl-9999/work/spl-9999/module/spl/../../module/spl/spl-condvar.c:
+In function ‘__cv_init’:
+/var/tmp/portage/sys-kernel/spl-9999/work/spl-9999/module/spl/../../module/spl/spl-condvar.c:39:6:
+error: variable ‘flags’ set but not used
+[-Werror=unused-but-set-variable]
+  int flags = KM_SLEEP;
+        ^
+	cc1: all warnings being treated as errors
+
+Additionally, the superfluous code uses a preempt_count variable that is
+no longer available on Linux 3.13. Deleting the unnecessary code fixes a
+Linux 3.13 compatibility issue.
+
+Signed-off-by: Richard Yao <ryao@gentoo.org>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes #312
+---
+ module/spl/spl-condvar.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/module/spl/spl-condvar.c b/module/spl/spl-condvar.c
+index 283648a..8236412 100644
+--- a/module/spl/spl-condvar.c
++++ b/module/spl/spl-condvar.c
+@@ -36,8 +36,6 @@
+ void
+ __cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg)
+ {
+-	int flags = KM_SLEEP;
+-
+ 	SENTRY;
+ 	ASSERT(cvp);
+ 	ASSERT(name == NULL);
+@@ -51,12 +49,6 @@
+ 	atomic_set(&cvp->cv_refs, 1);
+ 	cvp->cv_mutex = NULL;
+ 
+-        /* We may be called when there is a non-zero preempt_count or
+-	 * interrupts are disabled is which case we must not sleep.
+-	 */
+-        if (current_thread_info()->preempt_count || irqs_disabled())
+-		flags = KM_NOSLEEP;
+-
+ 	SEXIT;
+ }
+ EXPORT_SYMBOL(__cv_init);
+-- 
+1.8.5.5
+
diff --git a/pkgs/os-specific/linux/spl/3_13-compat-2.patch b/pkgs/os-specific/linux/spl/3_13-compat-2.patch
new file mode 100644
index 00000000000..1f487f042f8
--- /dev/null
+++ b/pkgs/os-specific/linux/spl/3_13-compat-2.patch
@@ -0,0 +1,168 @@
+From 50a0749eba31e821a7edf286f1e3b149f7d13c59 Mon Sep 17 00:00:00 2001
+From: Richard Yao <ryao@gentoo.org>
+Date: Mon, 25 Nov 2013 11:22:33 -0500
+Subject: [PATCH] Linux 3.13 compat: Pass NULL for new delegated inode argument
+
+This check was originally added for SLES10, a093c6a, to check for
+a 'struct vfsmount *' argument which they added.  However, since
+SLES10 is based on a 2.6.16 kernel which is no longer supported
+this functionality was dropped.  The checks were refactored to
+support Linux 3.13 without concern for historical versions.
+
+Signed-off-by: Richard Yao <ryao@gentoo.org>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes #312
+---
+ config/spl-build.m4    | 52 ++++++++++++++++++++++++++++++++++++++++----------
+ module/spl/spl-vnode.c | 22 ++++++++++++---------
+ 2 files changed, 55 insertions(+), 19 deletions(-)
+
+diff --git a/config/spl-build.m4 b/config/spl-build.m4
+index 7d744db..8426780 100644
+--- a/config/spl-build.m4
++++ b/config/spl-build.m4
+@@ -1842,41 +1842,73 @@ AC_DEFUN([SPL_AC_SET_FS_PWD_WITH_CONST],
+ 	EXTRA_KCFLAGS="$tmp_flags"
+ ])
+ 
+-dnl #
+-dnl # SLES API change, never adopted in mainline,
+-dnl # Third 'struct vfsmount *' argument removed.
+-dnl #
+ AC_DEFUN([SPL_AC_2ARGS_VFS_UNLINK],
+ 	[AC_MSG_CHECKING([whether vfs_unlink() wants 2 args])
+ 	SPL_LINUX_TRY_COMPILE([
+ 		#include <linux/fs.h>
+ 	],[
+-		vfs_unlink(NULL, NULL);
++		vfs_unlink((struct inode *) NULL, (struct dentry *) NULL);
+ 	],[
+ 		AC_MSG_RESULT(yes)
+ 		AC_DEFINE(HAVE_2ARGS_VFS_UNLINK, 1,
+ 		          [vfs_unlink() wants 2 args])
+ 	],[
+ 		AC_MSG_RESULT(no)
++		dnl #
++		dnl # Linux 3.13 API change
++		dnl # Added delegated inode
++		dnl #
++		AC_MSG_CHECKING([whether vfs_unlink() wants 3 args])
++		SPL_LINUX_TRY_COMPILE([
++			#include <linux/fs.h>
++		],[
++			vfs_unlink((struct inode *) NULL,
++				(struct dentry *) NULL,
++				(struct inode **) NULL);
++		],[
++			AC_MSG_RESULT(yes)
++			AC_DEFINE(HAVE_3ARGS_VFS_UNLINK, 1,
++				  [vfs_unlink() wants 3 args])
++		],[
++			AC_MSG_ERROR(no)
++		])
++
+ 	])
+ ])
+ 
+-dnl #
+-dnl # SLES API change, never adopted in mainline,
+-dnl # Third and sixth 'struct vfsmount *' argument removed.
+-dnl #
+ AC_DEFUN([SPL_AC_4ARGS_VFS_RENAME],
+ 	[AC_MSG_CHECKING([whether vfs_rename() wants 4 args])
+ 	SPL_LINUX_TRY_COMPILE([
+ 		#include <linux/fs.h>
+ 	],[
+-		vfs_rename(NULL, NULL, NULL, NULL);
++		vfs_rename((struct inode *) NULL, (struct dentry *) NULL,
++			(struct inode *) NULL, (struct dentry *) NULL);
+ 	],[
+ 		AC_MSG_RESULT(yes)
+ 		AC_DEFINE(HAVE_4ARGS_VFS_RENAME, 1,
+ 		          [vfs_rename() wants 4 args])
+ 	],[
+ 		AC_MSG_RESULT(no)
++		dnl #
++		dnl # Linux 3.13 API change
++		dnl # Added delegated inode
++		dnl #
++		AC_MSG_CHECKING([whether vfs_rename() wants 5 args])
++		SPL_LINUX_TRY_COMPILE([
++			#include <linux/fs.h>
++		],[
++			vfs_rename((struct inode *) NULL,
++				(struct dentry *) NULL,
++				(struct inode *) NULL,
++				(struct dentry *) NULL,
++				(struct inode **) NULL);
++		],[
++			AC_MSG_RESULT(yes)
++			AC_DEFINE(HAVE_5ARGS_VFS_RENAME, 1,
++				  [vfs_rename() wants 5 args])
++		],[
++			AC_MSG_ERROR(no)
++		])
+ 	])
+ ])
+ 
+diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c
+index 0784ff2..5496067 100644
+--- a/module/spl/spl-vnode.c
++++ b/module/spl/spl-vnode.c
+@@ -334,7 +334,11 @@
+ 		if (inode)
+ 			ihold(inode);
+ 
++#ifdef HAVE_2ARGS_VFS_UNLINK
+ 		rc = vfs_unlink(parent.dentry->d_inode, dentry);
++#else
++		rc = vfs_unlink(parent.dentry->d_inode, dentry, NULL);
++#endif /* HAVE_2ARGS_VFS_UNLINK */
+ exit1:
+ 		dput(dentry);
+ 	} else {
+@@ -412,10 +416,10 @@
+ 
+ #ifdef HAVE_4ARGS_VFS_RENAME
+ 	rc = vfs_rename(old_dir->d_inode, old_dentry,
+-			new_dir->d_inode, new_dentry);
++	    new_dir->d_inode, new_dentry);
+ #else
+-	rc = vfs_rename(old_dir->d_inode, old_dentry, oldnd.nd_mnt,
+-			new_dir->d_inode, new_dentry, newnd.nd_mnt);
++	rc = vfs_rename(old_dir->d_inode, old_dentry,
++	    new_dir->d_inode, new_dentry, NULL);
+ #endif /* HAVE_4ARGS_VFS_RENAME */
+ exit4:
+ 	unlock_rename(new_dir, old_dir);
+@@ -478,9 +482,9 @@
+                 if (inode)
+                         atomic_inc(&inode->i_count);
+ #ifdef HAVE_2ARGS_VFS_UNLINK
+-                rc = vfs_unlink(nd.nd_dentry->d_inode, dentry);
++		rc = vfs_unlink(nd.nd_dentry->d_inode, dentry);
+ #else
+-                rc = vfs_unlink(nd.nd_dentry->d_inode, dentry, nd.nd_mnt);
++		rc = vfs_unlink(nd.nd_dentry->d_inode, dentry, NULL);
+ #endif /* HAVE_2ARGS_VFS_UNLINK */
+ exit2:
+                 dput(dentry);
+@@ -571,11 +575,11 @@
+                 SGOTO(exit5, rc);
+ 
+ #ifdef HAVE_4ARGS_VFS_RENAME
+-        rc = vfs_rename(old_dir->d_inode, old_dentry,
+-                        new_dir->d_inode, new_dentry);
++	rc = vfs_rename(old_dir->d_inode, old_dentry,
++	    new_dir->d_inode, new_dentry);
+ #else
+-        rc = vfs_rename(old_dir->d_inode, old_dentry, oldnd.nd_mnt,
+-                        new_dir->d_inode, new_dentry, newnd.nd_mnt);
++	rc = vfs_rename(old_dir->d_inode, old_dentry,
++	    new_dir->d_inode, new_dentry, NULL);
+ #endif /* HAVE_4ARGS_VFS_RENAME */
+ exit5:
+         dput(new_dentry);
+-- 
+1.8.5.5
+
diff --git a/pkgs/os-specific/linux/spl/default.nix b/pkgs/os-specific/linux/spl/default.nix
index ee264f67127..56c41798780 100644
--- a/pkgs/os-specific/linux/spl/default.nix
+++ b/pkgs/os-specific/linux/spl/default.nix
@@ -7,7 +7,7 @@ stdenv.mkDerivation {
     sha256 = "196scl8q0bkkak6m0p1l1fz254cgsizqm73bf9wk3iynamq7qmrw";
   };
 
-  patches = [ ./install_prefix.patch ];
+  patches = [ ./install_prefix.patch ./3_12-compat.patch ./3_13-compat-1.patch ./3_13-compat-2.patch ];
 
   buildInputs = [ perl autoconf automake libtool ];
 
@@ -15,7 +15,7 @@ stdenv.mkDerivation {
     ./autogen.sh
 
     substituteInPlace ./module/spl/spl-generic.c --replace /usr/bin/hostid hostid
-    substituteInPlace ./module/spl/spl-module.c  --replace /bin/mknod mknod 
+    substituteInPlace ./module/spl/spl-module.c  --replace /bin/mknod mknod
 
     substituteInPlace ./module/spl/spl-generic.c --replace "PATH=/sbin:/usr/sbin:/bin:/usr/bin" "PATH=${coreutils}:${gawk}:/bin"
     substituteInPlace ./module/splat/splat-vnode.c --replace "PATH=/sbin:/usr/sbin:/bin:/usr/bin" "PATH=${coreutils}:/bin"
diff --git a/pkgs/os-specific/linux/zfs/3.13-compat.patch b/pkgs/os-specific/linux/zfs/3.13-compat.patch
new file mode 100644
index 00000000000..f89d38f72ac
--- /dev/null
+++ b/pkgs/os-specific/linux/zfs/3.13-compat.patch
@@ -0,0 +1,43 @@
+From 729210564a5325e190fc4fba22bf17bacf957ace Mon Sep 17 00:00:00 2001
+From: Richard Yao <ryao@gentoo.org>
+Date: Mon, 25 Nov 2013 12:21:21 -0500
+Subject: [PATCH] Properly ignore bdi_setup_and_register return value
+
+This broke compilation against Linux 3.13 and GCC 4.7.3.
+
+Signed-off-by: Richard Yao <ryao@gentoo.org>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes #1906
+---
+ config/kernel-bdi-setup-and-register.m4 | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/config/kernel-bdi-setup-and-register.m4 b/config/kernel-bdi-setup-and-register.m4
+index 4196091..cb8ed67 100644
+--- a/config/kernel-bdi-setup-and-register.m4
++++ b/config/kernel-bdi-setup-and-register.m4
+@@ -1,12 +1,14 @@
+ dnl #
+ dnl # 2.6.34 API change
+-dnl # The bdi_setup_and_register() helper function is avilable and
++dnl # The bdi_setup_and_register() helper function is available and
+ dnl # exported by the kernel.  This is a trivial helper function but
+ dnl # using it significantly simplifies the code surrounding setting
+ dnl # up and tearing down the bdi structure.
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER],
+ 	[AC_MSG_CHECKING([whether bdi_setup_and_register() is available])
++	tmp_flags="$EXTRA_KCFLAGS"
++	EXTRA_KCFLAGS="-Wno-unused-result"
+ 	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+ 		#include <linux/backing-dev.h>
+ 	], [
+@@ -18,4 +20,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER],
+ 	], [
+ 		AC_MSG_RESULT(no)
+ 	])
++	EXTRA_KCFLAGS="$tmp_flags"
+ ])
+-- 
+1.8.5.5
+
diff --git a/pkgs/os-specific/linux/zfs/default.nix b/pkgs/os-specific/linux/zfs/default.nix
index 67ed1312826..ef313e6ca1e 100644
--- a/pkgs/os-specific/linux/zfs/default.nix
+++ b/pkgs/os-specific/linux/zfs/default.nix
@@ -8,7 +8,7 @@ stdenv.mkDerivation {
     sha256 = "18b5f18k8mwb17r5ippsilmp1a2sqjw9fwn0z82159dkhsadg33b";
   };
 
-  patches = [ ./mount_zfs_prefix.patch ./nix-build.patch ];
+  patches = [ ./mount_zfs_prefix.patch ./nix-build.patch ./libblkid-1db7b9b.patch ./gcc-4.8.patch ./3.13-compat.patch ];
 
   buildInputs = [ spl perl autoconf automake libtool zlib libuuid coreutils ];
 
diff --git a/pkgs/os-specific/linux/zfs/gcc-4.8.patch b/pkgs/os-specific/linux/zfs/gcc-4.8.patch
new file mode 100644
index 00000000000..34136016376
--- /dev/null
+++ b/pkgs/os-specific/linux/zfs/gcc-4.8.patch
@@ -0,0 +1,114 @@
+commit 0f62f3f9abc4bfa0bcafee9bfa3d55e91dcb371d
+Author: Brian Behlendorf <behlendorf1@llnl.gov>
+Date:   Tue Jan 14 09:39:13 2014 -0800
+
+    Disable GCCs aggressive loop optimization
+    
+    GCC >+ 4.8's aggressive loop optimization breaks some of the iterators
+    over the dn_blkptr[] pseudo-array in dnode_phys. Since dn_blkptr[] is
+    defined as a single-element array, GCC believes an iterator can only
+    access index 0 and will unroll the loop into a single iteration.
+    
+    One way to resolve the issue would be to cast the array to a pointer
+    and fix all the iterators that might break.  The only loop where it
+    is known to cause a problem is this loop in dmu_objset_write_ready():
+    
+        for (i = 0; i < dnp->dn_nblkptr; i++)
+                bp->blk_fill += dnp->dn_blkptr[i].blk_fill;
+    
+    In the common case where dn_nblkptr is 3, the loop is only executed a
+    single time and "i" is equal to 1 following the loop.
+    
+    The specific breakage caused by this problem is that the blk_fill of
+    root block pointers wouldn't be set properly when more than one blkptr
+    is in use (when no indrect blocks are needed).
+    
+    The simple reproducing sequence is:
+    
+    zpool create tank /tank.img
+    zdb -ddddd tank 0
+    
+    Notice that "fill=31", however, there are two L0 indirect blocks with
+    "F=31" and "F=5". The fill count should be 36 rather than 31. This
+    problem causes an assert to be hit in a simple "zdb tank" when built
+    with --enable-debug.
+    
+    However, this approach was not taken because we need to be absolutely
+    sure we catch all instances of this unwanted optimization.  Therefore,
+    the build system has been updated to detect if GCC supports the
+    aggressive loop optimization.  If it does the optimization will be
+    explicitly disabled using the -fno-aggressive-loop-optimization option.
+    
+    Original-fix-by: Tim Chase <tim@chase2k.com>
+    Signed-off-by: Tim Chase <tim@chase2k.com>
+    Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+    Closes #2010
+    Closes #2051
+
+diff --git a/config/Rules.am b/config/Rules.am
+index e3fa5b5..24f9426 100644
+--- a/config/Rules.am
++++ b/config/Rules.am
+@@ -1,8 +1,10 @@
+ DEFAULT_INCLUDES = -include ${top_builddir}/zfs_config.h
+ 
+ AM_LIBTOOLFLAGS = --silent
+-AM_CFLAGS  = -Wall -Wstrict-prototypes
+-AM_CFLAGS += -fno-strict-aliasing ${NO_UNUSED_BUT_SET_VARIABLE} ${DEBUG_CFLAGS}
++AM_CFLAGS  = ${DEBUG_CFLAGS} -Wall -Wstrict-prototypes
++AM_CFLAGS += ${NO_UNUSED_BUT_SET_VARIABLE}
++AM_CFLAGS += ${NO_AGGRESSIVE_LOOP_OPTIMIZATIONS}
++AM_CFLAGS += -fno-strict-aliasing
+ AM_CPPFLAGS  = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT
+ AM_CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64
+ AM_CPPFLAGS += -D_LARGEFILE64_SOURCE -DTEXT_DOMAIN=\"zfs-linux-user\"
+diff --git a/config/always-no-aggressive-loop-optimizations.m4 b/config/always-no-aggressive-loop-optimizations.m4
+new file mode 100644
+index 0000000..8f2115a
+--- /dev/null
++++ b/config/always-no-aggressive-loop-optimizations.m4
+@@ -0,0 +1,20 @@
++dnl #
++dnl # Check if gcc supports -fno-aggressive-loop-optimizations
++dnl #
++AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_NO_AGGRESSIVE_LOOP_OPTIMIZATIONS], [
++	AC_MSG_CHECKING([for -fno-aggressive-loop-optimizations support])
++
++	saved_flags="$CFLAGS"
++	CFLAGS="$CFLAGS -fno-aggressive-loop-optimizations"
++
++	AC_RUN_IFELSE([AC_LANG_PROGRAM([], [])], [
++		NO_AGGRESSIVE_LOOP_OPTIMIZATIONS=-fno-aggressive-loop-optimizations
++		AC_MSG_RESULT([yes])
++	], [
++		NO_AGGRESSIVE_LOOP_OPTIMIZATIONS=
++		AC_MSG_RESULT([no])
++	])
++
++	CFLAGS="$saved_flags"
++	AC_SUBST([NO_AGGRESSIVE_LOOP_OPTIMIZATIONS])
++])
+diff --git a/config/kernel.m4 b/config/kernel.m4
+index cbf0ca3..62a9b42 100644
+--- a/config/kernel.m4
++++ b/config/kernel.m4
+@@ -104,6 +104,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
+ 	dnl # -Wall -fno-strict-aliasing -Wstrict-prototypes and other
+ 	dnl # compiler options are added by the kernel build system.
+ 	KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_UNUSED_BUT_SET_VARIABLE"
++	KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_AGGRESSIVE_LOOP_OPTIMIZATIONS"
+ 	KERNELCPPFLAGS="$KERNELCPPFLAGS -DHAVE_SPL -D_KERNEL"
+ 	KERNELCPPFLAGS="$KERNELCPPFLAGS -DTEXT_DOMAIN=\\\"zfs-linux-kernel\\\""
+ 
+diff --git a/config/zfs-build.m4 b/config/zfs-build.m4
+index 005185b..477b916 100644
+--- a/config/zfs-build.m4
++++ b/config/zfs-build.m4
+@@ -62,6 +62,7 @@ AC_DEFUN([ZFS_AC_DEBUG_DMU_TX], [
+ 
+ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
+ 	ZFS_AC_CONFIG_ALWAYS_NO_UNUSED_BUT_SET_VARIABLE
++	ZFS_AC_CONFIG_ALWAYS_NO_AGGRESSIVE_LOOP_OPTIMIZATIONS
+ ])
+ 
+ AC_DEFUN([ZFS_AC_CONFIG], [
diff --git a/pkgs/os-specific/linux/zfs/libblkid-1db7b9b.patch b/pkgs/os-specific/linux/zfs/libblkid-1db7b9b.patch
new file mode 100644
index 00000000000..894bf395ce8
--- /dev/null
+++ b/pkgs/os-specific/linux/zfs/libblkid-1db7b9b.patch
@@ -0,0 +1,118 @@
+commit 1db7b9be75a225cedb3b7a60028ca5695e5b8346
+Author: Richard Yao <ryao@gentoo.org>
+Date:   Wed Aug 28 16:17:47 2013 -0400
+
+    Fix libblkid support
+    
+    libblkid support is dormant because the autotools check is broken and
+    liblkid identifies ZFS vdevs as "zfs_member", not "zfs". We fix that
+    with a few changes:
+    
+    First, we fix the libblkid autotools check to do a few things:
+    
+    1. Make a 64MB file, which is the minimum size ZFS permits.
+    2. Make 4 fake uberblock entries to make libblkid's check succeed.
+    3. Return 0 upon success to make autotools use the success case.
+    4. Include stdlib.h to avoid implicit declration of free().
+    5. Check for "zfs_member", not "zfs"
+    6. Make --with-blkid disable autotools check (avoids Gentoo sandbox violation)
+    7. Pass '-lblkid' correctly using LIBS not LDFLAGS.
+    
+    Second, we change the libblkid support to scan for "zfs_member", not
+    "zfs".
+    
+    This makes --with-blkid work on Gentoo.
+    
+    Signed-off-by: Richard Yao <ryao@gentoo.org>
+    Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+    Issue #1751
+
+diff --git a/config/user-libblkid.m4 b/config/user-libblkid.m4
+index 276587f..2dd2623 100644
+--- a/config/user-libblkid.m4
++++ b/config/user-libblkid.m4
+@@ -22,26 +22,45 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_LIBBLKID], [
+ 		[with_blkid=check])
+ 
+ 	LIBBLKID=
+-	AS_IF([test "x$with_blkid" != xno],
++	AS_IF([test "x$with_blkid" = xyes],
++	[
++		AC_SUBST([LIBBLKID], ["-lblkid"])
++		AC_DEFINE([HAVE_LIBBLKID], 1,
++			[Define if you have libblkid])
++	])
++
++	AS_IF([test "x$with_blkid" = xcheck],
+ 	[
+ 		AC_CHECK_LIB([blkid], [blkid_get_cache],
+ 		[
+ 			AC_MSG_CHECKING([for blkid zfs support])
+ 
+ 			ZFS_DEV=`mktemp`
+-			dd if=/dev/zero of=$ZFS_DEV bs=1024k count=8 \
++			truncate -s 64M $ZFS_DEV
++			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
++				dd of=$ZFS_DEV bs=1k count=8 \
++				seek=128 conv=notrunc &>/dev/null \
+ 				>/dev/null 2>/dev/null
+ 			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+ 				dd of=$ZFS_DEV bs=1k count=8 \
+ 				seek=132 conv=notrunc &>/dev/null \
+ 				>/dev/null 2>/dev/null
++			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
++				dd of=$ZFS_DEV bs=1k count=8 \
++				seek=136 conv=notrunc &>/dev/null \
++				>/dev/null 2>/dev/null
++			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
++				dd of=$ZFS_DEV bs=1k count=8 \
++				seek=140 conv=notrunc &>/dev/null \
++				>/dev/null 2>/dev/null
+ 
+-			saved_LDFLAGS="$LDFLAGS"
+-			LDFLAGS="-lblkid"
++			saved_LIBS="$LIBS"
++			LIBS="-lblkid"
+ 
+ 			AC_RUN_IFELSE([AC_LANG_PROGRAM(
+ 			[
+ 				#include <stdio.h>
++				#include <stdlib.h>
+ 				#include <blkid/blkid.h>
+ 			],
+ 			[
+@@ -58,10 +77,10 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_LIBBLKID], [
+ 					return 2;
+ 				}
+ 
+-				if (strcmp(value, "zfs")) {
++				if (strcmp(value, "zfs_member")) {
+ 					free(value);
+ 					blkid_put_cache(cache);
+-					return 3;
++					return 0;
+ 				}
+ 
+ 				free(value);
+@@ -82,7 +101,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_LIBBLKID], [
+ 					[--with-blkid given but unavailable])])
+ 			])
+ 
+-			LDFLAGS="$saved_LDFLAGS"
++			LIBS="$saved_LIBS"
+ 		],
+ 		[
+ 			AS_IF([test "x$with_blkid" != xcheck],
+diff --git a/lib/libzfs/libzfs_import.c b/lib/libzfs/libzfs_import.c
+index 53609f2..d1fa98e 100644
+--- a/lib/libzfs/libzfs_import.c
++++ b/lib/libzfs/libzfs_import.c
+@@ -965,7 +965,7 @@ zpool_find_import_blkid(libzfs_handle_t *hdl, pool_list_t *pools)
+ 		goto err_blkid2;
+ 	}
+ 
+-	err = blkid_dev_set_search(iter, "TYPE", "zfs");
++	err = blkid_dev_set_search(iter, "TYPE", "zfs_member");
+ 	if (err != 0) {
+ 		(void) zfs_error_fmt(hdl, EZFS_BADCACHE,
+ 		    dgettext(TEXT_DOMAIN, "blkid_dev_set_search() %d"), err);