+++ /dev/null
-diff --git a/include/spl-debug.h b/include/spl-debug.h
-index 0028c29..8bd4c44 100644
---- a/include/spl-debug.h
-+++ b/include/spl-debug.h
-@@ -64,6 +64,7 @@
- #define SS_KSTAT 0x00020000
- #define SS_XDR 0x00040000
- #define SS_TSD 0x00080000
-+#define SS_ZLIB 0x00100000
- #define SS_USER1 0x01000000
- #define SS_USER2 0x02000000
- #define SS_USER3 0x04000000
-diff --git a/include/splat-ctl.h b/include/splat-ctl.h
-index 61c7e0e..6f15ba2 100644
---- a/include/splat-ctl.h
-+++ b/include/splat-ctl.h
-@@ -104,6 +104,7 @@ typedef struct splat_cmd {
- #define SPLAT_SUBSYSTEM_LIST 0x0c00
- #define SPLAT_SUBSYSTEM_GENERIC 0x0d00
- #define SPLAT_SUBSYSTEM_CRED 0x0e00
-+#define SPLAT_SUBSYSTEM_ZLIB 0x0f00
- #define SPLAT_SUBSYSTEM_UNKNOWN 0xff00
-
- #endif /* _SPLAT_CTL_H */
-diff --git a/include/sys/zmod.h b/include/sys/zmod.h
-index f1a6317..246aa2a 100644
---- a/include/sys/zmod.h
-+++ b/include/sys/zmod.h
-@@ -55,105 +55,15 @@
- #ifndef _SPL_ZMOD_H
- #define _SPL_ZMOD_H
-
-+#include <sys/types.h>
- #include <linux/zlib.h>
-
--/*
-- * Compresses the source buffer into the destination buffer. The level
-- * parameter has the same meaning as in deflateInit. sourceLen is the byte
-- * length of the source buffer. Upon entry, destLen is the total size of the
-- * destination buffer, which must be at least 0.1% larger than sourceLen plus
-- * 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-- *
-- * compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-- * memory, Z_BUF_ERROR if there was not enough room in the output buffer,
-- * Z_STREAM_ERROR if the level parameter is invalid.
-- */
--static __inline__ int
--z_compress_level(void *dest, size_t *destLen, const void *source,
-- size_t sourceLen, int level)
--{
-- z_stream stream;
-- int err;
--
-- stream.next_in = (Byte *)source;
-- stream.avail_in = (uInt)sourceLen;
--#ifdef MAXSEG_64K
-- /* Check for source > 64K on 16-bit machine: */
-- if ((size_t)stream.avail_in != sourceLen)
-- return Z_BUF_ERROR;
--#endif
-- stream.next_out = dest;
-- stream.avail_out = (uInt)*destLen;
--
-- if ((size_t)stream.avail_out != *destLen)
-- return Z_BUF_ERROR;
--
-- err = zlib_deflateInit(&stream, level);
-- if (err != Z_OK)
-- return err;
--
-- err = zlib_deflate(&stream, Z_FINISH);
-- if (err != Z_STREAM_END) {
-- zlib_deflateEnd(&stream);
-- return err == Z_OK ? Z_BUF_ERROR : err;
-- }
-- *destLen = stream.total_out;
--
-- err = zlib_deflateEnd(&stream);
-- return err;
--} /* z_compress_level() */
--
--/*
-- * Decompresses the source buffer into the destination buffer. sourceLen is
-- * the byte length of the source buffer. Upon entry, destLen is the total
-- * size of the destination buffer, which must be large enough to hold the
-- * entire uncompressed data. (The size of the uncompressed data must have
-- * been saved previously by the compressor and transmitted to the decompressor
-- * by some mechanism outside the scope of this compression library.)
-- * Upon exit, destLen is the actual size of the compressed buffer.
-- * This function can be used to decompress a whole file at once if the
-- * input file is mmap'ed.
-- *
-- * uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
-- * enough memory, Z_BUF_ERROR if there was not enough room in the output
-- * buffer, or Z_DATA_ERROR if the input data was corrupted.
-- */
--static __inline__ int
--z_uncompress(void *dest, size_t *destLen, const void *source, size_t sourceLen)
--{
-- z_stream stream;
-- int err;
--
-- stream.next_in = (Byte *)source;
-- stream.avail_in = (uInt)sourceLen;
-- /* Check for source > 64K on 16-bit machine: */
-- if ((size_t)stream.avail_in != sourceLen)
-- return Z_BUF_ERROR;
--
-- stream.next_out = dest;
-- stream.avail_out = (uInt)*destLen;
--
-- if ((size_t)stream.avail_out != *destLen)
-- return Z_BUF_ERROR;
--
-- err = zlib_inflateInit(&stream);
-- if (err != Z_OK)
-- return err;
--
-- err = zlib_inflate(&stream, Z_FINISH);
-- if (err != Z_STREAM_END) {
-- zlib_inflateEnd(&stream);
--
-- if (err == Z_NEED_DICT ||
-- (err == Z_BUF_ERROR && stream.avail_in == 0))
-- return Z_DATA_ERROR;
--
-- return err;
-- }
-- *destLen = stream.total_out;
-+extern int z_compress_level(void *dest, size_t *destLen, const void *source,
-+ size_t sourceLen, int level);
-+extern int z_uncompress(void *dest, size_t *destLen, const void *source,
-+ size_t sourceLen);
-
-- err = zlib_inflateEnd(&stream);
-- return err;
--} /* z_uncompress() */
-+int zlib_init(void);
-+void zlib_fini(void);
-
- #endif /* SPL_ZMOD_H */
-diff --git a/module/spl/Makefile.in b/module/spl/Makefile.in
-index 483933b..a0211d2 100644
---- a/module/spl/Makefile.in
-+++ b/module/spl/Makefile.in
-@@ -27,3 +27,4 @@ spl-objs += @top_srcdir@/module/spl/spl-condvar.o
- spl-objs += @top_srcdir@/module/spl/spl-xdr.o
- spl-objs += @top_srcdir@/module/spl/spl-cred.o
- spl-objs += @top_srcdir@/module/spl/spl-tsd.o
-+spl-objs += @top_srcdir@/module/spl/spl-zlib.o
-diff --git a/module/spl/spl-debug.c b/module/spl/spl-debug.c
-index 2c76c79..21e8c5d 100644
---- a/module/spl/spl-debug.c
-+++ b/module/spl/spl-debug.c
-@@ -160,6 +160,8 @@ spl_debug_subsys2str(int subsys)
- return "xdr";
- case SS_TSD:
- return "tsd";
-+ case SS_ZLIB:
-+ return "zlib";
- case SS_USER1:
- return "user1";
- case SS_USER2:
-diff --git a/module/spl/spl-generic.c b/module/spl/spl-generic.c
-index b83d753..2b43f0c 100644
---- a/module/spl/spl-generic.c
-+++ b/module/spl/spl-generic.c
-@@ -33,6 +33,7 @@
- #include <sys/rwlock.h>
- #include <sys/taskq.h>
- #include <sys/tsd.h>
-+#include <sys/zmod.h>
- #include <sys/debug.h>
- #include <sys/proc.h>
- #include <sys/kstat.h>
-@@ -471,20 +472,25 @@ __init spl_init(void)
- if ((rc = tsd_init()))
- SGOTO(out8, rc);
-
-+ if ((rc = zlib_init()))
-+ SGOTO(out9, rc);
-+
- if ((rc = set_hostid()))
-- SGOTO(out9, rc = -EADDRNOTAVAIL);
-+ SGOTO(out10, rc = -EADDRNOTAVAIL);
-
- #ifndef HAVE_KALLSYMS_LOOKUP_NAME
- if ((rc = set_kallsyms_lookup_name()))
-- SGOTO(out9, rc = -EADDRNOTAVAIL);
-+ SGOTO(out10, rc = -EADDRNOTAVAIL);
- #endif /* HAVE_KALLSYMS_LOOKUP_NAME */
-
- if ((rc = spl_kmem_init_kallsyms_lookup()))
-- SGOTO(out9, rc);
-+ SGOTO(out10, rc);
-
- printk(KERN_NOTICE "SPL: Loaded Solaris Porting Layer v%s%s\n",
- SPL_META_VERSION, SPL_DEBUG_STR);
- SRETURN(rc);
-+out10:
-+ zlib_fini();
- out9:
- tsd_fini();
- out8:
-@@ -516,6 +522,7 @@ spl_fini(void)
-
- printk(KERN_NOTICE "SPL: Unloaded Solaris Porting Layer v%s%s\n",
- SPL_META_VERSION, SPL_DEBUG_STR);
-+ zlib_fini();
- tsd_fini();
- kstat_fini();
- proc_fini();
-diff --git a/module/spl/spl-zlib.c b/module/spl/spl-zlib.c
-new file mode 100644
-index 0000000..02825b4
---- /dev/null
-+++ b/module/spl/spl-zlib.c
-@@ -0,0 +1,217 @@
-+/*****************************************************************************\
-+ * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
-+ * Copyright (C) 2007 The Regents of the University of California.
-+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
-+ * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
-+ * UCRL-CODE-235197
-+ *
-+ * This file is part of the SPL, Solaris Porting Layer.
-+ * For details, see <http://github.com/behlendorf/spl/>.
-+ *
-+ * The SPL is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ *
-+ * The SPL is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ * for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with the SPL. If not, see <http://www.gnu.org/licenses/>.
-+ *****************************************************************************
-+ * z_compress_level/z_uncompress are nearly identical copies of the
-+ * compress2/uncompress functions provided by the official zlib package
-+ * available at http://zlib.net/. The only changes made we to slightly
-+ * adapt the functions called to match the linux kernel implementation
-+ * of zlib. The full zlib license follows:
-+ *
-+ * zlib.h -- interface of the 'zlib' general purpose compression library
-+ * version 1.2.5, April 19th, 2010
-+ *
-+ * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
-+ *
-+ * This software is provided 'as-is', without any express or implied
-+ * warranty. In no event will the authors be held liable for any damages
-+ * arising from the use of this software.
-+ *
-+ * Permission is granted to anyone to use this software for any purpose,
-+ * including commercial applications, and to alter it and redistribute it
-+ * freely, subject to the following restrictions:
-+ *
-+ * 1. The origin of this software must not be misrepresented; you must not
-+ * claim that you wrote the original software. If you use this software
-+ * in a product, an acknowledgment in the product documentation would be
-+ * appreciated but is not required.
-+ * 2. Altered source versions must be plainly marked as such, and must not be
-+ * misrepresented as being the original software.
-+ * 3. This notice may not be removed or altered from any source distribution.
-+ *
-+ * Jean-loup Gailly
-+ * Mark Adler
-+\*****************************************************************************/
-+
-+
-+#include <sys/kmem.h>
-+#include <sys/zmod.h>
-+#include <spl-debug.h>
-+
-+#ifdef DEBUG_SUBSYSTEM
-+#undef DEBUG_SUBSYSTEM
-+#endif
-+
-+#define DEBUG_SUBSYSTEM SS_ZLIB
-+
-+static spl_kmem_cache_t *zlib_workspace_cache;
-+
-+/*
-+ * A kmem_cache is used for the zlib workspaces to avoid having to vmalloc
-+ * and vfree for every call. Using a kmem_cache also has the advantage
-+ * that improves the odds that the memory used will be local to this cpu.
-+ * To further improve things it might be wise to create a dedicated per-cpu
-+ * workspace for use. This would take some additional care because we then
-+ * must disable preemption around the critical section, and verify that
-+ * zlib_deflate* and zlib_inflate* never internally call schedule().
-+ */
-+static void *
-+zlib_workspace_alloc(int flags)
-+{
-+ return kmem_cache_alloc(zlib_workspace_cache, flags & ~(__GFP_FS));
-+}
-+
-+static void
-+zlib_workspace_free(void *workspace)
-+{
-+ kmem_cache_free(zlib_workspace_cache, workspace);
-+}
-+
-+/*
-+ * Compresses the source buffer into the destination buffer. The level
-+ * parameter has the same meaning as in deflateInit. sourceLen is the byte
-+ * length of the source buffer. Upon entry, destLen is the total size of the
-+ * destination buffer, which must be at least 0.1% larger than sourceLen plus
-+ * 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-+ *
-+ * compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ * memory, Z_BUF_ERROR if there was not enough room in the output buffer,
-+ * Z_STREAM_ERROR if the level parameter is invalid.
-+ */
-+int
-+z_compress_level(void *dest, size_t *destLen, const void *source,
-+ size_t sourceLen, int level)
-+{
-+ z_stream stream;
-+ int err;
-+
-+ stream.next_in = (Byte *)source;
-+ stream.avail_in = (uInt)sourceLen;
-+ stream.next_out = dest;
-+ stream.avail_out = (uInt)*destLen;
-+
-+ if ((size_t)stream.avail_out != *destLen)
-+ return Z_BUF_ERROR;
-+
-+ stream.workspace = zlib_workspace_alloc(KM_SLEEP);
-+ if (!stream.workspace)
-+ return Z_MEM_ERROR;
-+
-+ err = zlib_deflateInit(&stream, level);
-+ if (err != Z_OK) {
-+ zlib_workspace_free(stream.workspace);
-+ return err;
-+ }
-+
-+ err = zlib_deflate(&stream, Z_FINISH);
-+ if (err != Z_STREAM_END) {
-+ zlib_deflateEnd(&stream);
-+ zlib_workspace_free(stream.workspace);
-+ return err == Z_OK ? Z_BUF_ERROR : err;
-+ }
-+ *destLen = stream.total_out;
-+
-+ err = zlib_deflateEnd(&stream);
-+ zlib_workspace_free(stream.workspace);
-+
-+ return err;
-+}
-+EXPORT_SYMBOL(z_compress_level);
-+
-+/*
-+ * Decompresses the source buffer into the destination buffer. sourceLen is
-+ * the byte length of the source buffer. Upon entry, destLen is the total
-+ * size of the destination buffer, which must be large enough to hold the
-+ * entire uncompressed data. (The size of the uncompressed data must have
-+ * been saved previously by the compressor and transmitted to the decompressor
-+ * by some mechanism outside the scope of this compression library.)
-+ * Upon exit, destLen is the actual size of the compressed buffer.
-+ * This function can be used to decompress a whole file at once if the
-+ * input file is mmap'ed.
-+ *
-+ * uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
-+ * enough memory, Z_BUF_ERROR if there was not enough room in the output
-+ * buffer, or Z_DATA_ERROR if the input data was corrupted.
-+ */
-+int
-+z_uncompress(void *dest, size_t *destLen, const void *source, size_t sourceLen)
-+{
-+ z_stream stream;
-+ int err;
-+
-+ stream.next_in = (Byte *)source;
-+ stream.avail_in = (uInt)sourceLen;
-+ stream.next_out = dest;
-+ stream.avail_out = (uInt)*destLen;
-+
-+ if ((size_t)stream.avail_out != *destLen)
-+ return Z_BUF_ERROR;
-+
-+ stream.workspace = zlib_workspace_alloc(KM_SLEEP);
-+ if (!stream.workspace)
-+ return Z_MEM_ERROR;
-+
-+ err = zlib_inflateInit(&stream);
-+ if (err != Z_OK) {
-+ zlib_workspace_free(stream.workspace);
-+ return err;
-+ }
-+
-+ err = zlib_inflate(&stream, Z_FINISH);
-+ if (err != Z_STREAM_END) {
-+ zlib_inflateEnd(&stream);
-+ zlib_workspace_free(stream.workspace);
-+
-+ if (err == Z_NEED_DICT ||
-+ (err == Z_BUF_ERROR && stream.avail_in == 0))
-+ return Z_DATA_ERROR;
-+
-+ return err;
-+ }
-+ *destLen = stream.total_out;
-+
-+ err = zlib_inflateEnd(&stream);
-+ zlib_workspace_free(stream.workspace);
-+
-+ return err;
-+}
-+EXPORT_SYMBOL(z_uncompress);
-+
-+int zlib_init(void)
-+{
-+ SENTRY;
-+ zlib_workspace_cache = kmem_cache_create("spl_zlib_workspace_cache",
-+ max(zlib_deflate_workspacesize(), zlib_inflate_workspacesize()),
-+ 0, NULL, NULL, NULL, NULL, NULL, KMC_VMEM);
-+ if (!zlib_workspace_cache)
-+ SRETURN(1);
-+
-+ SRETURN(0);
-+}
-+
-+void zlib_fini(void)
-+{
-+ SENTRY;
-+ kmem_cache_destroy(zlib_workspace_cache);
-+ zlib_workspace_cache = NULL;
-+ SEXIT;
-+}
-diff --git a/module/splat/Makefile.in b/module/splat/Makefile.in
-index 724f824..2bf25c5 100644
---- a/module/splat/Makefile.in
-+++ b/module/splat/Makefile.in
-@@ -23,3 +23,4 @@ splat-objs += @top_srcdir@/module/splat/splat-atomic.o
- splat-objs += @top_srcdir@/module/splat/splat-list.o
- splat-objs += @top_srcdir@/module/splat/splat-generic.o
- splat-objs += @top_srcdir@/module/splat/splat-cred.o
-+splat-objs += @top_srcdir@/module/splat/splat-zlib.o
-diff --git a/module/splat/splat-ctl.c b/module/splat/splat-ctl.c
-index de72b80..65ad8c1 100644
---- a/module/splat/splat-ctl.c
-+++ b/module/splat/splat-ctl.c
-@@ -632,6 +632,7 @@ splat_init(void)
- SPLAT_SUBSYSTEM_INIT(list);
- SPLAT_SUBSYSTEM_INIT(generic);
- SPLAT_SUBSYSTEM_INIT(cred);
-+ SPLAT_SUBSYSTEM_INIT(zlib);
-
- dev = MKDEV(SPLAT_MAJOR, 0);
- if ((rc = register_chrdev_region(dev, SPLAT_MINORS, SPLAT_NAME)))
-@@ -680,6 +681,7 @@ splat_fini(void)
- cdev_del(&splat_cdev);
- unregister_chrdev_region(dev, SPLAT_MINORS);
-
-+ SPLAT_SUBSYSTEM_FINI(zlib);
- SPLAT_SUBSYSTEM_FINI(cred);
- SPLAT_SUBSYSTEM_FINI(generic);
- SPLAT_SUBSYSTEM_FINI(list);
-diff --git a/module/splat/splat-internal.h b/module/splat/splat-internal.h
-index c42e08d..072abb8 100644
---- a/module/splat/splat-internal.h
-+++ b/module/splat/splat-internal.h
-@@ -63,6 +63,7 @@
- #include <sys/atomic.h>
- #include <sys/list.h>
- #include <sys/sunddi.h>
-+#include <sys/zmod.h>
- #include <linux/cdev.h>
-
- #include "spl-device.h"
-@@ -218,6 +219,7 @@ splat_subsystem_t *splat_atomic_init(void);
- splat_subsystem_t *splat_list_init(void);
- splat_subsystem_t *splat_generic_init(void);
- splat_subsystem_t *splat_cred_init(void);
-+splat_subsystem_t *splat_zlib_init(void);
-
- void splat_condvar_fini(splat_subsystem_t *);
- void splat_kmem_fini(splat_subsystem_t *);
-@@ -233,6 +235,7 @@ void splat_atomic_fini(splat_subsystem_t *);
- void splat_list_fini(splat_subsystem_t *);
- void splat_generic_fini(splat_subsystem_t *);
- void splat_cred_fini(splat_subsystem_t *);
-+void splat_zlib_fini(splat_subsystem_t *);
-
- int splat_condvar_id(void);
- int splat_kmem_id(void);
-@@ -248,5 +251,6 @@ int splat_atomic_id(void);
- int splat_list_id(void);
- int splat_generic_id(void);
- int splat_cred_id(void);
-+int splat_zlib_id(void);
-
- #endif /* _SPLAT_INTERNAL_H */
-diff --git a/module/splat/splat-zlib.c b/module/splat/splat-zlib.c
-new file mode 100644
-index 0000000..465d340
---- /dev/null
-+++ b/module/splat/splat-zlib.c
-@@ -0,0 +1,162 @@
-+/*****************************************************************************\
-+ * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
-+ * Copyright (C) 2007 The Regents of the University of California.
-+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
-+ * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
-+ * UCRL-CODE-235197
-+ *
-+ * This file is part of the SPL, Solaris Porting Layer.
-+ * For details, see <http://github.com/behlendorf/spl/>.
-+ *
-+ * The SPL is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ *
-+ * The SPL is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ * for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with the SPL. If not, see <http://www.gnu.org/licenses/>.
-+ *****************************************************************************
-+ * Solaris Porting LAyer Tests (SPLAT) Zlib Compression Tests.
-+\*****************************************************************************/
-+
-+#include "splat-internal.h"
-+
-+#define SPLAT_ZLIB_NAME "zlib"
-+#define SPLAT_ZLIB_DESC "Zlib Compression Tests"
-+
-+#define SPLAT_ZLIB_TEST1_ID 0x0f01
-+#define SPLAT_ZLIB_TEST1_NAME "compress/uncompress"
-+#define SPLAT_ZLIB_TEST1_DESC "Compress/Uncompress Test"
-+
-+#define BUFFER_SIZE (128 * 1024)
-+
-+static int
-+splat_zlib_test1_check(struct file *file, void *src, void *dst, void *chk,
-+ int level)
-+{
-+ size_t dst_len = BUFFER_SIZE;
-+ size_t chk_len = BUFFER_SIZE;
-+ int rc;
-+
-+ memset(dst, 0, BUFFER_SIZE);
-+ memset(chk, 0, BUFFER_SIZE);
-+
-+ rc = z_compress_level(dst, &dst_len, src, BUFFER_SIZE, level);
-+ if (rc != Z_OK) {
-+ splat_vprint(file, SPLAT_ZLIB_TEST1_NAME,
-+ "Failed level %d z_compress_level(), %d\n", level, rc);
-+ return -EINVAL;
-+ }
-+
-+ rc = z_uncompress(chk, &chk_len, dst, dst_len);
-+ if (rc != Z_OK) {
-+ splat_vprint(file, SPLAT_ZLIB_TEST1_NAME,
-+ "Failed level %d z_uncompress(), %d\n", level, rc);
-+ return -EINVAL;
-+ }
-+
-+ rc = memcmp(src, chk, BUFFER_SIZE);
-+ if (rc) {
-+ splat_vprint(file, SPLAT_ZLIB_TEST1_NAME,
-+ "Failed level %d memcmp()), %d\n", level, rc);
-+ return -EINVAL;
-+ }
-+
-+ splat_vprint(file, SPLAT_ZLIB_TEST1_NAME,
-+ "Passed level %d, compressed %d bytes to %d bytes\n",
-+ level, BUFFER_SIZE, (int)dst_len);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Compress a buffer, uncompress the newly compressed buffer, then
-+ * compare it to the original. Do this for all 9 compression levels.
-+ */
-+static int
-+splat_zlib_test1(struct file *file, void *arg)
-+{
-+ void *src = NULL, *dst = NULL, *chk = NULL;
-+ int i, rc, level;
-+
-+ src = vmalloc(BUFFER_SIZE);
-+ if (src == NULL) {
-+ rc = -ENOMEM;
-+ goto out;
-+ }
-+
-+ dst = vmalloc(BUFFER_SIZE);
-+ if (dst == NULL) {
-+ rc = -ENOMEM;
-+ goto out;
-+ }
-+
-+ chk = vmalloc(BUFFER_SIZE);
-+ if (chk == NULL) {
-+ rc = -ENOMEM;
-+ goto out;
-+ }
-+
-+ /* Source buffer is a repeating 1024 byte random pattern. */
-+ random_get_pseudo_bytes(src, sizeof(uint8_t) * 1024);
-+ for (i = 1; i < 128; i++)
-+ memcpy(src + (i * 1024), src, 1024);
-+
-+ for (level = 1; level <= 9; level++)
-+ if ((rc = splat_zlib_test1_check(file, src, dst, chk, level)))
-+ break;
-+out:
-+ if (src)
-+ vfree(src);
-+
-+ if (dst)
-+ vfree(dst);
-+
-+ if (chk)
-+ vfree(chk);
-+
-+ return rc;
-+}
-+
-+splat_subsystem_t *
-+splat_zlib_init(void)
-+{
-+ splat_subsystem_t *sub;
-+
-+ sub = kmalloc(sizeof(*sub), GFP_KERNEL);
-+ if (sub == NULL)
-+ return NULL;
-+
-+ memset(sub, 0, sizeof(*sub));
-+ strncpy(sub->desc.name, SPLAT_ZLIB_NAME, SPLAT_NAME_SIZE);
-+ strncpy(sub->desc.desc, SPLAT_ZLIB_DESC, SPLAT_DESC_SIZE);
-+ INIT_LIST_HEAD(&sub->subsystem_list);
-+ INIT_LIST_HEAD(&sub->test_list);
-+ spin_lock_init(&sub->test_lock);
-+ sub->desc.id = SPLAT_SUBSYSTEM_ZLIB;
-+
-+ SPLAT_TEST_INIT(sub, SPLAT_ZLIB_TEST1_NAME, SPLAT_ZLIB_TEST1_DESC,
-+ SPLAT_ZLIB_TEST1_ID, splat_zlib_test1);
-+
-+ return sub;
-+}
-+
-+void
-+splat_zlib_fini(splat_subsystem_t *sub)
-+{
-+ ASSERT(sub);
-+
-+ SPLAT_TEST_FINI(sub, SPLAT_ZLIB_TEST1_ID);
-+
-+ kfree(sub);
-+}
-+
-+int
-+splat_zlib_id(void) {
-+ return SPLAT_SUBSYSTEM_ZLIB;
-+}
-diff --git a/scripts/check.sh b/scripts/check.sh
-index b44b313..4e49406 100755
---- a/scripts/check.sh
-+++ b/scripts/check.sh
-@@ -62,6 +62,8 @@ if [ ! -f ${spl_module} ] || [ ! -f ${splat_module} ]; then
- die "Source tree must be built, run 'make'"
- fi
-
-+/sbin/modprobe zlib_deflate &>/dev/null
-+
- spl_module_params="spl_debug_mask=0xffffffff spl_debug_subsys=0xffffffff"
- echo "Loading ${spl_module}"
- /sbin/insmod ${spl_module} ${spl_module_params} || die "Failed to load ${spl_module}"
+++ /dev/null
-diff --git a/config/spl-build.m4 b/config/spl-build.m4
-index d8eadb7..2356f20 100644
---- a/config/spl-build.m4
-+++ b/config/spl-build.m4
-@@ -74,6 +74,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
- SPL_AC_KVASPRINTF
- SPL_AC_3ARGS_FILE_FSYNC
- SPL_AC_EXPORTED_RWSEM_IS_LOCKED
-+ SPL_AC_KERNEL_INVALIDATE_INODES
- ])
-
- AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
-@@ -1685,3 +1686,18 @@ AC_DEFUN([SPL_AC_EXPORTED_RWSEM_IS_LOCKED], [
- [rwsem_is_locked() acquires sem->wait_lock])],
- [])
- ])
-+
-+dnl #
-+dnl # 2.6.37 API compat,
-+dnl # The function invalidate_inodes() is no longer exported by the kernel.
-+dnl # The prototype however is still available which means it is safe
-+dnl # to acquire the symbol's address using spl_kallsyms_lookup_name().
-+dnl #
-+AC_DEFUN([SPL_AC_KERNEL_INVALIDATE_INODES], [
-+ SPL_CHECK_SYMBOL_EXPORT(
-+ [invalidate_inodes],
-+ [],
-+ [AC_DEFINE(HAVE_INVALIDATE_INODES, 1,
-+ [invalidate_inodes() is available])],
-+ [])
-+])
-diff --git a/configure b/configure
-index c3b0844..535ca2e 100755
---- a/configure
-+++ b/configure
-@@ -15334,6 +15334,47 @@ _ACEOF
- fi
-
-
-+
-+ { $as_echo "$as_me:$LINENO: checking whether symbol invalidate_inodes is exported" >&5
-+$as_echo_n "checking whether symbol invalidate_inodes is exported... " >&6; }
-+ grep -q -E '[[:space:]]invalidate_inodes[[:space:]]' \
-+ $LINUX_OBJ/Module*.symvers 2>/dev/null
-+ rc=$?
-+ if test $rc -ne 0; then
-+ export=0
-+ for file in ; do
-+ grep -q -E "EXPORT_SYMBOL.*(invalidate_inodes)" \
-+ "$LINUX_OBJ/$file" 2>/dev/null
-+ rc=$?
-+ if test $rc -eq 0; then
-+ export=1
-+ break;
-+ fi
-+ done
-+ if test $export -eq 0; then
-+ { $as_echo "$as_me:$LINENO: result: no" >&5
-+$as_echo "no" >&6; }
-+
-+ else
-+ { $as_echo "$as_me:$LINENO: result: yes" >&5
-+$as_echo "yes" >&6; }
-+
-+cat >>confdefs.h <<\_ACEOF
-+#define HAVE_INVALIDATE_INODES 1
-+_ACEOF
-+
-+ fi
-+ else
-+ { $as_echo "$as_me:$LINENO: result: yes" >&5
-+$as_echo "yes" >&6; }
-+
-+cat >>confdefs.h <<\_ACEOF
-+#define HAVE_INVALIDATE_INODES 1
-+_ACEOF
-+
-+ fi
-+
-+
- ;;
- user)
-
-@@ -19029,6 +19070,47 @@ _ACEOF
-
-
-
-+ { $as_echo "$as_me:$LINENO: checking whether symbol invalidate_inodes is exported" >&5
-+$as_echo_n "checking whether symbol invalidate_inodes is exported... " >&6; }
-+ grep -q -E '[[:space:]]invalidate_inodes[[:space:]]' \
-+ $LINUX_OBJ/Module*.symvers 2>/dev/null
-+ rc=$?
-+ if test $rc -ne 0; then
-+ export=0
-+ for file in ; do
-+ grep -q -E "EXPORT_SYMBOL.*(invalidate_inodes)" \
-+ "$LINUX_OBJ/$file" 2>/dev/null
-+ rc=$?
-+ if test $rc -eq 0; then
-+ export=1
-+ break;
-+ fi
-+ done
-+ if test $export -eq 0; then
-+ { $as_echo "$as_me:$LINENO: result: no" >&5
-+$as_echo "no" >&6; }
-+
-+ else
-+ { $as_echo "$as_me:$LINENO: result: yes" >&5
-+$as_echo "yes" >&6; }
-+
-+cat >>confdefs.h <<\_ACEOF
-+#define HAVE_INVALIDATE_INODES 1
-+_ACEOF
-+
-+ fi
-+ else
-+ { $as_echo "$as_me:$LINENO: result: yes" >&5
-+$as_echo "yes" >&6; }
-+
-+cat >>confdefs.h <<\_ACEOF
-+#define HAVE_INVALIDATE_INODES 1
-+_ACEOF
-+
-+ fi
-+
-+
-+
-
-
- if test "x$AWK" != xgawk; then
-diff --git a/include/linux/mm_compat.h b/include/linux/mm_compat.h
-index 57f83dc..5c5198b 100644
---- a/include/linux/mm_compat.h
-+++ b/include/linux/mm_compat.h
-@@ -26,6 +26,7 @@
- #define _SPL_MM_COMPAT_H
-
- #include <linux/mm.h>
-+#include <linux/fs.h>
-
- /*
- * Linux 2.6.31 API Change.
-@@ -43,4 +44,16 @@
- #define high_wmark_pages(z) (z->pages_high)
- #endif
-
-+/*
-+ * 2.6.37 API compat,
-+ * The function invalidate_inodes() is no longer exported by the kernel.
-+ * The prototype however is still available which means it is safe
-+ * to acquire the symbol's address using spl_kallsyms_lookup_name().
-+ */
-+#ifndef HAVE_INVALIDATE_INODES
-+typedef int (*invalidate_inodes_t)(struct super_block *sb);
-+extern invalidate_inodes_t invalidate_inodes_fn;
-+#define invalidate_inodes(sb) invalidate_inodes_fn(sb)
-+#endif /* HAVE_INVALIDATE_INODES */
-+
- #endif /* SPL_MM_COMPAT_H */
-diff --git a/include/sys/fcntl.h b/include/sys/fcntl.h
-index c7bc02a..4e260a4 100644
---- a/include/sys/fcntl.h
-+++ b/include/sys/fcntl.h
-@@ -28,12 +28,10 @@
-
- #define F_FREESP 11
-
--typedef struct flock64 {
-- short l_type;
-- short l_whence;
-- loff_t l_start;
-- loff_t l_len;
-- pid_t l_pid;
--} flock64_t;
-+#ifdef CONFIG_64BIT
-+typedef struct flock flock64_t;
-+#else
-+typedef struct flock64 flock64_t;
-+#endif /* CONFIG_64BIT */
-
- #endif /* _SPL_FCNTL_H */
-diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c
-index 1a9c1fe..100d674 100644
---- a/module/spl/spl-kmem.c
-+++ b/module/spl/spl-kmem.c
-@@ -180,6 +180,11 @@ spl_global_page_state(spl_zone_stat_item_t item)
- #endif /* NEED_GET_ZONE_COUNTS */
- EXPORT_SYMBOL(spl_global_page_state);
-
-+#ifndef HAVE_INVALIDATE_INODES
-+invalidate_inodes_t invalidate_inodes_fn = SYMBOL_POISON;
-+EXPORT_SYMBOL(invalidate_inodes_fn);
-+#endif /* HAVE_INVALIDATE_INODES */
-+
- pgcnt_t
- spl_kmem_availrmem(void)
- {
-@@ -2089,6 +2094,15 @@ spl_kmem_init_kallsyms_lookup(void)
- */
- spl_kmem_init_globals();
-
-+#ifndef HAVE_INVALIDATE_INODES
-+ invalidate_inodes_fn = (invalidate_inodes_t)
-+ spl_kallsyms_lookup_name("invalidate_inodes");
-+ if (!invalidate_inodes_fn) {
-+ printk(KERN_ERR "Error: Unknown symbol invalidate_inodes\n");
-+ return -EFAULT;
-+ }
-+#endif /* HAVE_INVALIDATE_INODES */
-+
- return 0;
- }
-
-diff --git a/spl_config.h.in b/spl_config.h.in
-index 7863f7b..a587841 100644
---- a/spl_config.h.in
-+++ b/spl_config.h.in
-@@ -102,6 +102,9 @@
- /* Define to 1 if you have the <inttypes.h> header file. */
- #undef HAVE_INTTYPES_H
-
-+/* invalidate_inodes() is available */
-+#undef HAVE_INVALIDATE_INODES
-+
- /* kallsyms_lookup_name() is available */
- #undef HAVE_KALLSYMS_LOOKUP_NAME
-