aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/lib/libspl
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/openzfs/lib/libspl')
-rw-r--r--sys/contrib/openzfs/lib/libspl/Makefile.am56
-rw-r--r--sys/contrib/openzfs/lib/libspl/asm-generic/.gitignore1
-rw-r--r--sys/contrib/openzfs/lib/libspl/asm-generic/atomic.c450
-rw-r--r--sys/contrib/openzfs/lib/libspl/asm-i386/atomic.S840
-rw-r--r--sys/contrib/openzfs/lib/libspl/asm-x86_64/atomic.S691
-rw-r--r--sys/contrib/openzfs/lib/libspl/assert.c46
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/Makefile.am22
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/assert.h151
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/atomic.h296
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/ia32/Makefile.am1
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/ia32/sys/Makefile.am3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/ia32/sys/asm_linkage.h302
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/libdevinfo.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/libgen.h35
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/libshare.h86
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/limits.h40
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/locale.h35
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/Makefile.am7
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/Makefile.am1
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/Makefile.am11
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/byteorder.h192
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/file.h42
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mnttab.h85
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h108
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h66
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/stat.h71
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/sysmacros.h1
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/vfs.h37
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/zfs_context_os.h34
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/Makefile.am1
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/Makefile.am10
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/byteorder.h223
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/errno.h46
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mnttab.h89
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mount.h98
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h67
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/stat.h50
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/sysmacros.h103
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/zfs_context_os.h25
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/rpc/Makefile.am3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/rpc/xdr.h68
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/statcommon.h41
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/stdio.h34
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/stdlib.h34
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/string.h40
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/stropts.h25
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/Makefile.am47
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/acl.h287
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/acl_impl.h59
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/callb.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/cred.h32
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/debug.h40
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/dkio.h483
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/dklabel.h268
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/dktp/Makefile.am4
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/dktp/fdisk.h173
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h32
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/int_limits.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/int_types.h32
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h34
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h264
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/kmem.h45
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/kstat.h822
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/list.h65
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/list_impl.h51
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/mhd.h159
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/mkdev.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/policy.h26
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/poll.h41
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/priv.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/processor.h34
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/sha2.h151
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/simd.h502
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/stack.h74
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h54
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/strings.h33
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/stropts.h29
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h29
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/systeminfo.h38
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/time.h107
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/trace_spl.h24
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/trace_zfs.h24
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/types.h77
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/types32.h89
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/tzfile.h164
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/uio.h153
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/va_list.h32
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/varargs.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/vnode.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/vtoc.h350
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/zone.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/thread.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/tzfile.h32
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/ucred.h32
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/umem.h208
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/unistd.h39
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/util/Makefile.am3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/util/sscanf.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/zone.h53
-rw-r--r--sys/contrib/openzfs/lib/libspl/list.c243
-rw-r--r--sys/contrib/openzfs/lib/libspl/mkdirp.c212
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c71
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/freebsd/gethostid.c36
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/freebsd/getmntany.c67
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c216
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c59
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c86
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c165
-rw-r--r--sys/contrib/openzfs/lib/libspl/page.c34
-rw-r--r--sys/contrib/openzfs/lib/libspl/strlcat.c60
-rw-r--r--sys/contrib/openzfs/lib/libspl/strlcpy.c56
-rw-r--r--sys/contrib/openzfs/lib/libspl/timestamp.c63
-rw-r--r--sys/contrib/openzfs/lib/libspl/zone.c63
114 files changed, 11723 insertions, 0 deletions
diff --git a/sys/contrib/openzfs/lib/libspl/Makefile.am b/sys/contrib/openzfs/lib/libspl/Makefile.am
new file mode 100644
index 000000000000..f576d69248fa
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/Makefile.am
@@ -0,0 +1,56 @@
+include $(top_srcdir)/config/Rules.am
+
+if TARGET_CPU_I386
+TARGET_CPU_ATOMIC_SOURCE = asm-i386/atomic.S
+else
+if TARGET_CPU_X86_64
+TARGET_CPU_ATOMIC_SOURCE = asm-x86_64/atomic.S
+else
+TARGET_CPU_ATOMIC_SOURCE = asm-generic/atomic.c
+endif
+endif
+
+SUBDIRS = include
+
+AM_CCASFLAGS = \
+ $(CFLAGS)
+
+noinst_LTLIBRARIES = libspl_assert.la libspl.la
+
+libspl_assert_la_SOURCES = \
+ assert.c
+
+USER_C = \
+ list.c \
+ mkdirp.c \
+ page.c \
+ strlcat.c \
+ strlcpy.c \
+ timestamp.c \
+ zone.c \
+ include/sys/list.h \
+ include/sys/list_impl.h
+
+if BUILD_LINUX
+USER_C += \
+ os/linux/getexecname.c \
+ os/linux/gethostid.c \
+ os/linux/getmntany.c
+endif
+
+if BUILD_FREEBSD
+USER_C += \
+ os/freebsd/getexecname.c \
+ os/freebsd/gethostid.c \
+ os/freebsd/getmntany.c \
+ os/freebsd/mnttab.c
+endif
+
+libspl_la_SOURCES = \
+ $(USER_C) \
+ $(TARGET_CPU_ATOMIC_SOURCE)
+
+libspl_la_LIBADD = \
+ libspl_assert.la
+
+libspl_la_LIBADD += $(LIBCLOCK_GETTIME)
diff --git a/sys/contrib/openzfs/lib/libspl/asm-generic/.gitignore b/sys/contrib/openzfs/lib/libspl/asm-generic/.gitignore
new file mode 100644
index 000000000000..2792cf7b4551
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/asm-generic/.gitignore
@@ -0,0 +1 @@
+/atomic.S
diff --git a/sys/contrib/openzfs/lib/libspl/asm-generic/atomic.c b/sys/contrib/openzfs/lib/libspl/asm-generic/atomic.c
new file mode 100644
index 000000000000..35535ea49c79
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/asm-generic/atomic.c
@@ -0,0 +1,450 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2009 by Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <atomic.h>
+#include <assert.h>
+#include <pthread.h>
+
+/*
+ * All operations are implemented by serializing them through a global
+ * pthread mutex. This provides a correct generic implementation.
+ * However all supported architectures are encouraged to provide a
+ * native implementation is assembly for performance reasons.
+ */
+pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/*
+ * These are the void returning variants
+ */
+/* BEGIN CSTYLED */
+#define ATOMIC_INC(name, type) \
+ void atomic_inc_##name(volatile type *target) \
+ { \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ (*target)++; \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ }
+
+ATOMIC_INC(8, uint8_t)
+ATOMIC_INC(uchar, uchar_t)
+ATOMIC_INC(16, uint16_t)
+ATOMIC_INC(ushort, ushort_t)
+ATOMIC_INC(32, uint32_t)
+ATOMIC_INC(uint, uint_t)
+ATOMIC_INC(ulong, ulong_t)
+ATOMIC_INC(64, uint64_t)
+
+
+#define ATOMIC_DEC(name, type) \
+ void atomic_dec_##name(volatile type *target) \
+ { \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ (*target)--; \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ }
+
+ATOMIC_DEC(8, uint8_t)
+ATOMIC_DEC(uchar, uchar_t)
+ATOMIC_DEC(16, uint16_t)
+ATOMIC_DEC(ushort, ushort_t)
+ATOMIC_DEC(32, uint32_t)
+ATOMIC_DEC(uint, uint_t)
+ATOMIC_DEC(ulong, ulong_t)
+ATOMIC_DEC(64, uint64_t)
+
+
+#define ATOMIC_ADD(name, type1, type2) \
+ void atomic_add_##name(volatile type1 *target, type2 bits) \
+ { \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ *target += bits; \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ }
+
+ATOMIC_ADD(8, uint8_t, int8_t)
+ATOMIC_ADD(char, uchar_t, signed char)
+ATOMIC_ADD(16, uint16_t, int16_t)
+ATOMIC_ADD(short, ushort_t, short)
+ATOMIC_ADD(32, uint32_t, int32_t)
+ATOMIC_ADD(int, uint_t, int)
+ATOMIC_ADD(long, ulong_t, long)
+ATOMIC_ADD(64, uint64_t, int64_t)
+
+void
+atomic_add_ptr(volatile void *target, ssize_t bits)
+{
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0);
+ *(caddr_t *)target += bits;
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+}
+
+
+#define ATOMIC_SUB(name, type1, type2) \
+ void atomic_sub_##name(volatile type1 *target, type2 bits) \
+ { \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ *target -= bits; \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ }
+
+ATOMIC_SUB(8, uint8_t, int8_t)
+ATOMIC_SUB(char, uchar_t, signed char)
+ATOMIC_SUB(16, uint16_t, int16_t)
+ATOMIC_SUB(short, ushort_t, short)
+ATOMIC_SUB(32, uint32_t, int32_t)
+ATOMIC_SUB(int, uint_t, int)
+ATOMIC_SUB(long, ulong_t, long)
+ATOMIC_SUB(64, uint64_t, int64_t)
+
+void
+atomic_sub_ptr(volatile void *target, ssize_t bits)
+{
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0);
+ *(caddr_t *)target -= bits;
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+}
+
+
+#define ATOMIC_OR(name, type) \
+ void atomic_or_##name(volatile type *target, type bits) \
+ { \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ *target |= bits; \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ }
+
+ATOMIC_OR(8, uint8_t)
+ATOMIC_OR(uchar, uchar_t)
+ATOMIC_OR(16, uint16_t)
+ATOMIC_OR(ushort, ushort_t)
+ATOMIC_OR(32, uint32_t)
+ATOMIC_OR(uint, uint_t)
+ATOMIC_OR(ulong, ulong_t)
+ATOMIC_OR(64, uint64_t)
+
+
+#define ATOMIC_AND(name, type) \
+ void atomic_and_##name(volatile type *target, type bits) \
+ { \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ *target &= bits; \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ }
+
+ATOMIC_AND(8, uint8_t)
+ATOMIC_AND(uchar, uchar_t)
+ATOMIC_AND(16, uint16_t)
+ATOMIC_AND(ushort, ushort_t)
+ATOMIC_AND(32, uint32_t)
+ATOMIC_AND(uint, uint_t)
+ATOMIC_AND(ulong, ulong_t)
+ATOMIC_AND(64, uint64_t)
+
+
+/*
+ * New value returning variants
+ */
+
+#define ATOMIC_INC_NV(name, type) \
+ type atomic_inc_##name##_nv(volatile type *target) \
+ { \
+ type rc; \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ rc = (++(*target)); \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ return (rc); \
+ }
+
+ATOMIC_INC_NV(8, uint8_t)
+ATOMIC_INC_NV(uchar, uchar_t)
+ATOMIC_INC_NV(16, uint16_t)
+ATOMIC_INC_NV(ushort, ushort_t)
+ATOMIC_INC_NV(32, uint32_t)
+ATOMIC_INC_NV(uint, uint_t)
+ATOMIC_INC_NV(ulong, ulong_t)
+ATOMIC_INC_NV(64, uint64_t)
+
+
+#define ATOMIC_DEC_NV(name, type) \
+ type atomic_dec_##name##_nv(volatile type *target) \
+ { \
+ type rc; \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ rc = (--(*target)); \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ return (rc); \
+ }
+
+ATOMIC_DEC_NV(8, uint8_t)
+ATOMIC_DEC_NV(uchar, uchar_t)
+ATOMIC_DEC_NV(16, uint16_t)
+ATOMIC_DEC_NV(ushort, ushort_t)
+ATOMIC_DEC_NV(32, uint32_t)
+ATOMIC_DEC_NV(uint, uint_t)
+ATOMIC_DEC_NV(ulong, ulong_t)
+ATOMIC_DEC_NV(64, uint64_t)
+
+
+#define ATOMIC_ADD_NV(name, type1, type2) \
+ type1 atomic_add_##name##_nv(volatile type1 *target, type2 bits)\
+ { \
+ type1 rc; \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ rc = (*target += bits); \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ return (rc); \
+ }
+
+ATOMIC_ADD_NV(8, uint8_t, int8_t)
+ATOMIC_ADD_NV(char, uchar_t, signed char)
+ATOMIC_ADD_NV(16, uint16_t, int16_t)
+ATOMIC_ADD_NV(short, ushort_t, short)
+ATOMIC_ADD_NV(32, uint32_t, int32_t)
+ATOMIC_ADD_NV(int, uint_t, int)
+ATOMIC_ADD_NV(long, ulong_t, long)
+ATOMIC_ADD_NV(64, uint64_t, int64_t)
+
+void *
+atomic_add_ptr_nv(volatile void *target, ssize_t bits)
+{
+ void *ptr;
+
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0);
+ ptr = (*(caddr_t *)target += bits);
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+
+ return (ptr);
+}
+
+
+#define ATOMIC_SUB_NV(name, type1, type2) \
+ type1 atomic_sub_##name##_nv(volatile type1 *target, type2 bits)\
+ { \
+ type1 rc; \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ rc = (*target -= bits); \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ return (rc); \
+ }
+
+ATOMIC_SUB_NV(8, uint8_t, int8_t)
+ATOMIC_SUB_NV(char, uchar_t, signed char)
+ATOMIC_SUB_NV(16, uint16_t, int16_t)
+ATOMIC_SUB_NV(short, ushort_t, short)
+ATOMIC_SUB_NV(32, uint32_t, int32_t)
+ATOMIC_SUB_NV(int, uint_t, int)
+ATOMIC_SUB_NV(long, ulong_t, long)
+ATOMIC_SUB_NV(64, uint64_t, int64_t)
+
+void *
+atomic_sub_ptr_nv(volatile void *target, ssize_t bits)
+{
+ void *ptr;
+
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0);
+ ptr = (*(caddr_t *)target -= bits);
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+
+ return (ptr);
+}
+
+
+#define ATOMIC_OR_NV(name, type) \
+ type atomic_or_##name##_nv(volatile type *target, type bits) \
+ { \
+ type rc; \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ rc = (*target |= bits); \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ return (rc); \
+ }
+
+ATOMIC_OR_NV(8, uint8_t)
+ATOMIC_OR_NV(uchar, uchar_t)
+ATOMIC_OR_NV(16, uint16_t)
+ATOMIC_OR_NV(ushort, ushort_t)
+ATOMIC_OR_NV(32, uint32_t)
+ATOMIC_OR_NV(uint, uint_t)
+ATOMIC_OR_NV(ulong, ulong_t)
+ATOMIC_OR_NV(64, uint64_t)
+
+
+#define ATOMIC_AND_NV(name, type) \
+ type atomic_and_##name##_nv(volatile type *target, type bits) \
+ { \
+ type rc; \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ rc = (*target &= bits); \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ return (rc); \
+ }
+
+ATOMIC_AND_NV(8, uint8_t)
+ATOMIC_AND_NV(uchar, uchar_t)
+ATOMIC_AND_NV(16, uint16_t)
+ATOMIC_AND_NV(ushort, ushort_t)
+ATOMIC_AND_NV(32, uint32_t)
+ATOMIC_AND_NV(uint, uint_t)
+ATOMIC_AND_NV(ulong, ulong_t)
+ATOMIC_AND_NV(64, uint64_t)
+
+
+/*
+ * If *arg1 == arg2, set *arg1 = arg3; return old value
+ */
+
+#define ATOMIC_CAS(name, type) \
+ type atomic_cas_##name(volatile type *target, type arg1, type arg2) \
+ { \
+ type old; \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ old = *target; \
+ if (old == arg1) \
+ *target = arg2; \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ return (old); \
+ }
+
+ATOMIC_CAS(8, uint8_t)
+ATOMIC_CAS(uchar, uchar_t)
+ATOMIC_CAS(16, uint16_t)
+ATOMIC_CAS(ushort, ushort_t)
+ATOMIC_CAS(32, uint32_t)
+ATOMIC_CAS(uint, uint_t)
+ATOMIC_CAS(ulong, ulong_t)
+ATOMIC_CAS(64, uint64_t)
+
+void *
+atomic_cas_ptr(volatile void *target, void *arg1, void *arg2)
+{
+ void *old;
+
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0);
+ old = *(void **)target;
+ if (old == arg1)
+ *(void **)target = arg2;
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+
+ return (old);
+}
+
+
+/*
+ * Swap target and return old value
+ */
+
+#define ATOMIC_SWAP(name, type) \
+ type atomic_swap_##name(volatile type *target, type bits) \
+ { \
+ type old; \
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \
+ old = *target; \
+ *target = bits; \
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \
+ return (old); \
+ }
+
+ATOMIC_SWAP(8, uint8_t)
+ATOMIC_SWAP(uchar, uchar_t)
+ATOMIC_SWAP(16, uint16_t)
+ATOMIC_SWAP(ushort, ushort_t)
+ATOMIC_SWAP(32, uint32_t)
+ATOMIC_SWAP(uint, uint_t)
+ATOMIC_SWAP(ulong, ulong_t)
+ATOMIC_SWAP(64, uint64_t)
+/* END CSTYLED */
+
+void *
+atomic_swap_ptr(volatile void *target, void *bits)
+{
+ void *old;
+
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0);
+ old = *(void **)target;
+ *(void **)target = bits;
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+
+ return (old);
+}
+
+
+int
+atomic_set_long_excl(volatile ulong_t *target, uint_t value)
+{
+ ulong_t bit;
+
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0);
+ bit = (1UL << value);
+ if ((*target & bit) != 0) {
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+ return (-1);
+ }
+ *target |= bit;
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+
+ return (0);
+}
+
+int
+atomic_clear_long_excl(volatile ulong_t *target, uint_t value)
+{
+ ulong_t bit;
+
+ VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0);
+ bit = (1UL << value);
+ if ((*target & bit) == 0) {
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+ return (-1);
+ }
+ *target &= ~bit;
+ VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0);
+
+ return (0);
+}
+
+void
+membar_enter(void)
+{
+ /* XXX - Implement me */
+}
+
+void
+membar_exit(void)
+{
+ /* XXX - Implement me */
+}
+
+void
+membar_producer(void)
+{
+ /* XXX - Implement me */
+}
+
+void
+membar_consumer(void)
+{
+ /* XXX - Implement me */
+}
diff --git a/sys/contrib/openzfs/lib/libspl/asm-i386/atomic.S b/sys/contrib/openzfs/lib/libspl/asm-i386/atomic.S
new file mode 100644
index 000000000000..7a574b0d1729
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/asm-i386/atomic.S
@@ -0,0 +1,840 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+ .ident "%Z%%M% %I% %E% SMI"
+
+ .file "%M%"
+
+#define _ASM
+#ifdef __linux__
+#include <ia32/sys/asm_linkage.h>
+#elif __FreeBSD__
+#include <machine/asmacros.h>
+#define SET_SIZE(x)
+#endif
+ ENTRY(atomic_inc_8)
+ ALTENTRY(atomic_inc_uchar)
+ movl 4(%esp), %eax
+ lock
+ incb (%eax)
+ ret
+ SET_SIZE(atomic_inc_uchar)
+ SET_SIZE(atomic_inc_8)
+
+ ENTRY(atomic_inc_16)
+ ALTENTRY(atomic_inc_ushort)
+ movl 4(%esp), %eax
+ lock
+ incw (%eax)
+ ret
+ SET_SIZE(atomic_inc_ushort)
+ SET_SIZE(atomic_inc_16)
+
+ ENTRY(atomic_inc_32)
+ ALTENTRY(atomic_inc_uint)
+ ALTENTRY(atomic_inc_ulong)
+ movl 4(%esp), %eax
+ lock
+ incl (%eax)
+ ret
+ SET_SIZE(atomic_inc_ulong)
+ SET_SIZE(atomic_inc_uint)
+ SET_SIZE(atomic_inc_32)
+
+ ENTRY(atomic_inc_8_nv)
+ ALTENTRY(atomic_inc_uchar_nv)
+ movl 4(%esp), %edx
+ movb (%edx), %al
+1:
+ leal 1(%eax), %ecx
+ lock
+ cmpxchgb %cl, (%edx)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_inc_uchar_nv)
+ SET_SIZE(atomic_inc_8_nv)
+
+ ENTRY(atomic_inc_16_nv)
+ ALTENTRY(atomic_inc_ushort_nv)
+ movl 4(%esp), %edx
+ movw (%edx), %ax
+1:
+ leal 1(%eax), %ecx
+ lock
+ cmpxchgw %cx, (%edx)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_inc_ushort_nv)
+ SET_SIZE(atomic_inc_16_nv)
+
+ ENTRY(atomic_inc_32_nv)
+ ALTENTRY(atomic_inc_uint_nv)
+ ALTENTRY(atomic_inc_ulong_nv)
+ movl 4(%esp), %edx
+ movl (%edx), %eax
+1:
+ leal 1(%eax), %ecx
+ lock
+ cmpxchgl %ecx, (%edx)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_inc_ulong_nv)
+ SET_SIZE(atomic_inc_uint_nv)
+ SET_SIZE(atomic_inc_32_nv)
+
+ /*
+ * NOTE: If atomic_inc_64 and atomic_inc_64_nv are ever
+ * separated, you need to also edit the libc i386 platform
+ * specific mapfile and remove the NODYNSORT attribute
+ * from atomic_inc_64_nv.
+ */
+ ENTRY(atomic_inc_64)
+ ALTENTRY(atomic_inc_64_nv)
+ pushl %edi
+ pushl %ebx
+ movl 12(%esp), %edi
+ movl (%edi), %eax
+ movl 4(%edi), %edx
+1:
+ xorl %ebx, %ebx
+ xorl %ecx, %ecx
+ incl %ebx
+ addl %eax, %ebx
+ adcl %edx, %ecx
+ lock
+ cmpxchg8b (%edi)
+ jne 1b
+ movl %ebx, %eax
+ movl %ecx, %edx
+ popl %ebx
+ popl %edi
+ ret
+ SET_SIZE(atomic_inc_64_nv)
+ SET_SIZE(atomic_inc_64)
+
+ ENTRY(atomic_dec_8)
+ ALTENTRY(atomic_dec_uchar)
+ movl 4(%esp), %eax
+ lock
+ decb (%eax)
+ ret
+ SET_SIZE(atomic_dec_uchar)
+ SET_SIZE(atomic_dec_8)
+
+ ENTRY(atomic_dec_16)
+ ALTENTRY(atomic_dec_ushort)
+ movl 4(%esp), %eax
+ lock
+ decw (%eax)
+ ret
+ SET_SIZE(atomic_dec_ushort)
+ SET_SIZE(atomic_dec_16)
+
+ ENTRY(atomic_dec_32)
+ ALTENTRY(atomic_dec_uint)
+ ALTENTRY(atomic_dec_ulong)
+ movl 4(%esp), %eax
+ lock
+ decl (%eax)
+ ret
+ SET_SIZE(atomic_dec_ulong)
+ SET_SIZE(atomic_dec_uint)
+ SET_SIZE(atomic_dec_32)
+
+ ENTRY(atomic_dec_8_nv)
+ ALTENTRY(atomic_dec_uchar_nv)
+ movl 4(%esp), %edx
+ movb (%edx), %al
+1:
+ leal -1(%eax), %ecx
+ lock
+ cmpxchgb %cl, (%edx)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_dec_uchar_nv)
+ SET_SIZE(atomic_dec_8_nv)
+
+ ENTRY(atomic_dec_16_nv)
+ ALTENTRY(atomic_dec_ushort_nv)
+ movl 4(%esp), %edx
+ movw (%edx), %ax
+1:
+ leal -1(%eax), %ecx
+ lock
+ cmpxchgw %cx, (%edx)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_dec_ushort_nv)
+ SET_SIZE(atomic_dec_16_nv)
+
+ ENTRY(atomic_dec_32_nv)
+ ALTENTRY(atomic_dec_uint_nv)
+ ALTENTRY(atomic_dec_ulong_nv)
+ movl 4(%esp), %edx
+ movl (%edx), %eax
+1:
+ leal -1(%eax), %ecx
+ lock
+ cmpxchgl %ecx, (%edx)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_dec_ulong_nv)
+ SET_SIZE(atomic_dec_uint_nv)
+ SET_SIZE(atomic_dec_32_nv)
+
+ /*
+ * NOTE: If atomic_dec_64 and atomic_dec_64_nv are ever
+ * separated, it is important to edit the libc i386 platform
+ * specific mapfile and remove the NODYNSORT attribute
+ * from atomic_dec_64_nv.
+ */
+ ENTRY(atomic_dec_64)
+ ALTENTRY(atomic_dec_64_nv)
+ pushl %edi
+ pushl %ebx
+ movl 12(%esp), %edi
+ movl (%edi), %eax
+ movl 4(%edi), %edx
+1:
+ xorl %ebx, %ebx
+ xorl %ecx, %ecx
+ not %ecx
+ not %ebx
+ addl %eax, %ebx
+ adcl %edx, %ecx
+ lock
+ cmpxchg8b (%edi)
+ jne 1b
+ movl %ebx, %eax
+ movl %ecx, %edx
+ popl %ebx
+ popl %edi
+ ret
+ SET_SIZE(atomic_dec_64_nv)
+ SET_SIZE(atomic_dec_64)
+
+ ENTRY(atomic_add_8)
+ ALTENTRY(atomic_add_char)
+ movl 4(%esp), %eax
+ movl 8(%esp), %ecx
+ lock
+ addb %cl, (%eax)
+ ret
+ SET_SIZE(atomic_add_char)
+ SET_SIZE(atomic_add_8)
+
+ ENTRY(atomic_add_16)
+ ALTENTRY(atomic_add_short)
+ movl 4(%esp), %eax
+ movl 8(%esp), %ecx
+ lock
+ addw %cx, (%eax)
+ ret
+ SET_SIZE(atomic_add_short)
+ SET_SIZE(atomic_add_16)
+
+ ENTRY(atomic_add_32)
+ ALTENTRY(atomic_add_int)
+ ALTENTRY(atomic_add_ptr)
+ ALTENTRY(atomic_add_long)
+ movl 4(%esp), %eax
+ movl 8(%esp), %ecx
+ lock
+ addl %ecx, (%eax)
+ ret
+ SET_SIZE(atomic_add_long)
+ SET_SIZE(atomic_add_ptr)
+ SET_SIZE(atomic_add_int)
+ SET_SIZE(atomic_add_32)
+
+ ENTRY(atomic_sub_8)
+ ALTENTRY(atomic_sub_char)
+ movl 4(%esp), %eax
+ movl 8(%esp), %ecx
+ lock
+ subb %cl, (%eax)
+ ret
+ SET_SIZE(atomic_sub_char)
+ SET_SIZE(atomic_sub_8)
+
+ ENTRY(atomic_sub_16)
+ ALTENTRY(atomic_sub_short)
+ movl 4(%esp), %eax
+ movl 8(%esp), %ecx
+ lock
+ subw %cx, (%eax)
+ ret
+ SET_SIZE(atomic_sub_short)
+ SET_SIZE(atomic_sub_16)
+
+ ENTRY(atomic_sub_32)
+ ALTENTRY(atomic_sub_int)
+ ALTENTRY(atomic_sub_ptr)
+ ALTENTRY(atomic_sub_long)
+ movl 4(%esp), %eax
+ movl 8(%esp), %ecx
+ lock
+ subl %ecx, (%eax)
+ ret
+ SET_SIZE(atomic_sub_long)
+ SET_SIZE(atomic_sub_ptr)
+ SET_SIZE(atomic_sub_int)
+ SET_SIZE(atomic_sub_32)
+
+ ENTRY(atomic_or_8)
+ ALTENTRY(atomic_or_uchar)
+ movl 4(%esp), %eax
+ movb 8(%esp), %cl
+ lock
+ orb %cl, (%eax)
+ ret
+ SET_SIZE(atomic_or_uchar)
+ SET_SIZE(atomic_or_8)
+
+ ENTRY(atomic_or_16)
+ ALTENTRY(atomic_or_ushort)
+ movl 4(%esp), %eax
+ movw 8(%esp), %cx
+ lock
+ orw %cx, (%eax)
+ ret
+ SET_SIZE(atomic_or_ushort)
+ SET_SIZE(atomic_or_16)
+
+ ENTRY(atomic_or_32)
+ ALTENTRY(atomic_or_uint)
+ ALTENTRY(atomic_or_ulong)
+ movl 4(%esp), %eax
+ movl 8(%esp), %ecx
+ lock
+ orl %ecx, (%eax)
+ ret
+ SET_SIZE(atomic_or_ulong)
+ SET_SIZE(atomic_or_uint)
+ SET_SIZE(atomic_or_32)
+
+ ENTRY(atomic_and_8)
+ ALTENTRY(atomic_and_uchar)
+ movl 4(%esp), %eax
+ movb 8(%esp), %cl
+ lock
+ andb %cl, (%eax)
+ ret
+ SET_SIZE(atomic_and_uchar)
+ SET_SIZE(atomic_and_8)
+
+ ENTRY(atomic_and_16)
+ ALTENTRY(atomic_and_ushort)
+ movl 4(%esp), %eax
+ movw 8(%esp), %cx
+ lock
+ andw %cx, (%eax)
+ ret
+ SET_SIZE(atomic_and_ushort)
+ SET_SIZE(atomic_and_16)
+
+ ENTRY(atomic_and_32)
+ ALTENTRY(atomic_and_uint)
+ ALTENTRY(atomic_and_ulong)
+ movl 4(%esp), %eax
+ movl 8(%esp), %ecx
+ lock
+ andl %ecx, (%eax)
+ ret
+ SET_SIZE(atomic_and_ulong)
+ SET_SIZE(atomic_and_uint)
+ SET_SIZE(atomic_and_32)
+
+ ENTRY(atomic_add_8_nv)
+ ALTENTRY(atomic_add_char_nv)
+ movl 4(%esp), %edx
+ movb (%edx), %al
+1:
+ movl 8(%esp), %ecx
+ addb %al, %cl
+ lock
+ cmpxchgb %cl, (%edx)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_add_char_nv)
+ SET_SIZE(atomic_add_8_nv)
+
+ ENTRY(atomic_add_16_nv)
+ ALTENTRY(atomic_add_short_nv)
+ movl 4(%esp), %edx
+ movw (%edx), %ax
+1:
+ movl 8(%esp), %ecx
+ addw %ax, %cx
+ lock
+ cmpxchgw %cx, (%edx)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_add_short_nv)
+ SET_SIZE(atomic_add_16_nv)
+
+ ENTRY(atomic_add_32_nv)
+ ALTENTRY(atomic_add_int_nv)
+ ALTENTRY(atomic_add_ptr_nv)
+ ALTENTRY(atomic_add_long_nv)
+ movl 4(%esp), %edx
+ movl (%edx), %eax
+1:
+ movl 8(%esp), %ecx
+ addl %eax, %ecx
+ lock
+ cmpxchgl %ecx, (%edx)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_add_long_nv)
+ SET_SIZE(atomic_add_ptr_nv)
+ SET_SIZE(atomic_add_int_nv)
+ SET_SIZE(atomic_add_32_nv)
+
+ ENTRY(atomic_sub_8_nv)
+ ALTENTRY(atomic_sub_char_nv)
+ movl 4(%esp), %edx
+ movb (%edx), %al
+1:
+ movl 8(%esp), %ecx
+ subb %al, %cl
+ lock
+ cmpxchgb %cl, (%edx)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_sub_char_nv)
+ SET_SIZE(atomic_sub_8_nv)
+
+ ENTRY(atomic_sub_16_nv)
+ ALTENTRY(atomic_sub_short_nv)
+ movl 4(%esp), %edx
+ movw (%edx), %ax
+1:
+ movl 8(%esp), %ecx
+ subw %ax, %cx
+ lock
+ cmpxchgw %cx, (%edx)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_sub_short_nv)
+ SET_SIZE(atomic_sub_16_nv)
+
+ ENTRY(atomic_sub_32_nv)
+ ALTENTRY(atomic_sub_int_nv)
+ ALTENTRY(atomic_sub_ptr_nv)
+ ALTENTRY(atomic_sub_long_nv)
+ movl 4(%esp), %edx
+ movl (%edx), %eax
+1:
+ movl 8(%esp), %ecx
+ subl %eax, %ecx
+ lock
+ cmpxchgl %ecx, (%edx)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_sub_long_nv)
+ SET_SIZE(atomic_sub_ptr_nv)
+ SET_SIZE(atomic_sub_int_nv)
+ SET_SIZE(atomic_sub_32_nv)
+
+ /*
+ * NOTE: If atomic_add_64 and atomic_add_64_nv are ever
+ * separated, it is important to edit the libc i386 platform
+ * specific mapfile and remove the NODYNSORT attribute
+ * from atomic_add_64_nv.
+ */
+ ENTRY(atomic_add_64)
+ ALTENTRY(atomic_add_64_nv)
+ pushl %edi
+ pushl %ebx
+ movl 12(%esp), %edi
+ movl (%edi), %eax
+ movl 4(%edi), %edx
+1:
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx
+ addl %eax, %ebx
+ adcl %edx, %ecx
+ lock
+ cmpxchg8b (%edi)
+ jne 1b
+ movl %ebx, %eax
+ movl %ecx, %edx
+ popl %ebx
+ popl %edi
+ ret
+ SET_SIZE(atomic_add_64_nv)
+ SET_SIZE(atomic_add_64)
+
+ ENTRY(atomic_sub_64)
+ ALTENTRY(atomic_sub_64_nv)
+ pushl %edi
+ pushl %ebx
+ movl 12(%esp), %edi
+ movl (%edi), %eax
+ movl 4(%edi), %edx
+1:
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx
+ subl %eax, %ebx
+ sbbl %edx, %ecx
+ lock
+ cmpxchg8b (%edi)
+ jne 1b
+ movl %ebx, %eax
+ movl %ecx, %edx
+ popl %ebx
+ popl %edi
+ ret
+ SET_SIZE(atomic_sub_64_nv)
+ SET_SIZE(atomic_sub_64)
+
+ ENTRY(atomic_or_8_nv)
+ ALTENTRY(atomic_or_uchar_nv)
+ movl 4(%esp), %edx
+ movb (%edx), %al
+1:
+ movl 8(%esp), %ecx
+ orb %al, %cl
+ lock
+ cmpxchgb %cl, (%edx)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_or_uchar_nv)
+ SET_SIZE(atomic_or_8_nv)
+
+ ENTRY(atomic_or_16_nv)
+ ALTENTRY(atomic_or_ushort_nv)
+ movl 4(%esp), %edx
+ movw (%edx), %ax
+1:
+ movl 8(%esp), %ecx
+ orw %ax, %cx
+ lock
+ cmpxchgw %cx, (%edx)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_or_ushort_nv)
+ SET_SIZE(atomic_or_16_nv)
+
+ ENTRY(atomic_or_32_nv)
+ ALTENTRY(atomic_or_uint_nv)
+ ALTENTRY(atomic_or_ulong_nv)
+ movl 4(%esp), %edx
+ movl (%edx), %eax
+1:
+ movl 8(%esp), %ecx
+ orl %eax, %ecx
+ lock
+ cmpxchgl %ecx, (%edx)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_or_ulong_nv)
+ SET_SIZE(atomic_or_uint_nv)
+ SET_SIZE(atomic_or_32_nv)
+
+ /*
+ * NOTE: If atomic_or_64 and atomic_or_64_nv are ever
+ * separated, it is important to edit the libc i386 platform
+ * specific mapfile and remove the NODYNSORT attribute
+ * from atomic_or_64_nv.
+ */
+ ENTRY(atomic_or_64)
+ ALTENTRY(atomic_or_64_nv)
+ pushl %edi
+ pushl %ebx
+ movl 12(%esp), %edi
+ movl (%edi), %eax
+ movl 4(%edi), %edx
+1:
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx
+ orl %eax, %ebx
+ orl %edx, %ecx
+ lock
+ cmpxchg8b (%edi)
+ jne 1b
+ movl %ebx, %eax
+ movl %ecx, %edx
+ popl %ebx
+ popl %edi
+ ret
+ SET_SIZE(atomic_or_64_nv)
+ SET_SIZE(atomic_or_64)
+
+ ENTRY(atomic_and_8_nv)
+ ALTENTRY(atomic_and_uchar_nv)
+ movl 4(%esp), %edx
+ movb (%edx), %al
+1:
+ movl 8(%esp), %ecx
+ andb %al, %cl
+ lock
+ cmpxchgb %cl, (%edx)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_and_uchar_nv)
+ SET_SIZE(atomic_and_8_nv)
+
+ ENTRY(atomic_and_16_nv)
+ ALTENTRY(atomic_and_ushort_nv)
+ movl 4(%esp), %edx
+ movw (%edx), %ax
+1:
+ movl 8(%esp), %ecx
+ andw %ax, %cx
+ lock
+ cmpxchgw %cx, (%edx)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_and_ushort_nv)
+ SET_SIZE(atomic_and_16_nv)
+
+ ENTRY(atomic_and_32_nv)
+ ALTENTRY(atomic_and_uint_nv)
+ ALTENTRY(atomic_and_ulong_nv)
+ movl 4(%esp), %edx
+ movl (%edx), %eax
+1:
+ movl 8(%esp), %ecx
+ andl %eax, %ecx
+ lock
+ cmpxchgl %ecx, (%edx)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_and_ulong_nv)
+ SET_SIZE(atomic_and_uint_nv)
+ SET_SIZE(atomic_and_32_nv)
+
+ /*
+ * NOTE: If atomic_and_64 and atomic_and_64_nv are ever
+ * separated, it is important to edit the libc i386 platform
+ * specific mapfile and remove the NODYNSORT attribute
+ * from atomic_and_64_nv.
+ */
+ ENTRY(atomic_and_64)
+ ALTENTRY(atomic_and_64_nv)
+ pushl %edi
+ pushl %ebx
+ movl 12(%esp), %edi
+ movl (%edi), %eax
+ movl 4(%edi), %edx
+1:
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx
+ andl %eax, %ebx
+ andl %edx, %ecx
+ lock
+ cmpxchg8b (%edi)
+ jne 1b
+ movl %ebx, %eax
+ movl %ecx, %edx
+ popl %ebx
+ popl %edi
+ ret
+ SET_SIZE(atomic_and_64_nv)
+ SET_SIZE(atomic_and_64)
+
+ ENTRY(atomic_cas_8)
+ ALTENTRY(atomic_cas_uchar)
+ movl 4(%esp), %edx
+ movzbl 8(%esp), %eax
+ movb 12(%esp), %cl
+ lock
+ cmpxchgb %cl, (%edx)
+ ret
+ SET_SIZE(atomic_cas_uchar)
+ SET_SIZE(atomic_cas_8)
+
+ ENTRY(atomic_cas_16)
+ ALTENTRY(atomic_cas_ushort)
+ movl 4(%esp), %edx
+ movzwl 8(%esp), %eax
+ movw 12(%esp), %cx
+ lock
+ cmpxchgw %cx, (%edx)
+ ret
+ SET_SIZE(atomic_cas_ushort)
+ SET_SIZE(atomic_cas_16)
+
+ ENTRY(atomic_cas_32)
+ ALTENTRY(atomic_cas_uint)
+ ALTENTRY(atomic_cas_ulong)
+ ALTENTRY(atomic_cas_ptr)
+ movl 4(%esp), %edx
+ movl 8(%esp), %eax
+ movl 12(%esp), %ecx
+ lock
+ cmpxchgl %ecx, (%edx)
+ ret
+ SET_SIZE(atomic_cas_ptr)
+ SET_SIZE(atomic_cas_ulong)
+ SET_SIZE(atomic_cas_uint)
+ SET_SIZE(atomic_cas_32)
+
+ ENTRY(atomic_cas_64)
+ pushl %ebx
+ pushl %esi
+ movl 12(%esp), %esi
+ movl 16(%esp), %eax
+ movl 20(%esp), %edx
+ movl 24(%esp), %ebx
+ movl 28(%esp), %ecx
+ lock
+ cmpxchg8b (%esi)
+ popl %esi
+ popl %ebx
+ ret
+ SET_SIZE(atomic_cas_64)
+
+ ENTRY(atomic_swap_8)
+ ALTENTRY(atomic_swap_uchar)
+ movl 4(%esp), %edx
+ movzbl 8(%esp), %eax
+ lock
+ xchgb %al, (%edx)
+ ret
+ SET_SIZE(atomic_swap_uchar)
+ SET_SIZE(atomic_swap_8)
+
+ ENTRY(atomic_swap_16)
+ ALTENTRY(atomic_swap_ushort)
+ movl 4(%esp), %edx
+ movzwl 8(%esp), %eax
+ lock
+ xchgw %ax, (%edx)
+ ret
+ SET_SIZE(atomic_swap_ushort)
+ SET_SIZE(atomic_swap_16)
+
+ ENTRY(atomic_swap_32)
+ ALTENTRY(atomic_swap_uint)
+ ALTENTRY(atomic_swap_ptr)
+ ALTENTRY(atomic_swap_ulong)
+ movl 4(%esp), %edx
+ movl 8(%esp), %eax
+ lock
+ xchgl %eax, (%edx)
+ ret
+ SET_SIZE(atomic_swap_ulong)
+ SET_SIZE(atomic_swap_ptr)
+ SET_SIZE(atomic_swap_uint)
+ SET_SIZE(atomic_swap_32)
+
+ ENTRY(atomic_swap_64)
+ pushl %esi
+ pushl %ebx
+ movl 12(%esp), %esi
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx
+ movl (%esi), %eax
+ movl 4(%esi), %edx
+1:
+ lock
+ cmpxchg8b (%esi)
+ jne 1b
+ popl %ebx
+ popl %esi
+ ret
+ SET_SIZE(atomic_swap_64)
+
+ ENTRY(atomic_set_long_excl)
+ movl 4(%esp), %edx
+ movl 8(%esp), %ecx
+ xorl %eax, %eax
+ lock
+ btsl %ecx, (%edx)
+ jnc 1f
+ decl %eax
+1:
+ ret
+ SET_SIZE(atomic_set_long_excl)
+
+ ENTRY(atomic_clear_long_excl)
+ movl 4(%esp), %edx
+ movl 8(%esp), %ecx
+ xorl %eax, %eax
+ lock
+ btrl %ecx, (%edx)
+ jc 1f
+ decl %eax
+1:
+ ret
+ SET_SIZE(atomic_clear_long_excl)
+
+ /*
+ * NOTE: membar_enter, membar_exit, membar_producer, and
+ * membar_consumer are all identical routines. We define them
+ * separately, instead of using ALTENTRY definitions to alias them
+ * together, so that DTrace and debuggers will see a unique address
+ * for them, allowing more accurate tracing.
+ */
+
+
+ ENTRY(membar_enter)
+ lock
+ xorl $0, (%esp)
+ ret
+ SET_SIZE(membar_enter)
+
+ ENTRY(membar_exit)
+ lock
+ xorl $0, (%esp)
+ ret
+ SET_SIZE(membar_exit)
+
+ ENTRY(membar_producer)
+ lock
+ xorl $0, (%esp)
+ ret
+ SET_SIZE(membar_producer)
+
+ ENTRY(membar_consumer)
+ lock
+ xorl $0, (%esp)
+ ret
+ SET_SIZE(membar_consumer)
+
+#ifdef __ELF__
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/asm-x86_64/atomic.S b/sys/contrib/openzfs/lib/libspl/asm-x86_64/atomic.S
new file mode 100644
index 000000000000..50edfe878cc9
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/asm-x86_64/atomic.S
@@ -0,0 +1,691 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+ .ident "%Z%%M% %I% %E% SMI"
+
+ .file "%M%"
+
+#define _ASM
+#ifdef __linux__
+#include <ia32/sys/asm_linkage.h>
+#elif __FreeBSD__
+#include <machine/asmacros.h>
+#define SET_SIZE(x)
+#endif
+ ENTRY(atomic_inc_8)
+ ALTENTRY(atomic_inc_uchar)
+ lock
+ incb (%rdi)
+ ret
+ SET_SIZE(atomic_inc_uchar)
+ SET_SIZE(atomic_inc_8)
+
+ ENTRY(atomic_inc_16)
+ ALTENTRY(atomic_inc_ushort)
+ lock
+ incw (%rdi)
+ ret
+ SET_SIZE(atomic_inc_ushort)
+ SET_SIZE(atomic_inc_16)
+
+ ENTRY(atomic_inc_32)
+ ALTENTRY(atomic_inc_uint)
+ lock
+ incl (%rdi)
+ ret
+ SET_SIZE(atomic_inc_uint)
+ SET_SIZE(atomic_inc_32)
+
+ ENTRY(atomic_inc_64)
+ ALTENTRY(atomic_inc_ulong)
+ lock
+ incq (%rdi)
+ ret
+ SET_SIZE(atomic_inc_ulong)
+ SET_SIZE(atomic_inc_64)
+
+ ENTRY(atomic_inc_8_nv)
+ ALTENTRY(atomic_inc_uchar_nv)
+ movb (%rdi), %al
+1:
+ leaq 1(%rax), %rcx
+ lock
+ cmpxchgb %cl, (%rdi)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_inc_uchar_nv)
+ SET_SIZE(atomic_inc_8_nv)
+
+ ENTRY(atomic_inc_16_nv)
+ ALTENTRY(atomic_inc_ushort_nv)
+ movw (%rdi), %ax
+1:
+ leaq 1(%rax), %rcx
+ lock
+ cmpxchgw %cx, (%rdi)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_inc_ushort_nv)
+ SET_SIZE(atomic_inc_16_nv)
+
+ ENTRY(atomic_inc_32_nv)
+ ALTENTRY(atomic_inc_uint_nv)
+ movl (%rdi), %eax
+1:
+ leaq 1(%rax), %rcx
+ lock
+ cmpxchgl %ecx, (%rdi)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_inc_uint_nv)
+ SET_SIZE(atomic_inc_32_nv)
+
+ ENTRY(atomic_inc_64_nv)
+ ALTENTRY(atomic_inc_ulong_nv)
+ movq (%rdi), %rax
+1:
+ leaq 1(%rax), %rcx
+ lock
+ cmpxchgq %rcx, (%rdi)
+ jne 1b
+ movq %rcx, %rax
+ ret
+ SET_SIZE(atomic_inc_ulong_nv)
+ SET_SIZE(atomic_inc_64_nv)
+
+ ENTRY(atomic_dec_8)
+ ALTENTRY(atomic_dec_uchar)
+ lock
+ decb (%rdi)
+ ret
+ SET_SIZE(atomic_dec_uchar)
+ SET_SIZE(atomic_dec_8)
+
+ ENTRY(atomic_dec_16)
+ ALTENTRY(atomic_dec_ushort)
+ lock
+ decw (%rdi)
+ ret
+ SET_SIZE(atomic_dec_ushort)
+ SET_SIZE(atomic_dec_16)
+
+ ENTRY(atomic_dec_32)
+ ALTENTRY(atomic_dec_uint)
+ lock
+ decl (%rdi)
+ ret
+ SET_SIZE(atomic_dec_uint)
+ SET_SIZE(atomic_dec_32)
+
+ ENTRY(atomic_dec_64)
+ ALTENTRY(atomic_dec_ulong)
+ lock
+ decq (%rdi)
+ ret
+ SET_SIZE(atomic_dec_ulong)
+ SET_SIZE(atomic_dec_64)
+
+ ENTRY(atomic_dec_8_nv)
+ ALTENTRY(atomic_dec_uchar_nv)
+ movb (%rdi), %al
+1:
+ leaq -1(%rax), %rcx
+ lock
+ cmpxchgb %cl, (%rdi)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_dec_uchar_nv)
+ SET_SIZE(atomic_dec_8_nv)
+
+ ENTRY(atomic_dec_16_nv)
+ ALTENTRY(atomic_dec_ushort_nv)
+ movw (%rdi), %ax
+1:
+ leaq -1(%rax), %rcx
+ lock
+ cmpxchgw %cx, (%rdi)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_dec_ushort_nv)
+ SET_SIZE(atomic_dec_16_nv)
+
+ ENTRY(atomic_dec_32_nv)
+ ALTENTRY(atomic_dec_uint_nv)
+ movl (%rdi), %eax
+1:
+ leaq -1(%rax), %rcx
+ lock
+ cmpxchgl %ecx, (%rdi)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_dec_uint_nv)
+ SET_SIZE(atomic_dec_32_nv)
+
+ ENTRY(atomic_dec_64_nv)
+ ALTENTRY(atomic_dec_ulong_nv)
+ movq (%rdi), %rax
+1:
+ leaq -1(%rax), %rcx
+ lock
+ cmpxchgq %rcx, (%rdi)
+ jne 1b
+ movq %rcx, %rax
+ ret
+ SET_SIZE(atomic_dec_ulong_nv)
+ SET_SIZE(atomic_dec_64_nv)
+
+ ENTRY(atomic_add_8)
+ ALTENTRY(atomic_add_char)
+ lock
+ addb %sil, (%rdi)
+ ret
+ SET_SIZE(atomic_add_char)
+ SET_SIZE(atomic_add_8)
+
+ ENTRY(atomic_add_16)
+ ALTENTRY(atomic_add_short)
+ lock
+ addw %si, (%rdi)
+ ret
+ SET_SIZE(atomic_add_short)
+ SET_SIZE(atomic_add_16)
+
+ ENTRY(atomic_add_32)
+ ALTENTRY(atomic_add_int)
+ lock
+ addl %esi, (%rdi)
+ ret
+ SET_SIZE(atomic_add_int)
+ SET_SIZE(atomic_add_32)
+
+ ENTRY(atomic_add_64)
+ ALTENTRY(atomic_add_ptr)
+ ALTENTRY(atomic_add_long)
+ lock
+ addq %rsi, (%rdi)
+ ret
+ SET_SIZE(atomic_add_long)
+ SET_SIZE(atomic_add_ptr)
+ SET_SIZE(atomic_add_64)
+
+ ENTRY(atomic_sub_8)
+ ALTENTRY(atomic_sub_char)
+ lock
+ subb %sil, (%rdi)
+ ret
+ SET_SIZE(atomic_sub_char)
+ SET_SIZE(atomic_sub_8)
+
+ ENTRY(atomic_sub_16)
+ ALTENTRY(atomic_sub_short)
+ lock
+ subw %si, (%rdi)
+ ret
+ SET_SIZE(atomic_sub_short)
+ SET_SIZE(atomic_sub_16)
+
+ ENTRY(atomic_sub_32)
+ ALTENTRY(atomic_sub_int)
+ lock
+ subl %esi, (%rdi)
+ ret
+ SET_SIZE(atomic_sub_int)
+ SET_SIZE(atomic_sub_32)
+
+ ENTRY(atomic_sub_64)
+ ALTENTRY(atomic_sub_ptr)
+ ALTENTRY(atomic_sub_long)
+ lock
+ subq %rsi, (%rdi)
+ ret
+ SET_SIZE(atomic_sub_long)
+ SET_SIZE(atomic_sub_ptr)
+ SET_SIZE(atomic_sub_64)
+
+ ENTRY(atomic_or_8)
+ ALTENTRY(atomic_or_uchar)
+ lock
+ orb %sil, (%rdi)
+ ret
+ SET_SIZE(atomic_or_uchar)
+ SET_SIZE(atomic_or_8)
+
+ ENTRY(atomic_or_16)
+ ALTENTRY(atomic_or_ushort)
+ lock
+ orw %si, (%rdi)
+ ret
+ SET_SIZE(atomic_or_ushort)
+ SET_SIZE(atomic_or_16)
+
+ ENTRY(atomic_or_32)
+ ALTENTRY(atomic_or_uint)
+ lock
+ orl %esi, (%rdi)
+ ret
+ SET_SIZE(atomic_or_uint)
+ SET_SIZE(atomic_or_32)
+
+ ENTRY(atomic_or_64)
+ ALTENTRY(atomic_or_ulong)
+ lock
+ orq %rsi, (%rdi)
+ ret
+ SET_SIZE(atomic_or_ulong)
+ SET_SIZE(atomic_or_64)
+
+ ENTRY(atomic_and_8)
+ ALTENTRY(atomic_and_uchar)
+ lock
+ andb %sil, (%rdi)
+ ret
+ SET_SIZE(atomic_and_uchar)
+ SET_SIZE(atomic_and_8)
+
+ ENTRY(atomic_and_16)
+ ALTENTRY(atomic_and_ushort)
+ lock
+ andw %si, (%rdi)
+ ret
+ SET_SIZE(atomic_and_ushort)
+ SET_SIZE(atomic_and_16)
+
+ ENTRY(atomic_and_32)
+ ALTENTRY(atomic_and_uint)
+ lock
+ andl %esi, (%rdi)
+ ret
+ SET_SIZE(atomic_and_uint)
+ SET_SIZE(atomic_and_32)
+
+ ENTRY(atomic_and_64)
+ ALTENTRY(atomic_and_ulong)
+ lock
+ andq %rsi, (%rdi)
+ ret
+ SET_SIZE(atomic_and_ulong)
+ SET_SIZE(atomic_and_64)
+
+ ENTRY(atomic_add_8_nv)
+ ALTENTRY(atomic_add_char_nv)
+ movb (%rdi), %al
+1:
+ movb %sil, %cl
+ addb %al, %cl
+ lock
+ cmpxchgb %cl, (%rdi)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_add_char_nv)
+ SET_SIZE(atomic_add_8_nv)
+
+ ENTRY(atomic_add_16_nv)
+ ALTENTRY(atomic_add_short_nv)
+ movw (%rdi), %ax
+1:
+ movw %si, %cx
+ addw %ax, %cx
+ lock
+ cmpxchgw %cx, (%rdi)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_add_short_nv)
+ SET_SIZE(atomic_add_16_nv)
+
+ ENTRY(atomic_add_32_nv)
+ ALTENTRY(atomic_add_int_nv)
+ movl (%rdi), %eax
+1:
+ movl %esi, %ecx
+ addl %eax, %ecx
+ lock
+ cmpxchgl %ecx, (%rdi)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_add_int_nv)
+ SET_SIZE(atomic_add_32_nv)
+
+ ENTRY(atomic_add_64_nv)
+ ALTENTRY(atomic_add_ptr_nv)
+ ALTENTRY(atomic_add_long_nv)
+ movq (%rdi), %rax
+1:
+ movq %rsi, %rcx
+ addq %rax, %rcx
+ lock
+ cmpxchgq %rcx, (%rdi)
+ jne 1b
+ movq %rcx, %rax
+ ret
+ SET_SIZE(atomic_add_long_nv)
+ SET_SIZE(atomic_add_ptr_nv)
+ SET_SIZE(atomic_add_64_nv)
+
+ ENTRY(atomic_sub_8_nv)
+ ALTENTRY(atomic_sub_char_nv)
+ movb (%rdi), %al
+1:
+ movb %sil, %cl
+ subb %al, %cl
+ lock
+ cmpxchgb %cl, (%rdi)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_sub_char_nv)
+ SET_SIZE(atomic_sub_8_nv)
+
+ ENTRY(atomic_sub_16_nv)
+ ALTENTRY(atomic_sub_short_nv)
+ movw (%rdi), %ax
+1:
+ movw %si, %cx
+ subw %ax, %cx
+ lock
+ cmpxchgw %cx, (%rdi)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_sub_short_nv)
+ SET_SIZE(atomic_sub_16_nv)
+
+ ENTRY(atomic_sub_32_nv)
+ ALTENTRY(atomic_sub_int_nv)
+ movl (%rdi), %eax
+1:
+ movl %esi, %ecx
+ subl %eax, %ecx
+ lock
+ cmpxchgl %ecx, (%rdi)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_sub_int_nv)
+ SET_SIZE(atomic_sub_32_nv)
+
+ ENTRY(atomic_sub_64_nv)
+ ALTENTRY(atomic_sub_ptr_nv)
+ ALTENTRY(atomic_sub_long_nv)
+ movq (%rdi), %rax
+1:
+ movq %rsi, %rcx
+ subq %rax, %rcx
+ lock
+ cmpxchgq %rcx, (%rdi)
+ jne 1b
+ movq %rcx, %rax
+ ret
+ SET_SIZE(atomic_sub_long_nv)
+ SET_SIZE(atomic_sub_ptr_nv)
+ SET_SIZE(atomic_sub_64_nv)
+
+ ENTRY(atomic_and_8_nv)
+ ALTENTRY(atomic_and_uchar_nv)
+ movb (%rdi), %al
+1:
+ movb %sil, %cl
+ andb %al, %cl
+ lock
+ cmpxchgb %cl, (%rdi)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_and_uchar_nv)
+ SET_SIZE(atomic_and_8_nv)
+
+ ENTRY(atomic_and_16_nv)
+ ALTENTRY(atomic_and_ushort_nv)
+ movw (%rdi), %ax
+1:
+ movw %si, %cx
+ andw %ax, %cx
+ lock
+ cmpxchgw %cx, (%rdi)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_and_ushort_nv)
+ SET_SIZE(atomic_and_16_nv)
+
+ ENTRY(atomic_and_32_nv)
+ ALTENTRY(atomic_and_uint_nv)
+ movl (%rdi), %eax
+1:
+ movl %esi, %ecx
+ andl %eax, %ecx
+ lock
+ cmpxchgl %ecx, (%rdi)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_and_uint_nv)
+ SET_SIZE(atomic_and_32_nv)
+
+ ENTRY(atomic_and_64_nv)
+ ALTENTRY(atomic_and_ulong_nv)
+ movq (%rdi), %rax
+1:
+ movq %rsi, %rcx
+ andq %rax, %rcx
+ lock
+ cmpxchgq %rcx, (%rdi)
+ jne 1b
+ movq %rcx, %rax
+ ret
+ SET_SIZE(atomic_and_ulong_nv)
+ SET_SIZE(atomic_and_64_nv)
+
+ ENTRY(atomic_or_8_nv)
+ ALTENTRY(atomic_or_uchar_nv)
+ movb (%rdi), %al
+1:
+ movb %sil, %cl
+ orb %al, %cl
+ lock
+ cmpxchgb %cl, (%rdi)
+ jne 1b
+ movzbl %cl, %eax
+ ret
+ SET_SIZE(atomic_and_uchar_nv)
+ SET_SIZE(atomic_and_8_nv)
+
+ ENTRY(atomic_or_16_nv)
+ ALTENTRY(atomic_or_ushort_nv)
+ movw (%rdi), %ax
+1:
+ movw %si, %cx
+ orw %ax, %cx
+ lock
+ cmpxchgw %cx, (%rdi)
+ jne 1b
+ movzwl %cx, %eax
+ ret
+ SET_SIZE(atomic_or_ushort_nv)
+ SET_SIZE(atomic_or_16_nv)
+
+ ENTRY(atomic_or_32_nv)
+ ALTENTRY(atomic_or_uint_nv)
+ movl (%rdi), %eax
+1:
+ movl %esi, %ecx
+ orl %eax, %ecx
+ lock
+ cmpxchgl %ecx, (%rdi)
+ jne 1b
+ movl %ecx, %eax
+ ret
+ SET_SIZE(atomic_or_uint_nv)
+ SET_SIZE(atomic_or_32_nv)
+
+ ENTRY(atomic_or_64_nv)
+ ALTENTRY(atomic_or_ulong_nv)
+ movq (%rdi), %rax
+1:
+ movq %rsi, %rcx
+ orq %rax, %rcx
+ lock
+ cmpxchgq %rcx, (%rdi)
+ jne 1b
+ movq %rcx, %rax
+ ret
+ SET_SIZE(atomic_or_ulong_nv)
+ SET_SIZE(atomic_or_64_nv)
+
+ ENTRY(atomic_cas_8)
+ ALTENTRY(atomic_cas_uchar)
+ movzbl %sil, %eax
+ lock
+ cmpxchgb %dl, (%rdi)
+ ret
+ SET_SIZE(atomic_cas_uchar)
+ SET_SIZE(atomic_cas_8)
+
+ ENTRY(atomic_cas_16)
+ ALTENTRY(atomic_cas_ushort)
+ movzwl %si, %eax
+ lock
+ cmpxchgw %dx, (%rdi)
+ ret
+ SET_SIZE(atomic_cas_ushort)
+ SET_SIZE(atomic_cas_16)
+
+ ENTRY(atomic_cas_32)
+ ALTENTRY(atomic_cas_uint)
+ movl %esi, %eax
+ lock
+ cmpxchgl %edx, (%rdi)
+ ret
+ SET_SIZE(atomic_cas_uint)
+ SET_SIZE(atomic_cas_32)
+
+ ENTRY(atomic_cas_64)
+ ALTENTRY(atomic_cas_ulong)
+ ALTENTRY(atomic_cas_ptr)
+ movq %rsi, %rax
+ lock
+ cmpxchgq %rdx, (%rdi)
+ ret
+ SET_SIZE(atomic_cas_ptr)
+ SET_SIZE(atomic_cas_ulong)
+ SET_SIZE(atomic_cas_64)
+
+ ENTRY(atomic_swap_8)
+ ALTENTRY(atomic_swap_uchar)
+ movzbl %sil, %eax
+ lock
+ xchgb %al, (%rdi)
+ ret
+ SET_SIZE(atomic_swap_uchar)
+ SET_SIZE(atomic_swap_8)
+
+ ENTRY(atomic_swap_16)
+ ALTENTRY(atomic_swap_ushort)
+ movzwl %si, %eax
+ lock
+ xchgw %ax, (%rdi)
+ ret
+ SET_SIZE(atomic_swap_ushort)
+ SET_SIZE(atomic_swap_16)
+
+ ENTRY(atomic_swap_32)
+ ALTENTRY(atomic_swap_uint)
+ movl %esi, %eax
+ lock
+ xchgl %eax, (%rdi)
+ ret
+ SET_SIZE(atomic_swap_uint)
+ SET_SIZE(atomic_swap_32)
+
+ ENTRY(atomic_swap_64)
+ ALTENTRY(atomic_swap_ulong)
+ ALTENTRY(atomic_swap_ptr)
+ movq %rsi, %rax
+ lock
+ xchgq %rax, (%rdi)
+ ret
+ SET_SIZE(atomic_swap_ptr)
+ SET_SIZE(atomic_swap_ulong)
+ SET_SIZE(atomic_swap_64)
+
+ ENTRY(atomic_set_long_excl)
+ xorl %eax, %eax
+ lock
+ btsq %rsi, (%rdi)
+ jnc 1f
+ decl %eax
+1:
+ ret
+ SET_SIZE(atomic_set_long_excl)
+
+ ENTRY(atomic_clear_long_excl)
+ xorl %eax, %eax
+ lock
+ btrq %rsi, (%rdi)
+ jc 1f
+ decl %eax
+1:
+ ret
+ SET_SIZE(atomic_clear_long_excl)
+
+ /*
+ * NOTE: membar_enter, and membar_exit are identical routines.
+ * We define them separately, instead of using an ALTENTRY
+ * definitions to alias them together, so that DTrace and
+ * debuggers will see a unique address for them, allowing
+ * more accurate tracing.
+ */
+
+ ENTRY(membar_enter)
+ mfence
+ ret
+ SET_SIZE(membar_enter)
+
+ ENTRY(membar_exit)
+ mfence
+ ret
+ SET_SIZE(membar_exit)
+
+ ENTRY(membar_producer)
+ sfence
+ ret
+ SET_SIZE(membar_producer)
+
+ ENTRY(membar_consumer)
+ lfence
+ ret
+ SET_SIZE(membar_consumer)
+
+#ifdef __ELF__
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/assert.c b/sys/contrib/openzfs/lib/libspl/assert.c
new file mode 100644
index 000000000000..94290ae13e09
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/assert.c
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <assert.h>
+
+int aok = 0;
+
+/* printf version of libspl_assert */
+void
+libspl_assertf(const char *file, const char *func, int line,
+ const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "ASSERT at %s:%d:%s()", file, line, func);
+ va_end(args);
+ if (aok) {
+ return;
+ }
+ abort();
+}
diff --git a/sys/contrib/openzfs/lib/libspl/include/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/Makefile.am
new file mode 100644
index 000000000000..9ca08b2bc0f7
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/Makefile.am
@@ -0,0 +1,22 @@
+SUBDIRS = ia32 rpc sys util os
+
+libspldir = $(includedir)/libspl
+libspl_HEADERS = \
+ assert.h \
+ atomic.h \
+ libdevinfo.h \
+ libgen.h \
+ libshare.h \
+ limits.h \
+ locale.h \
+ statcommon.h \
+ stdio.h \
+ stdlib.h \
+ string.h \
+ stropts.h \
+ thread.h \
+ tzfile.h \
+ ucred.h \
+ umem.h \
+ unistd.h \
+ zone.h
diff --git a/sys/contrib/openzfs/lib/libspl/include/assert.h b/sys/contrib/openzfs/lib/libspl/include/assert.h
new file mode 100644
index 000000000000..0503ce492181
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/assert.h
@@ -0,0 +1,151 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include_next <assert.h>
+
+#ifndef _LIBSPL_ASSERT_H
+#define _LIBSPL_ASSERT_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+/* Set to non-zero to avoid abort()ing on an assertion failure */
+extern int aok;
+
+/* printf version of libspl_assert */
+extern void libspl_assertf(const char *file, const char *func, int line,
+ const char *format, ...);
+
+static inline int
+libspl_assert(const char *buf, const char *file, const char *func, int line)
+{
+ libspl_assertf(file, func, line, "%s", buf);
+ return (0);
+}
+
+#ifdef verify
+#undef verify
+#endif
+
+#define VERIFY(cond) \
+ (void) ((!(cond)) && \
+ libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
+#define verify(cond) \
+ (void) ((!(cond)) && \
+ libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
+
+#define VERIFY3B(LEFT, OP, RIGHT) \
+do { \
+ const boolean_t __left = (boolean_t)(LEFT); \
+ const boolean_t __right = (boolean_t)(RIGHT); \
+ if (!(__left OP __right)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "%s %s %s (0x%llx %s 0x%llx)", #LEFT, #OP, #RIGHT, \
+ (u_longlong_t)__left, #OP, (u_longlong_t)__right); \
+} while (0)
+
+#define VERIFY3S(LEFT, OP, RIGHT) \
+do { \
+ const int64_t __left = (int64_t)(LEFT); \
+ const int64_t __right = (int64_t)(RIGHT); \
+ if (!(__left OP __right)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "%s %s %s (0x%llx %s 0x%llx)", #LEFT, #OP, #RIGHT, \
+ (u_longlong_t)__left, #OP, (u_longlong_t)__right); \
+} while (0)
+
+#define VERIFY3U(LEFT, OP, RIGHT) \
+do { \
+ const uint64_t __left = (uint64_t)(LEFT); \
+ const uint64_t __right = (uint64_t)(RIGHT); \
+ if (!(__left OP __right)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "%s %s %s (0x%llx %s 0x%llx)", #LEFT, #OP, #RIGHT, \
+ (u_longlong_t)__left, #OP, (u_longlong_t)__right); \
+} while (0)
+
+#define VERIFY3P(LEFT, OP, RIGHT) \
+do { \
+ const uintptr_t __left = (uintptr_t)(LEFT); \
+ const uintptr_t __right = (uintptr_t)(RIGHT); \
+ if (!(__left OP __right)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "%s %s %s (0x%llx %s 0x%llx)", #LEFT, #OP, #RIGHT, \
+ (u_longlong_t)__left, #OP, (u_longlong_t)__right); \
+} while (0)
+
+#define VERIFY0(LEFT) \
+do { \
+ const uint64_t __left = (uint64_t)(LEFT); \
+ if (!(__left == 0)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "%s == 0 (0x%llx == 0)", #LEFT, \
+ (u_longlong_t)__left); \
+} while (0)
+
+#ifdef assert
+#undef assert
+#endif
+
+/* Compile time assert */
+#define CTASSERT_GLOBAL(x) _CTASSERT(x, __LINE__)
+#define CTASSERT(x) { _CTASSERT(x, __LINE__); }
+#define _CTASSERT(x, y) __CTASSERT(x, y)
+#define __CTASSERT(x, y) \
+ typedef char __attribute__((unused)) \
+ __compile_time_assertion__ ## y[(x) ? 1 : -1]
+
+#ifdef NDEBUG
+#define ASSERT3B(x, y, z) ((void)0)
+#define ASSERT3S(x, y, z) ((void)0)
+#define ASSERT3U(x, y, z) ((void)0)
+#define ASSERT3P(x, y, z) ((void)0)
+#define ASSERT0(x) ((void)0)
+#define ASSERT(x) ((void)0)
+#define assert(x) ((void)0)
+#define IMPLY(A, B) ((void)0)
+#define EQUIV(A, B) ((void)0)
+#else
+#define ASSERT3B VERIFY3B
+#define ASSERT3S VERIFY3S
+#define ASSERT3U VERIFY3U
+#define ASSERT3P VERIFY3P
+#define ASSERT0 VERIFY0
+#define ASSERT VERIFY
+#define assert VERIFY
+#define IMPLY(A, B) \
+ ((void)(((!(A)) || (B)) || \
+ libspl_assert("(" #A ") implies (" #B ")", \
+ __FILE__, __FUNCTION__, __LINE__)))
+#define EQUIV(A, B) \
+ ((void)((!!(A) == !!(B)) || \
+ libspl_assert("(" #A ") is equivalent to (" #B ")", \
+ __FILE__, __FUNCTION__, __LINE__)))
+
+#endif /* NDEBUG */
+
+#endif /* _LIBSPL_ASSERT_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/atomic.h b/sys/contrib/openzfs/lib/libspl/include/atomic.h
new file mode 100644
index 000000000000..f8c257f9696b
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/atomic.h
@@ -0,0 +1,296 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_ATOMIC_H
+#define _SYS_ATOMIC_H
+
+#include <sys/types.h>
+#include <sys/inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__STDC__)
+/*
+ * Increment target.
+ */
+extern void atomic_inc_8(volatile uint8_t *);
+extern void atomic_inc_uchar(volatile uchar_t *);
+extern void atomic_inc_16(volatile uint16_t *);
+extern void atomic_inc_ushort(volatile ushort_t *);
+extern void atomic_inc_32(volatile uint32_t *);
+extern void atomic_inc_uint(volatile uint_t *);
+extern void atomic_inc_ulong(volatile ulong_t *);
+#if defined(_INT64_TYPE)
+extern void atomic_inc_64(volatile uint64_t *);
+#endif
+
+/*
+ * Decrement target
+ */
+extern void atomic_dec_8(volatile uint8_t *);
+extern void atomic_dec_uchar(volatile uchar_t *);
+extern void atomic_dec_16(volatile uint16_t *);
+extern void atomic_dec_ushort(volatile ushort_t *);
+extern void atomic_dec_32(volatile uint32_t *);
+extern void atomic_dec_uint(volatile uint_t *);
+extern void atomic_dec_ulong(volatile ulong_t *);
+#if defined(_INT64_TYPE)
+extern void atomic_dec_64(volatile uint64_t *);
+#endif
+
+/*
+ * Add delta to target
+ */
+extern void atomic_add_8(volatile uint8_t *, int8_t);
+extern void atomic_add_char(volatile uchar_t *, signed char);
+extern void atomic_add_16(volatile uint16_t *, int16_t);
+extern void atomic_add_short(volatile ushort_t *, short);
+extern void atomic_add_32(volatile uint32_t *, int32_t);
+extern void atomic_add_int(volatile uint_t *, int);
+extern void atomic_add_ptr(volatile void *, ssize_t);
+extern void atomic_add_long(volatile ulong_t *, long);
+#if defined(_INT64_TYPE)
+extern void atomic_add_64(volatile uint64_t *, int64_t);
+#endif
+
+/*
+ * Subtract delta from target
+ */
+extern void atomic_sub_8(volatile uint8_t *, int8_t);
+extern void atomic_sub_char(volatile uchar_t *, signed char);
+extern void atomic_sub_16(volatile uint16_t *, int16_t);
+extern void atomic_sub_short(volatile ushort_t *, short);
+extern void atomic_sub_32(volatile uint32_t *, int32_t);
+extern void atomic_sub_int(volatile uint_t *, int);
+extern void atomic_sub_ptr(volatile void *, ssize_t);
+extern void atomic_sub_long(volatile ulong_t *, long);
+#if defined(_INT64_TYPE)
+extern void atomic_sub_64(volatile uint64_t *, int64_t);
+#endif
+
+/*
+ * logical OR bits with target
+ */
+extern void atomic_or_8(volatile uint8_t *, uint8_t);
+extern void atomic_or_uchar(volatile uchar_t *, uchar_t);
+extern void atomic_or_16(volatile uint16_t *, uint16_t);
+extern void atomic_or_ushort(volatile ushort_t *, ushort_t);
+extern void atomic_or_32(volatile uint32_t *, uint32_t);
+extern void atomic_or_uint(volatile uint_t *, uint_t);
+extern void atomic_or_ulong(volatile ulong_t *, ulong_t);
+#if defined(_INT64_TYPE)
+extern void atomic_or_64(volatile uint64_t *, uint64_t);
+#endif
+
+/*
+ * logical AND bits with target
+ */
+extern void atomic_and_8(volatile uint8_t *, uint8_t);
+extern void atomic_and_uchar(volatile uchar_t *, uchar_t);
+extern void atomic_and_16(volatile uint16_t *, uint16_t);
+extern void atomic_and_ushort(volatile ushort_t *, ushort_t);
+extern void atomic_and_32(volatile uint32_t *, uint32_t);
+extern void atomic_and_uint(volatile uint_t *, uint_t);
+extern void atomic_and_ulong(volatile ulong_t *, ulong_t);
+#if defined(_INT64_TYPE)
+extern void atomic_and_64(volatile uint64_t *, uint64_t);
+#endif
+
+/*
+ * As above, but return the new value. Note that these _nv() variants are
+ * substantially more expensive on some platforms than the no-return-value
+ * versions above, so don't use them unless you really need to know the
+ * new value *atomically* (e.g. when decrementing a reference count and
+ * checking whether it went to zero).
+ */
+
+/*
+ * Increment target and return new value.
+ */
+extern uint8_t atomic_inc_8_nv(volatile uint8_t *);
+extern uchar_t atomic_inc_uchar_nv(volatile uchar_t *);
+extern uint16_t atomic_inc_16_nv(volatile uint16_t *);
+extern ushort_t atomic_inc_ushort_nv(volatile ushort_t *);
+extern uint32_t atomic_inc_32_nv(volatile uint32_t *);
+extern uint_t atomic_inc_uint_nv(volatile uint_t *);
+extern ulong_t atomic_inc_ulong_nv(volatile ulong_t *);
+#if defined(_INT64_TYPE)
+extern uint64_t atomic_inc_64_nv(volatile uint64_t *);
+#endif
+
+/*
+ * Decrement target and return new value.
+ */
+extern uint8_t atomic_dec_8_nv(volatile uint8_t *);
+extern uchar_t atomic_dec_uchar_nv(volatile uchar_t *);
+extern uint16_t atomic_dec_16_nv(volatile uint16_t *);
+extern ushort_t atomic_dec_ushort_nv(volatile ushort_t *);
+extern uint32_t atomic_dec_32_nv(volatile uint32_t *);
+extern uint_t atomic_dec_uint_nv(volatile uint_t *);
+extern ulong_t atomic_dec_ulong_nv(volatile ulong_t *);
+#if defined(_INT64_TYPE)
+extern uint64_t atomic_dec_64_nv(volatile uint64_t *);
+#endif
+
+/*
+ * Add delta to target
+ */
+extern uint8_t atomic_add_8_nv(volatile uint8_t *, int8_t);
+extern uchar_t atomic_add_char_nv(volatile uchar_t *, signed char);
+extern uint16_t atomic_add_16_nv(volatile uint16_t *, int16_t);
+extern ushort_t atomic_add_short_nv(volatile ushort_t *, short);
+extern uint32_t atomic_add_32_nv(volatile uint32_t *, int32_t);
+extern uint_t atomic_add_int_nv(volatile uint_t *, int);
+extern void *atomic_add_ptr_nv(volatile void *, ssize_t);
+extern ulong_t atomic_add_long_nv(volatile ulong_t *, long);
+#if defined(_INT64_TYPE)
+extern uint64_t atomic_add_64_nv(volatile uint64_t *, int64_t);
+#endif
+
+/*
+ * Subtract delta from target
+ */
+extern uint8_t atomic_sub_8_nv(volatile uint8_t *, int8_t);
+extern uchar_t atomic_sub_char_nv(volatile uchar_t *, signed char);
+extern uint16_t atomic_sub_16_nv(volatile uint16_t *, int16_t);
+extern ushort_t atomic_sub_short_nv(volatile ushort_t *, short);
+extern uint32_t atomic_sub_32_nv(volatile uint32_t *, int32_t);
+extern uint_t atomic_sub_int_nv(volatile uint_t *, int);
+extern void *atomic_sub_ptr_nv(volatile void *, ssize_t);
+extern ulong_t atomic_sub_long_nv(volatile ulong_t *, long);
+#if defined(_INT64_TYPE)
+extern uint64_t atomic_sub_64_nv(volatile uint64_t *, int64_t);
+#endif
+
+/*
+ * logical OR bits with target and return new value.
+ */
+extern uint8_t atomic_or_8_nv(volatile uint8_t *, uint8_t);
+extern uchar_t atomic_or_uchar_nv(volatile uchar_t *, uchar_t);
+extern uint16_t atomic_or_16_nv(volatile uint16_t *, uint16_t);
+extern ushort_t atomic_or_ushort_nv(volatile ushort_t *, ushort_t);
+extern uint32_t atomic_or_32_nv(volatile uint32_t *, uint32_t);
+extern uint_t atomic_or_uint_nv(volatile uint_t *, uint_t);
+extern ulong_t atomic_or_ulong_nv(volatile ulong_t *, ulong_t);
+#if defined(_INT64_TYPE)
+extern uint64_t atomic_or_64_nv(volatile uint64_t *, uint64_t);
+#endif
+
+/*
+ * logical AND bits with target and return new value.
+ */
+extern uint8_t atomic_and_8_nv(volatile uint8_t *, uint8_t);
+extern uchar_t atomic_and_uchar_nv(volatile uchar_t *, uchar_t);
+extern uint16_t atomic_and_16_nv(volatile uint16_t *, uint16_t);
+extern ushort_t atomic_and_ushort_nv(volatile ushort_t *, ushort_t);
+extern uint32_t atomic_and_32_nv(volatile uint32_t *, uint32_t);
+extern uint_t atomic_and_uint_nv(volatile uint_t *, uint_t);
+extern ulong_t atomic_and_ulong_nv(volatile ulong_t *, ulong_t);
+#if defined(_INT64_TYPE)
+extern uint64_t atomic_and_64_nv(volatile uint64_t *, uint64_t);
+#endif
+
+/*
+ * If *arg1 == arg2, set *arg1 = arg3; return old value
+ */
+extern uint8_t atomic_cas_8(volatile uint8_t *, uint8_t, uint8_t);
+extern uchar_t atomic_cas_uchar(volatile uchar_t *, uchar_t, uchar_t);
+extern uint16_t atomic_cas_16(volatile uint16_t *, uint16_t, uint16_t);
+extern ushort_t atomic_cas_ushort(volatile ushort_t *, ushort_t, ushort_t);
+extern uint32_t atomic_cas_32(volatile uint32_t *, uint32_t, uint32_t);
+extern uint_t atomic_cas_uint(volatile uint_t *, uint_t, uint_t);
+extern void *atomic_cas_ptr(volatile void *, void *, void *);
+extern ulong_t atomic_cas_ulong(volatile ulong_t *, ulong_t, ulong_t);
+#if defined(_INT64_TYPE)
+extern uint64_t atomic_cas_64(volatile uint64_t *, uint64_t, uint64_t);
+#endif
+
+/*
+ * Swap target and return old value
+ */
+extern uint8_t atomic_swap_8(volatile uint8_t *, uint8_t);
+extern uchar_t atomic_swap_uchar(volatile uchar_t *, uchar_t);
+extern uint16_t atomic_swap_16(volatile uint16_t *, uint16_t);
+extern ushort_t atomic_swap_ushort(volatile ushort_t *, ushort_t);
+extern uint32_t atomic_swap_32(volatile uint32_t *, uint32_t);
+extern uint_t atomic_swap_uint(volatile uint_t *, uint_t);
+extern void *atomic_swap_ptr(volatile void *, void *);
+extern ulong_t atomic_swap_ulong(volatile ulong_t *, ulong_t);
+#if defined(_INT64_TYPE)
+extern uint64_t atomic_swap_64(volatile uint64_t *, uint64_t);
+#endif
+
+/*
+ * Perform an exclusive atomic bit set/clear on a target.
+ * Returns 0 if bit was successfully set/cleared, or -1
+ * if the bit was already set/cleared.
+ */
+extern int atomic_set_long_excl(volatile ulong_t *, uint_t);
+extern int atomic_clear_long_excl(volatile ulong_t *, uint_t);
+
+/*
+ * Generic memory barrier used during lock entry, placed after the
+ * memory operation that acquires the lock to guarantee that the lock
+ * protects its data. No stores from after the memory barrier will
+ * reach visibility, and no loads from after the barrier will be
+ * resolved, before the lock acquisition reaches global visibility.
+ */
+extern void membar_enter(void);
+
+/*
+ * Generic memory barrier used during lock exit, placed before the
+ * memory operation that releases the lock to guarantee that the lock
+ * protects its data. All loads and stores issued before the barrier
+ * will be resolved before the subsequent lock update reaches visibility.
+ */
+extern void membar_exit(void);
+
+/*
+ * Arrange that all stores issued before this point in the code reach
+ * global visibility before any stores that follow; useful in producer
+ * modules that update a data item, then set a flag that it is available.
+ * The memory barrier guarantees that the available flag is not visible
+ * earlier than the updated data, i.e. it imposes store ordering.
+ */
+extern void membar_producer(void);
+
+/*
+ * Arrange that all loads issued before this point in the code are
+ * completed before any subsequent loads; useful in consumer modules
+ * that check to see if data is available and read the data.
+ * The memory barrier guarantees that the data is not sampled until
+ * after the available flag has been seen, i.e. it imposes load ordering.
+ */
+extern void membar_consumer(void);
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_ATOMIC_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/ia32/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/ia32/Makefile.am
new file mode 100644
index 000000000000..081839c48c8f
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/ia32/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = sys
diff --git a/sys/contrib/openzfs/lib/libspl/include/ia32/sys/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/ia32/sys/Makefile.am
new file mode 100644
index 000000000000..683288460cdf
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/ia32/sys/Makefile.am
@@ -0,0 +1,3 @@
+libspldir = $(includedir)/libspl/ia32/sys
+libspl_HEADERS = \
+ asm_linkage.h
diff --git a/sys/contrib/openzfs/lib/libspl/include/ia32/sys/asm_linkage.h b/sys/contrib/openzfs/lib/libspl/include/ia32/sys/asm_linkage.h
new file mode 100644
index 000000000000..61c4d1a26977
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/ia32/sys/asm_linkage.h
@@ -0,0 +1,302 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _IA32_SYS_ASM_LINKAGE_H
+#define _IA32_SYS_ASM_LINKAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _ASM /* The remainder of this file is only for assembly files */
+
+/*
+ * make annoying differences in assembler syntax go away
+ */
+
+/*
+ * D16 and A16 are used to insert instructions prefixes; the
+ * macros help the assembler code be slightly more portable.
+ */
+#if !defined(__GNUC_AS__)
+/*
+ * /usr/ccs/bin/as prefixes are parsed as separate instructions
+ */
+#define D16 data16;
+#define A16 addr16;
+
+/*
+ * (There are some weird constructs in constant expressions)
+ */
+#define _CONST(const) [const]
+#define _BITNOT(const) -1!_CONST(const)
+#define _MUL(a, b) _CONST(a \* b)
+
+#else
+/*
+ * Why not use the 'data16' and 'addr16' prefixes .. well, the
+ * assembler doesn't quite believe in real mode, and thus argues with
+ * us about what we're trying to do.
+ */
+#define D16 .byte 0x66;
+#define A16 .byte 0x67;
+
+#define _CONST(const) (const)
+#define _BITNOT(const) ~_CONST(const)
+#define _MUL(a, b) _CONST(a * b)
+
+#endif
+
+/*
+ * C pointers are different sizes between i386 and amd64.
+ * These constants can be used to compute offsets into pointer arrays.
+ */
+#if defined(__amd64)
+#define CLONGSHIFT 3
+#define CLONGSIZE 8
+#define CLONGMASK 7
+#elif defined(__i386)
+#define CLONGSHIFT 2
+#define CLONGSIZE 4
+#define CLONGMASK 3
+#endif
+
+/*
+ * Since we know we're either ILP32 or LP64 ..
+ */
+#define CPTRSHIFT CLONGSHIFT
+#define CPTRSIZE CLONGSIZE
+#define CPTRMASK CLONGMASK
+
+#if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT)
+#error "inconsistent shift constants"
+#endif
+
+#if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1)
+#error "inconsistent mask constants"
+#endif
+
+#define ASM_ENTRY_ALIGN 16
+
+/*
+ * SSE register alignment and save areas
+ */
+
+#define XMM_SIZE 16
+#define XMM_ALIGN 16
+
+#if defined(__amd64)
+
+#define SAVE_XMM_PROLOG(sreg, nreg) \
+ subq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp; \
+ movq %rsp, sreg
+
+#define RSTOR_XMM_EPILOG(sreg, nreg) \
+ addq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp
+
+#elif defined(__i386)
+
+#define SAVE_XMM_PROLOG(sreg, nreg) \
+ subl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; \
+ movl %esp, sreg; \
+ addl $XMM_ALIGN, sreg; \
+ andl $_BITNOT(XMM_ALIGN-1), sreg
+
+#define RSTOR_XMM_EPILOG(sreg, nreg) \
+ addl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp;
+
+#endif /* __i386 */
+
+/*
+ * profiling causes definitions of the MCOUNT and RTMCOUNT
+ * particular to the type
+ */
+#ifdef GPROF
+
+#define MCOUNT(x) \
+ pushl %ebp; \
+ movl %esp, %ebp; \
+ call _mcount; \
+ popl %ebp
+
+#endif /* GPROF */
+
+#ifdef PROF
+
+#define MCOUNT(x) \
+/* CSTYLED */ \
+ .lcomm .L_/**/x/**/1, 4, 4; \
+ pushl %ebp; \
+ movl %esp, %ebp; \
+/* CSTYLED */ \
+ movl $.L_/**/x/**/1, %edx; \
+ call _mcount; \
+ popl %ebp
+
+#endif /* PROF */
+
+/*
+ * if we are not profiling, MCOUNT should be defined to nothing
+ */
+#if !defined(PROF) && !defined(GPROF)
+#define MCOUNT(x)
+#endif /* !defined(PROF) && !defined(GPROF) */
+
+#define RTMCOUNT(x) MCOUNT(x)
+
+/*
+ * Macro to define weak symbol aliases. These are similar to the ANSI-C
+ * #pragma weak name = _name
+ * except a compiler can determine type. The assembler must be told. Hence,
+ * the second parameter must be the type of the symbol (i.e.: function,...)
+ */
+#define ANSI_PRAGMA_WEAK(sym, stype) \
+ .weak sym; \
+ .type sym, @stype; \
+/* CSTYLED */ \
+sym = _/**/sym
+
+/*
+ * Like ANSI_PRAGMA_WEAK(), but for unrelated names, as in:
+ * #pragma weak sym1 = sym2
+ */
+#define ANSI_PRAGMA_WEAK2(sym1, sym2, stype) \
+ .weak sym1; \
+ .type sym1, @stype; \
+sym1 = sym2
+
+/*
+ * ENTRY provides the standard procedure entry code and an easy way to
+ * insert the calls to mcount for profiling. ENTRY_NP is identical, but
+ * never calls mcount.
+ */
+#define ENTRY(x) \
+ .text; \
+ .align ASM_ENTRY_ALIGN; \
+ .globl x; \
+ .type x, @function; \
+x: MCOUNT(x)
+
+#define ENTRY_NP(x) \
+ .text; \
+ .align ASM_ENTRY_ALIGN; \
+ .globl x; \
+ .type x, @function; \
+x:
+
+#define RTENTRY(x) \
+ .text; \
+ .align ASM_ENTRY_ALIGN; \
+ .globl x; \
+ .type x, @function; \
+x: RTMCOUNT(x)
+
+/*
+ * ENTRY2 is identical to ENTRY but provides two labels for the entry point.
+ */
+#define ENTRY2(x, y) \
+ .text; \
+ .align ASM_ENTRY_ALIGN; \
+ .globl x, y; \
+ .type x, @function; \
+ .type y, @function; \
+/* CSTYLED */ \
+x: ; \
+y: MCOUNT(x)
+
+#define ENTRY_NP2(x, y) \
+ .text; \
+ .align ASM_ENTRY_ALIGN; \
+ .globl x, y; \
+ .type x, @function; \
+ .type y, @function; \
+/* CSTYLED */ \
+x: ; \
+y:
+
+
+/*
+ * ALTENTRY provides for additional entry points.
+ */
+#define ALTENTRY(x) \
+ .globl x; \
+ .type x, @function; \
+x:
+
+/*
+ * DGDEF and DGDEF2 provide global data declarations.
+ *
+ * DGDEF provides a word aligned word of storage.
+ *
+ * DGDEF2 allocates "sz" bytes of storage with **NO** alignment. This
+ * implies this macro is best used for byte arrays.
+ *
+ * DGDEF3 allocates "sz" bytes of storage with "algn" alignment.
+ */
+#define DGDEF2(name, sz) \
+ .data; \
+ .globl name; \
+ .type name, @object; \
+ .size name, sz; \
+name:
+
+#define DGDEF3(name, sz, algn) \
+ .data; \
+ .align algn; \
+ .globl name; \
+ .type name, @object; \
+ .size name, sz; \
+name:
+
+#define DGDEF(name) DGDEF3(name, 4, 4)
+
+/*
+ * SET_SIZE trails a function and set the size for the ELF symbol table.
+ */
+#define SET_SIZE(x) \
+ .size x, [.-x]
+
+/*
+ * NWORD provides native word value.
+ */
+#if defined(__amd64)
+
+/*CSTYLED*/
+#define NWORD quad
+
+#elif defined(__i386)
+
+#define NWORD long
+
+#endif /* __i386 */
+
+#endif /* _ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IA32_SYS_ASM_LINKAGE_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/libdevinfo.h b/sys/contrib/openzfs/lib/libspl/include/libdevinfo.h
new file mode 100644
index 000000000000..be1d291f4051
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/libdevinfo.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_LIBDEVINFO_H
+#define _LIBSPL_LIBDEVINFO_H
+
+#endif /* _LIBSPL_LIBDEVINFO_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/libgen.h b/sys/contrib/openzfs/lib/libspl/include/libgen.h
new file mode 100644
index 000000000000..c46d7454e49f
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/libgen.h
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_LIBGEN_H
+#define _LIBSPL_LIBGEN_H
+
+#include <sys/types.h>
+#include_next <libgen.h>
+
+extern int mkdirp(const char *, mode_t);
+
+#endif /* _LIBSPL_LIBGEN_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/libshare.h b/sys/contrib/openzfs/lib/libspl/include/libshare.h
new file mode 100644
index 000000000000..ea53f8c15089
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/libshare.h
@@ -0,0 +1,86 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ * Copyright (c) 2019, 2020 by Delphix. All rights reserved.
+ */
+#ifndef _LIBSPL_LIBSHARE_H
+#define _LIBSPL_LIBSHARE_H
+
+/* API Initialization */
+#define SA_INIT_SHARE_API 0x0001 /* init share specific interface */
+#define SA_INIT_CONTROL_API 0x0002 /* init control specific interface */
+
+/*
+ * defined error values
+ */
+
+#define SA_OK 0
+#define SA_NO_SUCH_PATH 1 /* provided path doesn't exist */
+#define SA_NO_MEMORY 2 /* no memory for data structures */
+#define SA_DUPLICATE_NAME 3 /* object name is already in use */
+#define SA_BAD_PATH 4 /* not a full path */
+#define SA_NO_SUCH_GROUP 5 /* group is not defined */
+#define SA_CONFIG_ERR 6 /* system configuration error */
+#define SA_SYSTEM_ERR 7 /* system error, use errno */
+#define SA_SYNTAX_ERR 8 /* syntax error on command line */
+#define SA_NO_PERMISSION 9 /* no permission for operation */
+#define SA_BUSY 10 /* resource is busy */
+#define SA_NO_SUCH_PROP 11 /* property doesn't exist */
+#define SA_INVALID_NAME 12 /* name of object is invalid */
+#define SA_INVALID_PROTOCOL 13 /* specified protocol not valid */
+#define SA_NOT_ALLOWED 14 /* operation not allowed */
+#define SA_BAD_VALUE 15 /* bad value for property */
+#define SA_INVALID_SECURITY 16 /* invalid security type */
+#define SA_NO_SUCH_SECURITY 17 /* security set not found */
+#define SA_VALUE_CONFLICT 18 /* property value conflict */
+#define SA_NOT_IMPLEMENTED 19 /* plugin interface not implemented */
+#define SA_INVALID_PATH 20 /* path is sub-dir of existing share */
+#define SA_NOT_SUPPORTED 21 /* operation not supported for proto */
+#define SA_PROP_SHARE_ONLY 22 /* property valid on share only */
+#define SA_NOT_SHARED 23 /* path is not shared */
+#define SA_NO_SUCH_RESOURCE 24 /* resource not found */
+#define SA_RESOURCE_REQUIRED 25 /* resource name is required */
+#define SA_MULTIPLE_ERROR 26 /* multiple protocols reported error */
+#define SA_PATH_IS_SUBDIR 27 /* check_path found path is subdir */
+#define SA_PATH_IS_PARENTDIR 28 /* check_path found path is parent */
+#define SA_NO_SECTION 29 /* protocol requires section info */
+#define SA_NO_SUCH_SECTION 30 /* no section found */
+#define SA_NO_PROPERTIES 31 /* no properties found */
+#define SA_PASSWORD_ENC 32 /* passwords must be encrypted */
+#define SA_SHARE_EXISTS 33 /* path or file is already shared */
+
+/* initialization */
+extern char *sa_errorstr(int);
+
+/* share control */
+extern int sa_enable_share(const char *, const char *, const char *,
+ char *);
+extern int sa_disable_share(const char *, char *);
+extern boolean_t sa_is_shared(const char *, char *);
+extern void sa_commit_shares(const char *);
+
+/* protocol specific interfaces */
+extern int sa_validate_shareopts(char *, char *);
+
+#endif /* _LIBSPL_LIBSHARE_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/limits.h b/sys/contrib/openzfs/lib/libspl/include/limits.h
new file mode 100644
index 000000000000..1a42cfec469c
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/limits.h
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include_next <limits.h>
+
+#ifndef _LIBSPL_LIMITS_H
+#define _LIBSPL_LIMITS_H
+
+#define DBL_DIG 15
+#define DBL_MAX 1.7976931348623157081452E+308
+#define DBL_MIN 2.2250738585072013830903E-308
+
+#define FLT_DIG 6
+#define FLT_MAX 3.4028234663852885981170E+38F
+#define FLT_MIN 1.1754943508222875079688E-38F
+
+#endif /* _LIBSPL_LIMITS_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/locale.h b/sys/contrib/openzfs/lib/libspl/include/locale.h
new file mode 100644
index 000000000000..6c74df72072e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/locale.h
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include_next <locale.h>
+
+#ifndef _LIBSPL_LOCALE_H
+#define _LIBSPL_LOCALE_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/os/Makefile.am
new file mode 100644
index 000000000000..7b362e02ad59
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/Makefile.am
@@ -0,0 +1,7 @@
+if BUILD_FREEBSD
+SUBDIRS = freebsd
+endif
+
+if BUILD_LINUX
+SUBDIRS = linux
+endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/Makefile.am
new file mode 100644
index 000000000000..081839c48c8f
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = sys
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/Makefile.am
new file mode 100644
index 000000000000..6775522f5d72
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/Makefile.am
@@ -0,0 +1,11 @@
+libspldir = $(includedir)/libspl/sys
+libspl_HEADERS = \
+ byteorder.h \
+ file.h \
+ mnttab.h \
+ mount.h \
+ param.h \
+ stat.h \
+ sysmacros.h \
+ vfs.h \
+ zfs_context_os.h
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/byteorder.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/byteorder.h
new file mode 100644
index 000000000000..cd692d3616e0
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/byteorder.h
@@ -0,0 +1,192 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+
+#ifndef _SYS_BYTEORDER_H
+#define _SYS_BYTEORDER_H
+
+#include <sys/endian.h>
+#include <netinet/in.h>
+#include <sys/isa_defs.h>
+#include <sys/int_types.h>
+
+#if defined(__GNUC__) && defined(_ASM_INLINES) && \
+ (defined(__i386) || defined(__amd64))
+#include <asm/byteorder.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * macros for conversion between host and (internet) network byte order
+ */
+#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
+
+/*
+ * Macros to reverse byte order
+ */
+#define BSWAP_8(x) ((x) & 0xff)
+#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
+#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
+#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
+
+#define BMASK_8(x) ((x) & 0xff)
+#define BMASK_16(x) ((x) & 0xffff)
+#define BMASK_32(x) ((x) & 0xffffffff)
+#define BMASK_64(x) (x)
+
+/*
+ * Macros to convert from a specific byte order to/from native byte order
+ */
+#ifdef _ZFS_BIG_ENDIAN
+#define BE_8(x) BMASK_8(x)
+#define BE_16(x) BMASK_16(x)
+#define BE_32(x) BMASK_32(x)
+#define BE_64(x) BMASK_64(x)
+#define LE_8(x) BSWAP_8(x)
+#define LE_16(x) BSWAP_16(x)
+#define LE_32(x) BSWAP_32(x)
+#define LE_64(x) BSWAP_64(x)
+#else
+#define LE_8(x) BMASK_8(x)
+#define LE_16(x) BMASK_16(x)
+#define LE_32(x) BMASK_32(x)
+#define LE_64(x) BMASK_64(x)
+#define BE_8(x) BSWAP_8(x)
+#define BE_16(x) BSWAP_16(x)
+#define BE_32(x) BSWAP_32(x)
+#define BE_64(x) BSWAP_64(x)
+#endif
+
+#ifdef _ZFS_BIG_ENDIAN
+static __inline__ uint64_t
+htonll(uint64_t n)
+{
+ return (n);
+}
+
+static __inline__ uint64_t
+ntohll(uint64_t n)
+{
+ return (n);
+}
+#else
+static __inline__ uint64_t
+htonll(uint64_t n)
+{
+ return ((((uint64_t)htonl(n)) << 32) + htonl(n >> 32));
+}
+
+static __inline__ uint64_t
+ntohll(uint64_t n)
+{
+ return ((((uint64_t)ntohl(n)) << 32) + ntohl(n >> 32));
+}
+#endif
+
+/*
+ * Macros to read unaligned values from a specific byte order to
+ * native byte order
+ */
+
+#define BE_IN8(xa) \
+ *((uint8_t *)(xa))
+
+#define BE_IN16(xa) \
+ (((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1))
+
+#define BE_IN32(xa) \
+ (((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2))
+
+#define BE_IN64(xa) \
+ (((uint64_t)BE_IN32(xa) << 32) | BE_IN32((uint8_t *)(xa)+4))
+
+#define LE_IN8(xa) \
+ *((uint8_t *)(xa))
+
+#define LE_IN16(xa) \
+ (((uint16_t)LE_IN8((uint8_t *)(xa) + 1) << 8) | LE_IN8(xa))
+
+#define LE_IN32(xa) \
+ (((uint32_t)LE_IN16((uint8_t *)(xa) + 2) << 16) | LE_IN16(xa))
+
+#define LE_IN64(xa) \
+ (((uint64_t)LE_IN32((uint8_t *)(xa) + 4) << 32) | LE_IN32(xa))
+
+/*
+ * Macros to write unaligned values from native byte order to a specific byte
+ * order.
+ */
+
+#define BE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
+
+#define BE_OUT16(xa, yv) \
+ BE_OUT8((uint8_t *)(xa) + 1, yv); \
+ BE_OUT8((uint8_t *)(xa), (yv) >> 8);
+
+#define BE_OUT32(xa, yv) \
+ BE_OUT16((uint8_t *)(xa) + 2, yv); \
+ BE_OUT16((uint8_t *)(xa), (yv) >> 16);
+
+#define BE_OUT64(xa, yv) \
+ BE_OUT32((uint8_t *)(xa) + 4, yv); \
+ BE_OUT32((uint8_t *)(xa), (yv) >> 32);
+
+#define LE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
+
+#define LE_OUT16(xa, yv) \
+ LE_OUT8((uint8_t *)(xa), yv); \
+ LE_OUT8((uint8_t *)(xa) + 1, (yv) >> 8);
+
+#define LE_OUT32(xa, yv) \
+ LE_OUT16((uint8_t *)(xa), yv); \
+ LE_OUT16((uint8_t *)(xa) + 2, (yv) >> 16);
+
+#define LE_OUT64(xa, yv) \
+ LE_OUT32((uint8_t *)(xa), yv); \
+ LE_OUT32((uint8_t *)(xa) + 4, (yv) >> 32);
+
+#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_BYTEORDER_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/file.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/file.h
new file mode 100644
index 000000000000..27fd2888f326
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/file.h
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_FILE_H
+#define _LIBSPL_SYS_FILE_H
+
+#include_next <sys/file.h>
+
+#define FCREAT O_CREAT
+#define FTRUNC O_TRUNC
+#define FSYNC O_SYNC
+#define FDSYNC O_DSYNC
+#define FEXCL O_EXCL
+
+#define FNODSYNC 0x10000 /* fsync pseudo flag */
+#define FNOFOLLOW 0x20000 /* don't follow symlinks */
+#define FIGNORECASE 0x80000 /* request case-insensitive lookups */
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mnttab.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mnttab.h
new file mode 100644
index 000000000000..c08349bdf9bd
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mnttab.h
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/* Copyright 2006 Ricardo Correia */
+
+#ifndef _SYS_MNTTAB_H
+#define _SYS_MNTTAB_H
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef MNTTAB
+#undef MNTTAB
+#endif /* MNTTAB */
+
+#include <paths.h>
+#include <sys/mount.h>
+#define MNTTAB _PATH_DEVZERO
+#define MS_NOMNTTAB 0x0
+#define MS_RDONLY 0x1
+#define umount2(p, f) unmount(p, f)
+#define MNT_LINE_MAX 4108
+
+#define MNT_TOOLONG 1 /* entry exceeds MNT_LINE_MAX */
+#define MNT_TOOMANY 2 /* too many fields in line */
+#define MNT_TOOFEW 3 /* too few fields in line */
+
+struct mnttab {
+ char *mnt_special;
+ char *mnt_mountp;
+ char *mnt_fstype;
+ char *mnt_mntopts;
+};
+
+/*
+ * NOTE: fields in extmnttab should match struct mnttab till new fields
+ * are encountered, this allows hasmntopt to work properly when its arg is
+ * a pointer to an extmnttab struct cast to a mnttab struct pointer.
+ */
+
+struct extmnttab {
+ char *mnt_special;
+ char *mnt_mountp;
+ char *mnt_fstype;
+ char *mnt_mntopts;
+ uint_t mnt_major;
+ uint_t mnt_minor;
+};
+
+struct stat64;
+struct statfs;
+
+extern int getmntany(FILE *fp, struct mnttab *mp, struct mnttab *mpref);
+extern int _sol_getmntent(FILE *fp, struct mnttab *mp);
+extern int getextmntent(const char *path, struct extmnttab *entry,
+ struct stat64 *statbuf);
+extern void statfs2mnttab(struct statfs *sfs, struct mnttab *mp);
+char *hasmntopt(struct mnttab *mnt, char *opt);
+int getmntent(FILE *fp, struct mnttab *mp);
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h
new file mode 100644
index 000000000000..b4023910005b
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h
@@ -0,0 +1,108 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#ifndef _LIBSPL_SYS_MOUNT_H
+#define _LIBSPL_SYS_MOUNT_H
+
+#undef _SYS_MOUNT_H_
+#include_next <sys/mount.h>
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+/*
+ * Some old glibc headers don't define BLKGETSIZE64
+ * and we don't want to require the kernel headers
+ */
+#if !defined(BLKGETSIZE64)
+#define BLKGETSIZE64 _IOR(0x12, 114, size_t)
+#endif
+
+/*
+ * Some old glibc headers don't correctly define MS_DIRSYNC and
+ * instead use the enum name S_WRITE. When using these older
+ * headers define MS_DIRSYNC to be S_WRITE.
+ */
+#if !defined(MS_DIRSYNC)
+#define MS_DIRSYNC S_WRITE
+#endif
+
+/*
+ * Some old glibc headers don't correctly define MS_POSIXACL and
+ * instead leave it undefined. When using these older headers define
+ * MS_POSIXACL to the reserved value of (1<<16).
+ */
+#if !defined(MS_POSIXACL)
+#define MS_POSIXACL (1<<16)
+#endif
+
+#define MS_NOSUID MNT_NOSUID
+#define MS_NOEXEC MNT_NOEXEC
+#define MS_NODEV 0
+#define S_WRITE 0
+#define MS_BIND 0
+#define MS_REMOUNT 0
+#define MS_SYNCHRONOUS MNT_SYNCHRONOUS
+
+#define MS_USERS (MS_NOEXEC|MS_NOSUID|MS_NODEV)
+#define MS_OWNER (MS_NOSUID|MS_NODEV)
+#define MS_GROUP (MS_NOSUID|MS_NODEV)
+#define MS_COMMENT 0
+
+/*
+ * Older glibc <sys/mount.h> headers did not define all the available
+ * umount2(2) flags. Both MNT_FORCE and MNT_DETACH are supported in the
+ * kernel back to 2.4.11 so we define them correctly if they are missing.
+ */
+#ifdef MNT_FORCE
+#define MS_FORCE MNT_FORCE
+#else
+#define MS_FORCE 0x00000001
+#endif /* MNT_FORCE */
+
+#ifdef MNT_DETACH
+#define MS_DETACH MNT_DETACH
+#else
+#define MS_DETACH 0x00000002
+#endif /* MNT_DETACH */
+
+/*
+ * Overlay mount is default in Linux, but for solaris/zfs
+ * compatibility, MS_OVERLAY is defined to explicitly have the user
+ * provide a flag (-O) to mount over a non empty directory.
+ */
+#define MS_OVERLAY 0x00000004
+
+/*
+ * MS_CRYPT indicates that encryption keys should be loaded if they are not
+ * already available. This is not defined in glibc, but it is never seen by
+ * the kernel so it will not cause any problems.
+ */
+#define MS_CRYPT 0x00000008
+
+#endif /* _LIBSPL_SYS_MOUNT_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h
new file mode 100644
index 000000000000..7c23b670591a
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_PARAM_H
+#define _LIBSPL_SYS_PARAM_H
+
+#include_next <sys/param.h>
+#include <unistd.h>
+
+/*
+ * File system parameters and macros.
+ *
+ * The file system is made out of blocks of at most MAXBSIZE units,
+ * with smaller units (fragments) only in the last direct block.
+ * MAXBSIZE primarily determines the size of buffers in the buffer
+ * pool. It may be made larger without any effect on existing
+ * file systems; however making it smaller may make some file
+ * systems unmountable.
+ *
+ * Note that the blocked devices are assumed to have DEV_BSIZE
+ * "sectors" and that fragments must be some multiple of this size.
+ */
+#define MAXNAMELEN 256
+
+#ifndef IN_BASE
+#define UID_NOBODY 60001 /* user ID no body */
+#define GID_NOBODY UID_NOBODY
+#endif
+#define UID_NOACCESS 60002 /* user ID no access */
+
+#define MAXUID UINT32_MAX /* max user id */
+#define MAXPROJID MAXUID /* max project id */
+
+#ifdef PAGESIZE
+#undef PAGESIZE
+#endif /* PAGESIZE */
+
+extern size_t spl_pagesize(void);
+#define PAGESIZE (spl_pagesize())
+
+extern int execvpe(const char *name, char * const argv[], char * const envp[]);
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/stat.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/stat.h
new file mode 100644
index 000000000000..82c86262fff3
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/stat.h
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _LIBSPL_SYS_STAT_H
+#define _LIBSPL_SYS_STAT_H
+
+#include_next <sys/stat.h>
+
+#include <sys/mount.h> /* for BLKGETSIZE64 */
+
+#define stat64 stat
+
+#define MAXOFFSET_T OFF_MAX
+
+#ifndef _KERNEL
+#include <sys/disk.h>
+
+static __inline int
+fstat64(int fd, struct stat *sb)
+{
+ int ret;
+
+ ret = fstat(fd, sb);
+ if (ret == 0) {
+ if (S_ISCHR(sb->st_mode))
+ (void) ioctl(fd, DIOCGMEDIASIZE, &sb->st_size);
+ }
+ return (ret);
+}
+#endif
+
+/*
+ * Emulate Solaris' behavior of returning the block device size in fstat64().
+ */
+static inline int
+fstat64_blk(int fd, struct stat64 *st)
+{
+ if (fstat64(fd, st) == -1)
+ return (-1);
+
+ /* In Linux we need to use an ioctl to get the size of a block device */
+ if (S_ISBLK(st->st_mode)) {
+ if (ioctl(fd, BLKGETSIZE64, &st->st_size) != 0)
+ return (-1);
+ }
+
+ return (0);
+}
+#endif /* _LIBSPL_SYS_STAT_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/sysmacros.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/sysmacros.h
new file mode 100644
index 000000000000..d9639d27b60e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/sysmacros.h
@@ -0,0 +1 @@
+/* keep me */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/vfs.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/vfs.h
new file mode 100644
index 000000000000..55eb3c23b22e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/vfs.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 iXsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ZFS_SYS_VFS_H_
+#define ZFS_SYS_VFS_H_
+
+#include_next <sys/statvfs.h>
+
+int fsshare(const char *, const char *, const char *);
+int fsunshare(const char *, const char *);
+
+#endif /* !ZFS_SYS_VFS_H_ */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/zfs_context_os.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/zfs_context_os.h
new file mode 100644
index 000000000000..f5a136d22125
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/zfs_context_os.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 iXsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ZFS_CONTEXT_OS_H_
+#define ZFS_CONTEXT_OS_H_
+
+#define ZFS_EXPORTS_PATH "/etc/zfs/exports"
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/os/linux/Makefile.am
new file mode 100644
index 000000000000..081839c48c8f
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = sys
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/Makefile.am
new file mode 100644
index 000000000000..1ec07a76d354
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/Makefile.am
@@ -0,0 +1,10 @@
+libspldir = $(includedir)/libspl/sys
+libspl_HEADERS = \
+ byteorder.h \
+ errno.h \
+ mnttab.h \
+ mount.h \
+ param.h \
+ stat.h \
+ sysmacros.h \
+ zfs_context_os.h
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/byteorder.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/byteorder.h
new file mode 100644
index 000000000000..d5ee3e26f5a5
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/byteorder.h
@@ -0,0 +1,223 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+
+#ifndef _SYS_BYTEORDER_H
+#define _SYS_BYTEORDER_H
+
+#if defined(__GNUC__) && defined(_ASM_INLINES) && \
+ (defined(__i386) || defined(__amd64))
+#include <asm/byteorder.h>
+#endif
+
+#include <sys/isa_defs.h>
+#include <sys/int_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * macros for conversion between host and (internet) network byte order
+ */
+
+#if defined(_ZFS_BIG_ENDIAN) && !defined(ntohl) && !defined(__lint)
+/* big-endian */
+#define ntohl(x) (x)
+#define ntohs(x) (x)
+#define htonl(x) (x)
+#define htons(x) (x)
+
+#elif !defined(ntohl) /* little-endian */
+
+#ifndef _IN_PORT_T
+#define _IN_PORT_T
+typedef uint16_t in_port_t;
+#endif
+
+#ifndef _IN_ADDR_T
+#define _IN_ADDR_T
+typedef uint32_t in_addr_t;
+#endif
+
+#if !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5)
+extern uint32_t htonl(uint32_t);
+extern uint16_t htons(uint16_t);
+extern uint32_t ntohl(uint32_t);
+extern uint16_t ntohs(uint16_t);
+#else
+extern in_addr_t htonl(in_addr_t);
+extern in_port_t htons(in_port_t);
+extern in_addr_t ntohl(in_addr_t);
+extern in_port_t ntohs(in_port_t);
+#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5) */
+#endif
+
+#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
+
+/*
+ * Macros to reverse byte order
+ */
+#define BSWAP_8(x) ((x) & 0xff)
+#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
+#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
+#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
+
+#define BMASK_8(x) ((x) & 0xff)
+#define BMASK_16(x) ((x) & 0xffff)
+#define BMASK_32(x) ((x) & 0xffffffff)
+#define BMASK_64(x) (x)
+
+/*
+ * Macros to convert from a specific byte order to/from native byte order
+ */
+#ifdef _ZFS_BIG_ENDIAN
+#define BE_8(x) BMASK_8(x)
+#define BE_16(x) BMASK_16(x)
+#define BE_32(x) BMASK_32(x)
+#define BE_64(x) BMASK_64(x)
+#define LE_8(x) BSWAP_8(x)
+#define LE_16(x) BSWAP_16(x)
+#define LE_32(x) BSWAP_32(x)
+#define LE_64(x) BSWAP_64(x)
+#else
+#define LE_8(x) BMASK_8(x)
+#define LE_16(x) BMASK_16(x)
+#define LE_32(x) BMASK_32(x)
+#define LE_64(x) BMASK_64(x)
+#define BE_8(x) BSWAP_8(x)
+#define BE_16(x) BSWAP_16(x)
+#define BE_32(x) BSWAP_32(x)
+#define BE_64(x) BSWAP_64(x)
+#endif
+
+#ifdef _ZFS_BIG_ENDIAN
+static __inline__ uint64_t
+htonll(uint64_t n)
+{
+ return (n);
+}
+
+static __inline__ uint64_t
+ntohll(uint64_t n)
+{
+ return (n);
+}
+#else
+static __inline__ uint64_t
+htonll(uint64_t n)
+{
+ return ((((uint64_t)htonl(n)) << 32) + htonl(n >> 32));
+}
+
+static __inline__ uint64_t
+ntohll(uint64_t n)
+{
+ return ((((uint64_t)ntohl(n)) << 32) + ntohl(n >> 32));
+}
+#endif
+
+/*
+ * Macros to read unaligned values from a specific byte order to
+ * native byte order
+ */
+
+#define BE_IN8(xa) \
+ *((uint8_t *)(xa))
+
+#define BE_IN16(xa) \
+ (((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1))
+
+#define BE_IN32(xa) \
+ (((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2))
+
+#define BE_IN64(xa) \
+ (((uint64_t)BE_IN32(xa) << 32) | BE_IN32((uint8_t *)(xa)+4))
+
+#define LE_IN8(xa) \
+ *((uint8_t *)(xa))
+
+#define LE_IN16(xa) \
+ (((uint16_t)LE_IN8((uint8_t *)(xa) + 1) << 8) | LE_IN8(xa))
+
+#define LE_IN32(xa) \
+ (((uint32_t)LE_IN16((uint8_t *)(xa) + 2) << 16) | LE_IN16(xa))
+
+#define LE_IN64(xa) \
+ (((uint64_t)LE_IN32((uint8_t *)(xa) + 4) << 32) | LE_IN32(xa))
+
+/*
+ * Macros to write unaligned values from native byte order to a specific byte
+ * order.
+ */
+
+#define BE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
+
+#define BE_OUT16(xa, yv) \
+ BE_OUT8((uint8_t *)(xa) + 1, yv); \
+ BE_OUT8((uint8_t *)(xa), (yv) >> 8);
+
+#define BE_OUT32(xa, yv) \
+ BE_OUT16((uint8_t *)(xa) + 2, yv); \
+ BE_OUT16((uint8_t *)(xa), (yv) >> 16);
+
+#define BE_OUT64(xa, yv) \
+ BE_OUT32((uint8_t *)(xa) + 4, yv); \
+ BE_OUT32((uint8_t *)(xa), (yv) >> 32);
+
+#define LE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
+
+#define LE_OUT16(xa, yv) \
+ LE_OUT8((uint8_t *)(xa), yv); \
+ LE_OUT8((uint8_t *)(xa) + 1, (yv) >> 8);
+
+#define LE_OUT32(xa, yv) \
+ LE_OUT16((uint8_t *)(xa), yv); \
+ LE_OUT16((uint8_t *)(xa) + 2, (yv) >> 16);
+
+#define LE_OUT64(xa, yv) \
+ LE_OUT32((uint8_t *)(xa), yv); \
+ LE_OUT32((uint8_t *)(xa) + 4, (yv) >> 32);
+
+#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_BYTEORDER_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/errno.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/errno.h
new file mode 100644
index 000000000000..30d20ab895c5
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/errno.h
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2017 Zettabyte Software, LLC. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Compiling against musl correctly points out that including sys/errno.h is
+ * disallowed by the Single UNIX Specification when building in userspace, so
+ * we implement a dummy header to redirect the include to the proper header.
+ */
+#ifndef _LIBSPL_SYS_ERRNO_H
+#define _LIBSPL_SYS_ERRNO_H
+
+#include <errno.h>
+/*
+ * We'll take the unused errnos, 'EBADE' and 'EBADR' (from the Convergent
+ * graveyard) to indicate checksum errors and fragmentation.
+ */
+#define ECKSUM EBADE
+#define EFRAGS EBADR
+
+/* Similar for ENOACTIVE */
+#define ENOTACTIVE ENOANO
+
+#endif /* _LIBSPL_SYS_ERRNO_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mnttab.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mnttab.h
new file mode 100644
index 000000000000..1957293d5c69
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mnttab.h
@@ -0,0 +1,89 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/* Copyright 2006 Ricardo Correia */
+
+#ifndef _SYS_MNTTAB_H
+#define _SYS_MNTTAB_H
+
+#include <stdio.h>
+#include <mntent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef MNTTAB
+#undef MNTTAB
+#endif /* MNTTAB */
+
+#define MNTTAB "/proc/self/mounts"
+#define MNT_LINE_MAX 4108
+
+#define MNT_TOOLONG 1 /* entry exceeds MNT_LINE_MAX */
+#define MNT_TOOMANY 2 /* too many fields in line */
+#define MNT_TOOFEW 3 /* too few fields in line */
+
+struct mnttab {
+ char *mnt_special;
+ char *mnt_mountp;
+ char *mnt_fstype;
+ char *mnt_mntopts;
+};
+
+/*
+ * NOTE: fields in extmnttab should match struct mnttab till new fields
+ * are encountered, this allows hasmntopt to work properly when its arg is
+ * a pointer to an extmnttab struct cast to a mnttab struct pointer.
+ */
+
+struct extmnttab {
+ char *mnt_special;
+ char *mnt_mountp;
+ char *mnt_fstype;
+ char *mnt_mntopts;
+ uint_t mnt_major;
+ uint_t mnt_minor;
+};
+
+struct statfs;
+
+extern int getmntany(FILE *fp, struct mnttab *mp, struct mnttab *mpref);
+extern int _sol_getmntent(FILE *fp, struct mnttab *mp);
+extern int getextmntent(const char *path, struct extmnttab *mp,
+ struct stat64 *statbuf);
+static inline char *_sol_hasmntopt(struct mnttab *mnt, char *opt)
+{
+ struct mntent mnt_new;
+
+ mnt_new.mnt_opts = mnt->mnt_mntopts;
+
+ return (hasmntopt(&mnt_new, opt));
+}
+
+#define hasmntopt _sol_hasmntopt
+#define getmntent _sol_getmntent
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mount.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mount.h
new file mode 100644
index 000000000000..d7c6f750e23d
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mount.h
@@ -0,0 +1,98 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include_next <sys/mount.h>
+
+#ifndef _LIBSPL_SYS_MOUNT_H
+#define _LIBSPL_SYS_MOUNT_H
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+/*
+ * Some old glibc headers don't define BLKGETSIZE64
+ * and we don't want to require the kernel headers
+ */
+#if !defined(BLKGETSIZE64)
+#define BLKGETSIZE64 _IOR(0x12, 114, size_t)
+#endif
+
+/*
+ * Some old glibc headers don't correctly define MS_DIRSYNC and
+ * instead use the enum name S_WRITE. When using these older
+ * headers define MS_DIRSYNC to be S_WRITE.
+ */
+#if !defined(MS_DIRSYNC)
+#define MS_DIRSYNC S_WRITE
+#endif
+
+/*
+ * Some old glibc headers don't correctly define MS_POSIXACL and
+ * instead leave it undefined. When using these older headers define
+ * MS_POSIXACL to the reserved value of (1<<16).
+ */
+#if !defined(MS_POSIXACL)
+#define MS_POSIXACL (1<<16)
+#endif
+
+#define MS_USERS (MS_NOEXEC|MS_NOSUID|MS_NODEV)
+#define MS_OWNER (MS_NOSUID|MS_NODEV)
+#define MS_GROUP (MS_NOSUID|MS_NODEV)
+#define MS_COMMENT 0
+
+/*
+ * Older glibc <sys/mount.h> headers did not define all the available
+ * umount2(2) flags. Both MNT_FORCE and MNT_DETACH are supported in the
+ * kernel back to 2.4.11 so we define them correctly if they are missing.
+ */
+#ifdef MNT_FORCE
+#define MS_FORCE MNT_FORCE
+#else
+#define MS_FORCE 0x00000001
+#endif /* MNT_FORCE */
+
+#ifdef MNT_DETACH
+#define MS_DETACH MNT_DETACH
+#else
+#define MS_DETACH 0x00000002
+#endif /* MNT_DETACH */
+
+/*
+ * Overlay mount is default in Linux, but for solaris/zfs
+ * compatibility, MS_OVERLAY is defined to explicitly have the user
+ * provide a flag (-O) to mount over a non empty directory.
+ */
+#define MS_OVERLAY 0x00000004
+
+/*
+ * MS_CRYPT indicates that encryption keys should be loaded if they are not
+ * already available. This is not defined in glibc, but it is never seen by
+ * the kernel so it will not cause any problems.
+ */
+#define MS_CRYPT 0x00000008
+
+#endif /* _LIBSPL_SYS_MOUNT_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h
new file mode 100644
index 000000000000..26335187fdca
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_PARAM_H
+#define _LIBSPL_SYS_PARAM_H
+
+#include_next <sys/param.h>
+#include <unistd.h>
+
+/*
+ * File system parameters and macros.
+ *
+ * The file system is made out of blocks of at most MAXBSIZE units,
+ * with smaller units (fragments) only in the last direct block.
+ * MAXBSIZE primarily determines the size of buffers in the buffer
+ * pool. It may be made larger without any effect on existing
+ * file systems; however making it smaller may make some file
+ * systems unmountable.
+ *
+ * Note that the blocked devices are assumed to have DEV_BSIZE
+ * "sectors" and that fragments must be some multiple of this size.
+ */
+#define MAXBSIZE 8192
+#define DEV_BSIZE 512
+#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
+
+#define MAXNAMELEN 256
+#define MAXOFFSET_T LLONG_MAX
+
+#define UID_NOBODY 60001 /* user ID no body */
+#define GID_NOBODY UID_NOBODY
+#define UID_NOACCESS 60002 /* user ID no access */
+
+#define MAXUID UINT32_MAX /* max user id */
+#define MAXPROJID MAXUID /* max project id */
+
+#ifdef PAGESIZE
+#undef PAGESIZE
+#endif /* PAGESIZE */
+
+extern size_t spl_pagesize(void);
+#define PAGESIZE (spl_pagesize())
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/stat.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/stat.h
new file mode 100644
index 000000000000..3e8d27e4c19a
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/stat.h
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _LIBSPL_SYS_STAT_H
+#define _LIBSPL_SYS_STAT_H
+
+#include_next <sys/stat.h>
+
+#include <sys/mount.h> /* for BLKGETSIZE64 */
+
+/*
+ * Emulate Solaris' behavior of returning the block device size in fstat64().
+ */
+static inline int
+fstat64_blk(int fd, struct stat64 *st)
+{
+ if (fstat64(fd, st) == -1)
+ return (-1);
+
+ /* In Linux we need to use an ioctl to get the size of a block device */
+ if (S_ISBLK(st->st_mode)) {
+ if (ioctl(fd, BLKGETSIZE64, &st->st_size) != 0)
+ return (-1);
+ }
+
+ return (0);
+}
+#endif /* _LIBSPL_SYS_STAT_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/sysmacros.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/sysmacros.h
new file mode 100644
index 000000000000..22fcb04b94e0
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/sysmacros.h
@@ -0,0 +1,103 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_SYSMACROS_H
+#define _LIBSPL_SYS_SYSMACROS_H
+
+#include_next <sys/sysmacros.h>
+
+/* common macros */
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+#endif
+#ifndef ABS
+#define ABS(a) ((a) < 0 ? -(a) : (a))
+#endif
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
+#endif
+#ifndef DIV_ROUND_UP
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+#endif
+
+#define makedevice(maj, min) makedev(maj, min)
+#define _sysconf(a) sysconf(a)
+
+/*
+ * Compatibility macros/typedefs needed for Solaris -> Linux port
+ */
+#define P2ALIGN(x, align) ((x) & -(align))
+#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
+#define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1)
+#define P2BOUNDARY(off, len, align) \
+ (((off) ^ ((off) + (len) - 1)) > (align) - 1)
+#define P2PHASE(x, align) ((x) & ((align) - 1))
+#define P2NPHASE(x, align) (-(x) & ((align) - 1))
+#define P2NPHASE_TYPED(x, align, type) \
+ (-(type)(x) & ((type)(align) - 1))
+#define ISP2(x) (((x) & ((x) - 1)) == 0)
+#define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0)
+
+/*
+ * Typed version of the P2* macros. These macros should be used to ensure
+ * that the result is correctly calculated based on the data type of (x),
+ * which is passed in as the last argument, regardless of the data
+ * type of the alignment. For example, if (x) is of type uint64_t,
+ * and we want to round it up to a page boundary using "PAGESIZE" as
+ * the alignment, we can do either
+ * P2ROUNDUP(x, (uint64_t)PAGESIZE)
+ * or
+ * P2ROUNDUP_TYPED(x, PAGESIZE, uint64_t)
+ */
+#define P2ALIGN_TYPED(x, align, type) \
+ ((type)(x) & -(type)(align))
+#define P2PHASE_TYPED(x, align, type) \
+ ((type)(x) & ((type)(align) - 1))
+#define P2NPHASE_TYPED(x, align, type) \
+ (-(type)(x) & ((type)(align) - 1))
+#define P2ROUNDUP_TYPED(x, align, type) \
+ ((((type)(x) - 1) | ((type)(align) - 1)) + 1)
+#define P2END_TYPED(x, align, type) \
+ (-(~(type)(x) & -(type)(align)))
+#define P2PHASEUP_TYPED(x, align, phase, type) \
+ ((type)(phase) - (((type)(phase) - (type)(x)) & -(type)(align)))
+#define P2CROSS_TYPED(x, y, align, type) \
+ (((type)(x) ^ (type)(y)) > (type)(align) - 1)
+#define P2SAMEHIGHBIT_TYPED(x, y, type) \
+ (((type)(x) ^ (type)(y)) < ((type)(x) & (type)(y)))
+
+
+/* avoid any possibility of clashing with <stddef.h> version */
+#if defined(_KERNEL) && !defined(_KMEMUSER) && !defined(offsetof)
+#define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
+#endif
+
+#define _NOTE(x)
+
+#endif /* _LIBSPL_SYS_SYSMACROS_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/zfs_context_os.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/zfs_context_os.h
new file mode 100644
index 000000000000..008e57df4eae
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/zfs_context_os.h
@@ -0,0 +1,25 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#ifndef ZFS_CONTEXT_OS_H
+#define ZFS_CONTEXT_OS_H
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/rpc/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/rpc/Makefile.am
new file mode 100644
index 000000000000..7fe1d7fea4d7
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/rpc/Makefile.am
@@ -0,0 +1,3 @@
+libspldir = $(includedir)/libspl/rpc
+libspl_HEADERS = \
+ xdr.h
diff --git a/sys/contrib/openzfs/lib/libspl/include/rpc/xdr.h b/sys/contrib/openzfs/lib/libspl/include/rpc/xdr.h
new file mode 100644
index 000000000000..51d71f693bbf
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/rpc/xdr.h
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
+ * All Rights Reserved
+ *
+ * Portions of this source code were derived from Berkeley 4.3 BSD
+ * under license from the Regents of the University of California.
+ */
+
+#ifndef LIBSPL_RPC_XDR_H
+#define LIBSPL_RPC_XDR_H
+
+#include_next <rpc/xdr.h>
+
+#ifdef xdr_control /* if e.g. using tirpc */
+#undef xdr_control
+#endif
+
+#define XDR_GET_BYTES_AVAIL 1
+
+#ifndef HAVE_XDR_BYTESREC
+struct xdr_bytesrec {
+ bool_t xc_is_last_record;
+ size_t xc_num_avail;
+};
+#endif
+typedef struct xdr_bytesrec xdr_bytesrec_t;
+
+/*
+ * This functionality is not required and is disabled in user space.
+ */
+static inline bool_t
+xdr_control(XDR *xdrs, int request, void *info)
+{
+ xdr_bytesrec_t *xptr;
+
+ ASSERT3U(request, ==, XDR_GET_BYTES_AVAIL);
+
+ xptr = (xdr_bytesrec_t *)info;
+ xptr->xc_is_last_record = TRUE;
+ xptr->xc_num_avail = xdrs->x_handy;
+
+ return (TRUE);
+}
+
+#endif /* LIBSPL_RPC_XDR_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/statcommon.h b/sys/contrib/openzfs/lib/libspl/include/statcommon.h
new file mode 100644
index 000000000000..1f376f5c7c24
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/statcommon.h
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Common routines for acquiring snapshots of kstats for
+ * iostat, mpstat, and vmstat.
+ */
+
+#ifndef _STATCOMMON_H
+#define _STATCOMMON_H
+
+#include <sys/types.h>
+
+#define NODATE 0 /* Default: No time stamp */
+#define DDATE 1 /* Standard date format */
+#define UDATE 2 /* Internal representation of Unix time */
+
+/* Print a timestamp in either Unix or standard format. */
+void print_timestamp(uint_t);
+
+#endif /* _STATCOMMON_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/stdio.h b/sys/contrib/openzfs/lib/libspl/include/stdio.h
new file mode 100644
index 000000000000..6152b09f1a97
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/stdio.h
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include_next <stdio.h>
+
+#ifndef _LIBSPL_STDIO_H
+#define _LIBSPL_STDIO_H
+
+#define enable_extended_FILE_stdio(fd, sig) ((void) 0)
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/stdlib.h b/sys/contrib/openzfs/lib/libspl/include/stdlib.h
new file mode 100644
index 000000000000..a4ce4f781fc5
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/stdlib.h
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include_next <stdlib.h>
+
+#ifndef _LIBSPL_STDLIB_H
+#define _LIBSPL_STDLIB_H
+
+extern const char *getexecname(void);
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/string.h b/sys/contrib/openzfs/lib/libspl/include/string.h
new file mode 100644
index 000000000000..a7d40fa61943
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/string.h
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_STRING_H
+#define _LIBSPL_STRING_H
+
+#include_next <string.h>
+
+#ifndef HAVE_STRLCAT
+extern size_t strlcat(char *dst, const char *src, size_t dstsize);
+#endif
+
+#ifndef HAVE_STRLCPY
+extern size_t strlcpy(char *dst, const char *src, size_t len);
+#endif
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/stropts.h b/sys/contrib/openzfs/lib/libspl/include/stropts.h
new file mode 100644
index 000000000000..37acd4052b0b
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/stropts.h
@@ -0,0 +1,25 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#ifndef _LIBSPL_STROPTS_H
+#define _LIBSPL_STROPTS_H
+
+#endif /* _LIBSPL_STROPTS_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/sys/Makefile.am
new file mode 100644
index 000000000000..53a36f6bfbca
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/Makefile.am
@@ -0,0 +1,47 @@
+SUBDIRS = dktp
+
+libspldir = $(includedir)/libspl/sys
+libspl_HEADERS = \
+ acl.h \
+ acl_impl.h \
+ callb.h \
+ cmn_err.h \
+ cred.h \
+ debug.h \
+ dkio.h \
+ dklabel.h \
+ feature_tests.h \
+ int_limits.h \
+ int_types.h \
+ inttypes.h \
+ isa_defs.h \
+ kmem.h \
+ kstat.h \
+ list.h \
+ list_impl.h \
+ mhd.h \
+ mkdev.h \
+ policy.h \
+ poll.h \
+ priv.h \
+ processor.h \
+ sha2.h \
+ simd.h \
+ stack.h \
+ stdtypes.h \
+ strings.h \
+ stropts.h \
+ sunddi.h \
+ systeminfo.h \
+ time.h \
+ trace_spl.h \
+ trace_zfs.h \
+ types32.h \
+ types.h \
+ tzfile.h \
+ uio.h \
+ va_list.h \
+ varargs.h \
+ vnode.h \
+ vtoc.h \
+ zone.h
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/acl.h b/sys/contrib/openzfs/lib/libspl/include/sys/acl.h
new file mode 100644
index 000000000000..e6df864f850f
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/acl.h
@@ -0,0 +1,287 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_ACL_H
+#define _SYS_ACL_H
+
+#include <sys/types.h>
+#include <sys/acl_impl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_ACL_ENTRIES (1024) /* max entries of each type */
+typedef struct acl {
+ int a_type; /* the type of ACL entry */
+ uid_t a_id; /* the entry in -uid or gid */
+ o_mode_t a_perm; /* the permission field */
+} aclent_t;
+
+typedef struct ace {
+ uid_t a_who; /* uid or gid */
+ uint32_t a_access_mask; /* read,write,... */
+ uint16_t a_flags; /* see below */
+ uint16_t a_type; /* allow or deny */
+} ace_t;
+
+typedef struct acl_info acl_t;
+
+/*
+ * The following are Defined types for an aclent_t.
+ */
+#define USER_OBJ (0x01) /* object owner */
+#define USER (0x02) /* additional users */
+#define GROUP_OBJ (0x04) /* owning group of the object */
+#define GROUP (0x08) /* additional groups */
+#define CLASS_OBJ (0x10) /* file group class and mask entry */
+#define OTHER_OBJ (0x20) /* other entry for the object */
+#define ACL_DEFAULT (0x1000) /* default flag */
+/* default object owner */
+#define DEF_USER_OBJ (ACL_DEFAULT | USER_OBJ)
+/* default additional users */
+#define DEF_USER (ACL_DEFAULT | USER)
+/* default owning group */
+#define DEF_GROUP_OBJ (ACL_DEFAULT | GROUP_OBJ)
+/* default additional groups */
+#define DEF_GROUP (ACL_DEFAULT | GROUP)
+/* default mask entry */
+#define DEF_CLASS_OBJ (ACL_DEFAULT | CLASS_OBJ)
+/* default other entry */
+#define DEF_OTHER_OBJ (ACL_DEFAULT | OTHER_OBJ)
+
+/*
+ * The following are defined for ace_t.
+ */
+#define ACE_READ_DATA 0x00000001
+#define ACE_LIST_DIRECTORY 0x00000001
+#define ACE_WRITE_DATA 0x00000002
+#define ACE_ADD_FILE 0x00000002
+#define ACE_APPEND_DATA 0x00000004
+#define ACE_ADD_SUBDIRECTORY 0x00000004
+#define ACE_READ_NAMED_ATTRS 0x00000008
+#define ACE_WRITE_NAMED_ATTRS 0x00000010
+#define ACE_EXECUTE 0x00000020
+#define ACE_DELETE_CHILD 0x00000040
+#define ACE_READ_ATTRIBUTES 0x00000080
+#define ACE_WRITE_ATTRIBUTES 0x00000100
+#define ACE_DELETE 0x00010000
+#define ACE_READ_ACL 0x00020000
+#define ACE_WRITE_ACL 0x00040000
+#define ACE_WRITE_OWNER 0x00080000
+#define ACE_SYNCHRONIZE 0x00100000
+
+#define ACE_FILE_INHERIT_ACE 0x0001
+#define ACE_DIRECTORY_INHERIT_ACE 0x0002
+#define ACE_NO_PROPAGATE_INHERIT_ACE 0x0004
+#define ACE_INHERIT_ONLY_ACE 0x0008
+#define ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x0010
+#define ACE_FAILED_ACCESS_ACE_FLAG 0x0020
+#define ACE_IDENTIFIER_GROUP 0x0040
+#define ACE_INHERITED_ACE 0x0080
+#define ACE_OWNER 0x1000
+#define ACE_GROUP 0x2000
+#define ACE_EVERYONE 0x4000
+
+#define ACE_ACCESS_ALLOWED_ACE_TYPE 0x0000
+#define ACE_ACCESS_DENIED_ACE_TYPE 0x0001
+#define ACE_SYSTEM_AUDIT_ACE_TYPE 0x0002
+#define ACE_SYSTEM_ALARM_ACE_TYPE 0x0003
+
+#define ACL_AUTO_INHERIT 0x0001
+#define ACL_PROTECTED 0x0002
+#define ACL_DEFAULTED 0x0004
+#define ACL_FLAGS_ALL (ACL_AUTO_INHERIT|ACL_PROTECTED| \
+ ACL_DEFAULTED)
+
+#ifdef _KERNEL
+
+/*
+ * These are only applicable in a CIFS context.
+ */
+#define ACE_ACCESS_ALLOWED_COMPOUND_ACE_TYPE 0x04
+#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05
+#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06
+#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
+#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08
+#define ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE 0x09
+#define ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE 0x0A
+#define ACE_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE 0x0B
+#define ACE_ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE 0x0C
+#define ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE 0x0D
+#define ACE_SYSTEM_ALARM_CALLBACK_ACE_TYPE 0x0E
+#define ACE_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE 0x0F
+#define ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE 0x10
+
+#define ACE_ALL_TYPES 0x001F
+
+typedef struct ace_object {
+ uid_t a_who; /* uid or gid */
+ uint32_t a_access_mask; /* read,write,... */
+ uint16_t a_flags; /* see below */
+ uint16_t a_type; /* allow or deny */
+ uint8_t a_obj_type[16]; /* obj type */
+ uint8_t a_inherit_obj_type[16]; /* inherit obj */
+} ace_object_t;
+
+#endif
+
+#define ACE_ALL_PERMS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
+ ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_READ_NAMED_ATTRS| \
+ ACE_WRITE_NAMED_ATTRS|ACE_EXECUTE|ACE_DELETE_CHILD|ACE_READ_ATTRIBUTES| \
+ ACE_WRITE_ATTRIBUTES|ACE_DELETE|ACE_READ_ACL|ACE_WRITE_ACL| \
+ ACE_WRITE_OWNER|ACE_SYNCHRONIZE)
+
+/*
+ * The following flags are supported by both NFSv4 ACLs and ace_t.
+ */
+#define ACE_NFSV4_SUP_FLAGS (ACE_FILE_INHERIT_ACE | \
+ ACE_DIRECTORY_INHERIT_ACE | \
+ ACE_NO_PROPAGATE_INHERIT_ACE | \
+ ACE_INHERIT_ONLY_ACE | \
+ ACE_IDENTIFIER_GROUP)
+
+#define ACE_TYPE_FLAGS (ACE_OWNER|ACE_GROUP|ACE_EVERYONE| \
+ ACE_IDENTIFIER_GROUP)
+#define ACE_INHERIT_FLAGS (ACE_FILE_INHERIT_ACE| \
+ ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE)
+
+/* cmd args to acl(2) for aclent_t */
+#define GETACL 1
+#define SETACL 2
+#define GETACLCNT 3
+
+/* cmd's to manipulate ace acls. */
+#define ACE_GETACL 4
+#define ACE_SETACL 5
+#define ACE_GETACLCNT 6
+
+/* minimal acl entries from GETACLCNT */
+#define MIN_ACL_ENTRIES 4
+
+#if !defined(_KERNEL)
+
+/* acl check errors */
+#define GRP_ERROR 1
+#define USER_ERROR 2
+#define OTHER_ERROR 3
+#define CLASS_ERROR 4
+#define DUPLICATE_ERROR 5
+#define MISS_ERROR 6
+#define MEM_ERROR 7
+#define ENTRY_ERROR 8
+
+
+/*
+ * similar to ufs_acl.h: changed to char type for user commands (tar, cpio)
+ * Attribute types
+ */
+#define UFSD_FREE ('0') /* Free entry */
+#define UFSD_ACL ('1') /* Access Control Lists */
+#define UFSD_DFACL ('2') /* reserved for future use */
+#define ACE_ACL ('3') /* ace_t style acls */
+
+/*
+ * flag to [f]acl_get()
+ * controls whether a trivial acl should be returned.
+ */
+#define ACL_NO_TRIVIAL 0x2
+
+
+/*
+ * Flags to control acl_totext()
+ */
+
+#define ACL_APPEND_ID 0x1 /* append uid/gid to user/group entries */
+#define ACL_COMPACT_FMT 0x2 /* build ACL in ls -V format */
+#define ACL_NORESOLVE 0x4 /* don't do name service lookups */
+
+/*
+ * Legacy aclcheck errors for aclent_t ACLs
+ */
+#define EACL_GRP_ERROR GRP_ERROR
+#define EACL_USER_ERROR USER_ERROR
+#define EACL_OTHER_ERROR OTHER_ERROR
+#define EACL_CLASS_ERROR CLASS_ERROR
+#define EACL_DUPLICATE_ERROR DUPLICATE_ERROR
+#define EACL_MISS_ERROR MISS_ERROR
+#define EACL_MEM_ERROR MEM_ERROR
+#define EACL_ENTRY_ERROR ENTRY_ERROR
+
+#define EACL_INHERIT_ERROR 9 /* invalid inherit flags */
+#define EACL_FLAGS_ERROR 10 /* unknown flag value */
+#define EACL_PERM_MASK_ERROR 11 /* unknown permission */
+#define EACL_COUNT_ERROR 12 /* invalid acl count */
+
+#define EACL_INVALID_SLOT 13 /* invalid acl slot */
+#define EACL_NO_ACL_ENTRY 14 /* Entry doesn't exist */
+#define EACL_DIFF_TYPE 15 /* acls aren't same type */
+
+#define EACL_INVALID_USER_GROUP 16 /* need user/group name */
+#define EACL_INVALID_STR 17 /* invalid acl string */
+#define EACL_FIELD_NOT_BLANK 18 /* can't have blank field */
+#define EACL_INVALID_ACCESS_TYPE 19 /* invalid access type */
+#define EACL_UNKNOWN_DATA 20 /* Unrecognized data in ACL */
+#define EACL_MISSING_FIELDS 21 /* missing fields in acl */
+
+#define EACL_INHERIT_NOTDIR 22 /* Need dir for inheritance */
+
+extern int aclcheck(aclent_t *, int, int *);
+extern int acltomode(aclent_t *, int, mode_t *);
+extern int aclfrommode(aclent_t *, int, mode_t *);
+extern int aclsort(int, int, aclent_t *);
+extern char *acltotext(aclent_t *, int);
+extern aclent_t *aclfromtext(char *, int *);
+extern void acl_free(acl_t *);
+extern int acl_get(const char *, int, acl_t **);
+extern int facl_get(int, int, acl_t **);
+extern int acl_set(const char *, acl_t *acl);
+extern int facl_set(int, acl_t *acl);
+extern int acl_strip(const char *, uid_t, gid_t, mode_t);
+extern int acl_trivial(const char *);
+extern char *acl_totext(acl_t *, int);
+extern int acl_fromtext(const char *, acl_t **);
+extern int acl_check(acl_t *, int);
+
+#else /* !defined(_KERNEL) */
+
+extern void ksort(caddr_t, int, int, int (*)(void *, void *));
+extern int cmp2acls(void *, void *);
+
+#endif /* !defined(_KERNEL) */
+
+#if defined(__STDC__)
+extern int acl(const char *path, int cmd, int cnt, void *buf);
+extern int facl(int fd, int cmd, int cnt, void *buf);
+#else /* !__STDC__ */
+extern int acl();
+extern int facl();
+#endif /* defined(__STDC__) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_ACL_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/acl_impl.h b/sys/contrib/openzfs/lib/libspl/include/sys/acl_impl.h
new file mode 100644
index 000000000000..717334906415
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/acl_impl.h
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_ACL_IMPL_H
+#define _SYS_ACL_IMPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * acl flags
+ *
+ * ACL_AUTO_INHERIT, ACL_PROTECTED and ACL_DEFAULTED
+ * flags can also be stored in this field.
+ */
+#define ACL_IS_TRIVIAL 0x10000
+#define ACL_IS_DIR 0x20000
+
+typedef enum acl_type {
+ ACLENT_T = 0,
+ ACE_T = 1
+} acl_type_t;
+
+struct acl_info {
+ acl_type_t acl_type; /* style of acl */
+ int acl_cnt; /* number of acl entries */
+ int acl_entry_size; /* sizeof acl entry */
+ int acl_flags; /* special flags about acl */
+ void *acl_aclp; /* the acl */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_ACL_IMPL_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/callb.h b/sys/contrib/openzfs/lib/libspl/include/sys/callb.h
new file mode 100644
index 000000000000..8ffd18788865
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/callb.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_CALLB_H
+#define _SYS_CALLB_H
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h b/sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h
new file mode 100644
index 000000000000..63ff4eb29bc8
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_CMN_ERR_H
+#define _LIBSPL_SYS_CMN_ERR_H
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/cred.h b/sys/contrib/openzfs/lib/libspl/include/sys/cred.h
new file mode 100644
index 000000000000..463b3abfc977
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/cred.h
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_CRED_H
+#define _LIBSPL_SYS_CRED_H
+
+typedef struct cred cred_t;
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/debug.h b/sys/contrib/openzfs/lib/libspl/include/sys/debug.h
new file mode 100644
index 000000000000..af18da94804c
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/debug.h
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_DEBUG_H
+#define _LIBSPL_SYS_DEBUG_H
+
+#include <assert.h>
+
+#ifndef __printflike
+#define __printflike(x, y) __attribute__((__format__(__printf__, x, y)))
+#endif
+
+#ifndef __maybe_unused
+#define __maybe_unused __attribute__((unused))
+#endif
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/dkio.h b/sys/contrib/openzfs/lib/libspl/include/sys/dkio.h
new file mode 100644
index 000000000000..f3c641f669b7
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/dkio.h
@@ -0,0 +1,483 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_DKIO_H
+#define _SYS_DKIO_H
+
+
+
+#include <sys/dklabel.h> /* Needed for NDKMAP define */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Structures and definitions for disk io control commands
+ */
+
+/*
+ * Structures used as data by ioctl calls.
+ */
+
+#define DK_DEVLEN 16 /* device name max length, including */
+ /* unit # & NULL (ie - "xyc1") */
+
+/*
+ * Used for controller info
+ */
+struct dk_cinfo {
+ char dki_cname[DK_DEVLEN]; /* controller name (no unit #) */
+ ushort_t dki_ctype; /* controller type */
+ ushort_t dki_flags; /* flags */
+ ushort_t dki_cnum; /* controller number */
+ uint_t dki_addr; /* controller address */
+ uint_t dki_space; /* controller bus type */
+ uint_t dki_prio; /* interrupt priority */
+ uint_t dki_vec; /* interrupt vector */
+ char dki_dname[DK_DEVLEN]; /* drive name (no unit #) */
+ uint_t dki_unit; /* unit number */
+ ushort_t dki_partition; /* partition number */
+ ushort_t dki_maxtransfer; /* max. transfer size in DEV_BSIZE */
+};
+
+/*
+ * Controller types
+ */
+#define DKC_UNKNOWN 0
+#define DKC_CDROM 1 /* CD-ROM, SCSI or otherwise */
+#define DKC_WDC2880 2
+#define DKC_XXX_0 3 /* unassigned */
+#define DKC_XXX_1 4 /* unassigned */
+#define DKC_DSD5215 5
+#define DKC_ACB4000 7
+#define DKC_MD21 8
+#define DKC_XXX_2 9 /* unassigned */
+#define DKC_NCRFLOPPY 10
+#define DKC_SMSFLOPPY 12
+#define DKC_SCSI_CCS 13 /* SCSI CCS compatible */
+#define DKC_INTEL82072 14 /* native floppy chip */
+#define DKC_MD 16 /* meta-disk (virtual-disk) driver */
+#define DKC_INTEL82077 19 /* 82077 floppy disk controller */
+#define DKC_DIRECT 20 /* Intel direct attached device i.e. IDE */
+#define DKC_PCMCIA_MEM 21 /* PCMCIA memory disk-like type */
+#define DKC_PCMCIA_ATA 22 /* PCMCIA AT Attached type */
+#define DKC_VBD 23 /* virtual block device */
+
+/*
+ * Sun reserves up through 1023
+ */
+
+#define DKC_CUSTOMER_BASE 1024
+
+/*
+ * Flags
+ */
+#define DKI_BAD144 0x01 /* use DEC std 144 bad sector fwding */
+#define DKI_MAPTRK 0x02 /* controller does track mapping */
+#define DKI_FMTTRK 0x04 /* formats only full track at a time */
+#define DKI_FMTVOL 0x08 /* formats only full volume at a time */
+#define DKI_FMTCYL 0x10 /* formats only full cylinders at a time */
+#define DKI_HEXUNIT 0x20 /* unit number is printed as 3 hex digits */
+#define DKI_PCMCIA_PFD 0x40 /* PCMCIA pseudo-floppy memory card */
+
+/*
+ * Used for all partitions
+ */
+struct dk_allmap {
+ struct dk_map dka_map[NDKMAP];
+};
+
+#if defined(_SYSCALL32)
+struct dk_allmap32 {
+ struct dk_map32 dka_map[NDKMAP];
+};
+#endif /* _SYSCALL32 */
+
+/*
+ * Definition of a disk's geometry
+ */
+struct dk_geom {
+ unsigned short dkg_ncyl; /* # of data cylinders */
+ unsigned short dkg_acyl; /* # of alternate cylinders */
+ unsigned short dkg_bcyl; /* cyl offset (for fixed head area) */
+ unsigned short dkg_nhead; /* # of heads */
+ unsigned short dkg_obs1; /* obsolete */
+ unsigned short dkg_nsect; /* # of data sectors per track */
+ unsigned short dkg_intrlv; /* interleave factor */
+ unsigned short dkg_obs2; /* obsolete */
+ unsigned short dkg_obs3; /* obsolete */
+ unsigned short dkg_apc; /* alternates per cyl (SCSI only) */
+ unsigned short dkg_rpm; /* revolutions per minute */
+ unsigned short dkg_pcyl; /* # of physical cylinders */
+ unsigned short dkg_write_reinstruct; /* # sectors to skip, writes */
+ unsigned short dkg_read_reinstruct; /* # sectors to skip, reads */
+ unsigned short dkg_extra[7]; /* for compatible expansion */
+};
+
+/*
+ * These defines are for historic compatibility with old drivers.
+ */
+#define dkg_bhead dkg_obs1 /* used to be head offset */
+#define dkg_gap1 dkg_obs2 /* used to be gap1 */
+#define dkg_gap2 dkg_obs3 /* used to be gap2 */
+
+/*
+ * Disk io control commands
+ * Warning: some other ioctls with the DIOC prefix exist elsewhere.
+ * The Generic DKIOC numbers are from 0 - 50.
+ * The Floppy Driver uses 51 - 100.
+ * The Hard Disk (except SCSI) 101 - 106. (these are obsolete)
+ * The CDROM Driver 151 - 200.
+ * The USCSI ioctl 201 - 250.
+ */
+#define DKIOC (0x04 << 8)
+
+/*
+ * The following ioctls are generic in nature and need to be
+ * supported as appropriate by all disk drivers
+ */
+#define DKIOCGGEOM (DKIOC|1) /* Get geometry */
+#define DKIOCINFO (DKIOC|3) /* Get info */
+#define DKIOCEJECT (DKIOC|6) /* Generic 'eject' */
+#define DKIOCGVTOC (DKIOC|11) /* Get VTOC */
+#define DKIOCSVTOC (DKIOC|12) /* Set VTOC & Write to Disk */
+
+/*
+ * Disk Cache Controls. These ioctls should be supported by
+ * all disk drivers.
+ *
+ * DKIOCFLUSHWRITECACHE when used from user-mode ignores the ioctl
+ * argument, but it should be passed as NULL to allow for future
+ * reinterpretation. From user-mode, this ioctl request is synchronous.
+ *
+ * When invoked from within the kernel, the arg can be NULL to indicate
+ * a synchronous request or can be the address of a struct dk_callback
+ * to request an asynchronous callback when the flush request is complete.
+ * In this case, the flag to the ioctl must include FKIOCTL and the
+ * dkc_callback field of the pointed to struct must be non-null or the
+ * request is made synchronously.
+ *
+ * In the callback case: if the ioctl returns 0, a callback WILL be performed.
+ * If the ioctl returns non-zero, a callback will NOT be performed.
+ * NOTE: In some cases, the callback may be done BEFORE the ioctl call
+ * returns. The caller's locking strategy should be prepared for this case.
+ */
+#define DKIOCFLUSHWRITECACHE (DKIOC|34) /* flush cache to phys medium */
+
+struct dk_callback {
+ void (*dkc_callback)(void *dkc_cookie, int error);
+ void *dkc_cookie;
+ int dkc_flag;
+};
+
+/* bit flag definitions for dkc_flag */
+#define FLUSH_VOLATILE 0x1 /* Bit 0: if set, only flush */
+ /* volatile cache; otherwise, flush */
+ /* volatile and non-volatile cache */
+
+#define DKIOCGETWCE (DKIOC|36) /* Get current write cache */
+ /* enablement status */
+#define DKIOCSETWCE (DKIOC|37) /* Enable/Disable write cache */
+
+/*
+ * The following ioctls are used by Sun drivers to communicate
+ * with their associated format routines. Support of these ioctls
+ * is not required of foreign drivers
+ */
+#define DKIOCSGEOM (DKIOC|2) /* Set geometry */
+#define DKIOCSAPART (DKIOC|4) /* Set all partitions */
+#define DKIOCGAPART (DKIOC|5) /* Get all partitions */
+#define DKIOCG_PHYGEOM (DKIOC|32) /* get physical geometry */
+#define DKIOCG_VIRTGEOM (DKIOC|33) /* get virtual geometry */
+
+/*
+ * The following ioctl's are removable media support
+ */
+#define DKIOCLOCK (DKIOC|7) /* Generic 'lock' */
+#define DKIOCUNLOCK (DKIOC|8) /* Generic 'unlock' */
+#define DKIOCSTATE (DKIOC|13) /* Inquire insert/eject state */
+#define DKIOCREMOVABLE (DKIOC|16) /* is media removable */
+
+
+/*
+ * ioctl for hotpluggable devices
+ */
+#define DKIOCHOTPLUGGABLE (DKIOC|35) /* is hotpluggable */
+
+/*
+ * Ioctl to force driver to re-read the alternate partition and rebuild
+ * the internal defect map.
+ */
+#define DKIOCADDBAD (DKIOC|20) /* Re-read the alternate map (IDE) */
+#define DKIOCGETDEF (DKIOC|21) /* read defect list (IDE) */
+
+/*
+ * Used by applications to get disk defect information from IDE
+ * drives.
+ */
+#ifdef _SYSCALL32
+struct defect_header32 {
+ int head;
+ caddr32_t buffer;
+};
+#endif /* _SYSCALL32 */
+
+struct defect_header {
+ int head;
+ caddr_t buffer;
+};
+
+#define DKIOCPARTINFO (DKIOC|22) /* Get partition or slice parameters */
+
+/*
+ * Used by applications to get partition or slice information
+ */
+#ifdef _SYSCALL32
+struct part_info32 {
+ uint32_t p_start;
+ int p_length;
+};
+#endif /* _SYSCALL32 */
+
+struct part_info {
+ uint64_t p_start;
+ int p_length;
+};
+
+/* The following ioctls are for Optical Memory Device */
+#define DKIOC_EBP_ENABLE (DKIOC|40) /* enable by pass erase on write */
+#define DKIOC_EBP_DISABLE (DKIOC|41) /* disable by pass erase on write */
+
+/*
+ * This state enum is the argument passed to the DKIOCSTATE ioctl.
+ */
+enum dkio_state { DKIO_NONE, DKIO_EJECTED, DKIO_INSERTED, DKIO_DEV_GONE };
+
+#define DKIOCGMEDIAINFO (DKIOC|42) /* get information about the media */
+
+/*
+ * ioctls to read/write mboot info.
+ */
+#define DKIOCGMBOOT (DKIOC|43) /* get mboot info */
+#define DKIOCSMBOOT (DKIOC|44) /* set mboot info */
+
+/*
+ * ioctl to get the device temperature.
+ */
+#define DKIOCGTEMPERATURE (DKIOC|45) /* get temperature */
+
+/*
+ * Used for providing the temperature.
+ */
+
+struct dk_temperature {
+ uint_t dkt_flags; /* Flags */
+ short dkt_cur_temp; /* Current disk temperature */
+ short dkt_ref_temp; /* reference disk temperature */
+};
+
+#define DKT_BYPASS_PM 0x1
+#define DKT_INVALID_TEMP 0xFFFF
+
+
+/*
+ * Used for Media info or the current profile info
+ */
+struct dk_minfo {
+ uint_t dki_media_type; /* Media type or profile info */
+ uint_t dki_lbsize; /* Logical blocksize of media */
+ diskaddr_t dki_capacity; /* Capacity as # of dki_lbsize blks */
+};
+
+/*
+ * Media types or profiles known
+ */
+#define DK_UNKNOWN 0x00 /* Media inserted - type unknown */
+
+
+/*
+ * SFF 8090 Specification Version 3, media types 0x01 - 0xfffe are retained to
+ * maintain compatibility with SFF8090. The following define the
+ * optical media type.
+ */
+#define DK_REMOVABLE_DISK 0x02 /* Removable Disk */
+#define DK_MO_ERASABLE 0x03 /* MO Erasable */
+#define DK_MO_WRITEONCE 0x04 /* MO Write once */
+#define DK_AS_MO 0x05 /* AS MO */
+#define DK_CDROM 0x08 /* CDROM */
+#define DK_CDR 0x09 /* CD-R */
+#define DK_CDRW 0x0A /* CD-RW */
+#define DK_DVDROM 0x10 /* DVD-ROM */
+#define DK_DVDR 0x11 /* DVD-R */
+#define DK_DVDRAM 0x12 /* DVD_RAM or DVD-RW */
+
+/*
+ * Media types for other rewritable magnetic media
+ */
+#define DK_FIXED_DISK 0x10001 /* Fixed disk SCSI or otherwise */
+#define DK_FLOPPY 0x10002 /* Floppy media */
+#define DK_ZIP 0x10003 /* IOMEGA ZIP media */
+#define DK_JAZ 0x10004 /* IOMEGA JAZ media */
+
+#define DKIOCSETEFI (DKIOC|17) /* Set EFI info */
+#define DKIOCGETEFI (DKIOC|18) /* Get EFI info */
+
+#define DKIOCPARTITION (DKIOC|9) /* Get partition info */
+
+/*
+ * Ioctls to get/set volume capabilities related to Logical Volume Managers.
+ * They include the ability to get/set capabilities and to issue a read to a
+ * specific underlying device of a replicated device.
+ */
+
+#define DKIOCGETVOLCAP (DKIOC | 25) /* Get volume capabilities */
+#define DKIOCSETVOLCAP (DKIOC | 26) /* Set volume capabilities */
+#define DKIOCDMR (DKIOC | 27) /* Issue a directed read */
+
+typedef uint_t volcapinfo_t;
+
+typedef uint_t volcapset_t;
+
+#define DKV_ABR_CAP 0x00000001 /* Support Appl.Based Recovery */
+#define DKV_DMR_CAP 0x00000002 /* Support Directed Mirror Read */
+
+typedef struct volcap {
+ volcapinfo_t vc_info; /* Capabilities available */
+ volcapset_t vc_set; /* Capabilities set */
+} volcap_t;
+
+#define VOL_SIDENAME 256
+
+typedef struct vol_directed_rd {
+ int vdr_flags;
+ offset_t vdr_offset;
+ size_t vdr_nbytes;
+ size_t vdr_bytesread;
+ void *vdr_data;
+ int vdr_side;
+ char vdr_side_name[VOL_SIDENAME];
+} vol_directed_rd_t;
+
+#define DKV_SIDE_INIT (-1)
+#define DKV_DMR_NEXT_SIDE 0x00000001
+#define DKV_DMR_DONE 0x00000002
+#define DKV_DMR_ERROR 0x00000004
+#define DKV_DMR_SUCCESS 0x00000008
+#define DKV_DMR_SHORT 0x00000010
+
+#ifdef _MULTI_DATAMODEL
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack(4)
+#endif
+typedef struct vol_directed_rd32 {
+ int32_t vdr_flags;
+ offset_t vdr_offset; /* 64-bit element on 32-bit alignment */
+ size32_t vdr_nbytes;
+ size32_t vdr_bytesread;
+ caddr32_t vdr_data;
+ int32_t vdr_side;
+ char vdr_side_name[VOL_SIDENAME];
+} vol_directed_rd32_t;
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack()
+#endif
+#endif /* _MULTI_DATAMODEL */
+
+/*
+ * The ioctl is used to fetch disk's device type, vendor ID,
+ * model number/product ID, firmware revision and serial number together.
+ *
+ * Currently there are two device types - DKD_ATA_TYPE which means the
+ * disk is driven by cmdk/ata or dad/uata driver, and DKD_SCSI_TYPE
+ * which means the disk is driven by sd/scsi hba driver.
+ */
+#define DKIOC_GETDISKID (DKIOC|46)
+
+/* These two labels are for dkd_dtype of dk_disk_id_t */
+#define DKD_ATA_TYPE 0x01 /* ATA disk or legacy mode SATA disk */
+#define DKD_SCSI_TYPE 0x02 /* SCSI disk or native mode SATA disk */
+
+#define DKD_ATA_MODEL 40 /* model number length */
+#define DKD_ATA_FWVER 8 /* firmware revision length */
+#define DKD_ATA_SERIAL 20 /* serial number length */
+
+#define DKD_SCSI_VENDOR 8 /* vendor ID length */
+#define DKD_SCSI_PRODUCT 16 /* product ID length */
+#define DKD_SCSI_REVLEVEL 4 /* revision level length */
+#define DKD_SCSI_SERIAL 12 /* serial number length */
+
+/*
+ * The argument type for DKIOC_GETDISKID ioctl.
+ */
+typedef struct dk_disk_id {
+ uint_t dkd_dtype;
+ union {
+ struct {
+ char dkd_amodel[DKD_ATA_MODEL]; /* 40 bytes */
+ char dkd_afwver[DKD_ATA_FWVER]; /* 8 bytes */
+ char dkd_aserial[DKD_ATA_SERIAL]; /* 20 bytes */
+ } ata_disk_id;
+ struct {
+ char dkd_svendor[DKD_SCSI_VENDOR]; /* 8 bytes */
+ char dkd_sproduct[DKD_SCSI_PRODUCT]; /* 16 bytes */
+ char dkd_sfwver[DKD_SCSI_REVLEVEL]; /* 4 bytes */
+ char dkd_sserial[DKD_SCSI_SERIAL]; /* 12 bytes */
+ } scsi_disk_id;
+ } disk_id;
+} dk_disk_id_t;
+
+/*
+ * The ioctl is used to update the firmware of device.
+ */
+#define DKIOC_UPDATEFW (DKIOC|47)
+
+/* The argument type for DKIOC_UPDATEFW ioctl */
+typedef struct dk_updatefw {
+ caddr_t dku_ptrbuf; /* pointer to firmware buf */
+ uint_t dku_size; /* firmware buf length */
+ uint8_t dku_type; /* firmware update type */
+} dk_updatefw_t;
+
+#ifdef _SYSCALL32
+typedef struct dk_updatefw_32 {
+ caddr32_t dku_ptrbuf; /* pointer to firmware buf */
+ uint_t dku_size; /* firmware buf length */
+ uint8_t dku_type; /* firmware update type */
+} dk_updatefw_32_t;
+#endif /* _SYSCALL32 */
+
+/*
+ * firmware update type - temporary or permanent use
+ */
+#define FW_TYPE_TEMP 0x0 /* temporary use */
+#define FW_TYPE_PERM 0x1 /* permanent use */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_DKIO_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/dklabel.h b/sys/contrib/openzfs/lib/libspl/include/sys/dklabel.h
new file mode 100644
index 000000000000..95faf2bb4ab3
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/dklabel.h
@@ -0,0 +1,268 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1990-2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_DKLABEL_H
+#define _SYS_DKLABEL_H
+
+
+
+#include <sys/isa_defs.h>
+#include <sys/types32.h>
+#include <sys/isa_defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Miscellaneous defines
+ */
+#define DKL_MAGIC 0xDABE /* magic number */
+#define FKL_MAGIC 0xff /* magic number for DOS floppies */
+
+#if defined(_SUNOS_VTOC_16)
+#define NDKMAP 16 /* # of logical partitions */
+#define DK_LABEL_LOC 1 /* location of disk label */
+#elif defined(_SUNOS_VTOC_8)
+#define NDKMAP 8 /* # of logical partitions */
+#define DK_LABEL_LOC 0 /* location of disk label */
+#else
+#error "No VTOC format defined."
+#endif
+
+#define LEN_DKL_ASCII 128 /* length of dkl_asciilabel */
+#define LEN_DKL_VVOL 8 /* length of v_volume */
+#define DK_LABEL_SIZE 512 /* size of disk label */
+#define DK_MAX_BLOCKS 0x7fffffff /* max # of blocks handled */
+
+/*
+ * Reserve two cylinders on SCSI disks.
+ * One is for the backup disk label and the other is for the deviceid.
+ *
+ * IPI disks only reserve one cylinder, but they will go away soon.
+ * CDROMs do not reserve any cylinders.
+ */
+#define DK_ACYL 2
+
+/*
+ * Format of a Sun disk label.
+ * Resides in cylinder 0, head 0, sector 0.
+ *
+ * sizeof (struct dk_label) should be 512 (the current sector size),
+ * but should the sector size increase, this structure should remain
+ * at the beginning of the sector.
+ */
+
+/*
+ * partition headers: section 1
+ * Returned in struct dk_allmap by ioctl DKIOC[SG]APART (dkio(7I))
+ */
+struct dk_map {
+ uint64_t dkl_cylno; /* starting cylinder */
+ uint64_t dkl_nblk; /* number of blocks; if == 0, */
+ /* partition is undefined */
+};
+
+/*
+ * partition headers: section 1
+ * Fixed size for on-disk dk_label
+ */
+struct dk_map32 {
+ daddr32_t dkl_cylno; /* starting cylinder */
+ daddr32_t dkl_nblk; /* number of blocks; if == 0, */
+ /* partition is undefined */
+};
+
+/*
+ * partition headers: section 2,
+ * brought over from AT&T SVr4 vtoc structure.
+ */
+struct dk_map2 {
+ uint16_t p_tag; /* ID tag of partition */
+ uint16_t p_flag; /* permission flag */
+};
+
+struct dkl_partition {
+ uint16_t p_tag; /* ID tag of partition */
+ uint16_t p_flag; /* permission flags */
+ daddr32_t p_start; /* start sector no of partition */
+ int32_t p_size; /* # of blocks in partition */
+};
+
+
+/*
+ * VTOC inclusions from AT&T SVr4
+ * Fixed sized types for on-disk VTOC
+ */
+
+struct dk_vtoc {
+#if defined(_SUNOS_VTOC_16)
+ uint32_t v_bootinfo[3]; /* info for mboot (unsupported) */
+ uint32_t v_sanity; /* to verify vtoc sanity */
+ uint32_t v_version; /* layout version */
+ char v_volume[LEN_DKL_VVOL]; /* volume name */
+ uint16_t v_sectorsz; /* sector size in bytes */
+ uint16_t v_nparts; /* number of partitions */
+ uint32_t v_reserved[10]; /* free space */
+ struct dkl_partition v_part[NDKMAP]; /* partition headers */
+ time32_t timestamp[NDKMAP]; /* partition timestamp (unsupported) */
+ char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */
+#elif defined(_SUNOS_VTOC_8)
+ uint32_t v_version; /* layout version */
+ char v_volume[LEN_DKL_VVOL]; /* volume name */
+ uint16_t v_nparts; /* number of partitions */
+ struct dk_map2 v_part[NDKMAP]; /* partition hdrs, sec 2 */
+ uint32_t v_bootinfo[3]; /* info needed by mboot */
+ uint32_t v_sanity; /* to verify vtoc sanity */
+ uint32_t v_reserved[10]; /* free space */
+ time32_t v_timestamp[NDKMAP]; /* partition timestamp */
+#else
+#error "No VTOC format defined."
+#endif
+};
+
+/*
+ * define the amount of disk label padding needed to make
+ * the entire structure occupy 512 bytes.
+ */
+#if defined(_SUNOS_VTOC_16)
+#define LEN_DKL_PAD (DK_LABEL_SIZE - \
+ ((sizeof (struct dk_vtoc) + \
+ (4 * sizeof (uint32_t)) + \
+ (12 * sizeof (uint16_t)) + \
+ (2 * (sizeof (uint16_t))))))
+#elif defined(_SUNOS_VTOC_8)
+#define LEN_DKL_PAD (DK_LABEL_SIZE \
+ - ((LEN_DKL_ASCII) + \
+ (sizeof (struct dk_vtoc)) + \
+ (sizeof (struct dk_map32) * NDKMAP) + \
+ (14 * (sizeof (uint16_t))) + \
+ (2 * (sizeof (uint16_t)))))
+#else
+#error "No VTOC format defined."
+#endif
+
+
+struct dk_label {
+#if defined(_SUNOS_VTOC_16)
+ struct dk_vtoc dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */
+ uint32_t dkl_pcyl; /* # of physical cylinders */
+ uint32_t dkl_ncyl; /* # of data cylinders */
+ uint16_t dkl_acyl; /* # of alternate cylinders */
+ uint16_t dkl_bcyl; /* cyl offset (for fixed head area) */
+ uint32_t dkl_nhead; /* # of heads */
+ uint32_t dkl_nsect; /* # of data sectors per track */
+ uint16_t dkl_intrlv; /* interleave factor */
+ uint16_t dkl_skew; /* skew factor */
+ uint16_t dkl_apc; /* alternates per cyl (SCSI only) */
+ uint16_t dkl_rpm; /* revolutions per minute */
+ uint16_t dkl_write_reinstruct; /* # sectors to skip, writes */
+ uint16_t dkl_read_reinstruct; /* # sectors to skip, reads */
+ uint16_t dkl_extra[4]; /* for compatible expansion */
+ char dkl_pad[LEN_DKL_PAD]; /* unused part of 512 bytes */
+#elif defined(_SUNOS_VTOC_8)
+ char dkl_asciilabel[LEN_DKL_ASCII]; /* for compatibility */
+ struct dk_vtoc dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */
+ uint16_t dkl_write_reinstruct; /* # sectors to skip, writes */
+ uint16_t dkl_read_reinstruct; /* # sectors to skip, reads */
+ char dkl_pad[LEN_DKL_PAD]; /* unused part of 512 bytes */
+ uint16_t dkl_rpm; /* rotations per minute */
+ uint16_t dkl_pcyl; /* # physical cylinders */
+ uint16_t dkl_apc; /* alternates per cylinder */
+ uint16_t dkl_obs1; /* obsolete */
+ uint16_t dkl_obs2; /* obsolete */
+ uint16_t dkl_intrlv; /* interleave factor */
+ uint16_t dkl_ncyl; /* # of data cylinders */
+ uint16_t dkl_acyl; /* # of alternate cylinders */
+ uint16_t dkl_nhead; /* # of heads in this partition */
+ uint16_t dkl_nsect; /* # of 512 byte sectors per track */
+ uint16_t dkl_obs3; /* obsolete */
+ uint16_t dkl_obs4; /* obsolete */
+ struct dk_map32 dkl_map[NDKMAP]; /* logical partition headers */
+#else
+#error "No VTOC format defined."
+#endif
+ uint16_t dkl_magic; /* identifies this label format */
+ uint16_t dkl_cksum; /* xor checksum of sector */
+};
+
+#if defined(_SUNOS_VTOC_16)
+#define dkl_asciilabel dkl_vtoc.v_asciilabel
+#define v_timestamp timestamp
+
+#elif defined(_SUNOS_VTOC_8)
+
+/*
+ * These defines are for historic compatibility with old drivers.
+ */
+#define dkl_gap1 dkl_obs1 /* used to be gap1 */
+#define dkl_gap2 dkl_obs2 /* used to be gap2 */
+#define dkl_bhead dkl_obs3 /* used to be label head offset */
+#define dkl_ppart dkl_obs4 /* used to by physical partition */
+#else
+#error "No VTOC format defined."
+#endif
+
+struct fk_label { /* DOS floppy label */
+ uchar_t fkl_type;
+ uchar_t fkl_magich;
+ uchar_t fkl_magicl;
+ uchar_t filler;
+};
+
+/*
+ * Layout of stored fabricated device id (on-disk)
+ */
+#define DK_DEVID_BLKSIZE (512)
+#define DK_DEVID_SIZE (DK_DEVID_BLKSIZE - ((sizeof (uchar_t) * 7)))
+#define DK_DEVID_REV_MSB (0)
+#define DK_DEVID_REV_LSB (1)
+
+struct dk_devid {
+ uchar_t dkd_rev_hi; /* revision (MSB) */
+ uchar_t dkd_rev_lo; /* revision (LSB) */
+ uchar_t dkd_flags; /* flags (not used yet) */
+ uchar_t dkd_devid[DK_DEVID_SIZE]; /* devid stored here */
+ uchar_t dkd_checksum3; /* checksum (MSB) */
+ uchar_t dkd_checksum2;
+ uchar_t dkd_checksum1;
+ uchar_t dkd_checksum0; /* checksum (LSB) */
+};
+
+#define DKD_GETCHKSUM(dkd) ((dkd)->dkd_checksum3 << 24) + \
+ ((dkd)->dkd_checksum2 << 16) + \
+ ((dkd)->dkd_checksum1 << 8) + \
+ ((dkd)->dkd_checksum0)
+
+#define DKD_FORMCHKSUM(c, dkd) (dkd)->dkd_checksum3 = hibyte(hiword((c))); \
+ (dkd)->dkd_checksum2 = lobyte(hiword((c))); \
+ (dkd)->dkd_checksum1 = hibyte(loword((c))); \
+ (dkd)->dkd_checksum0 = lobyte(loword((c)));
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_DKLABEL_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/dktp/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/sys/dktp/Makefile.am
new file mode 100644
index 000000000000..4ad3695d8abc
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/dktp/Makefile.am
@@ -0,0 +1,4 @@
+libspldir = $(includedir)/libspl/sys/dktp
+libspl_HEADERS = \
+ fdisk.h
+
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/dktp/fdisk.h b/sys/contrib/openzfs/lib/libspl/include/sys/dktp/fdisk.h
new file mode 100644
index 000000000000..e90135f362e6
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/dktp/fdisk.h
@@ -0,0 +1,173 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/* Copyright (c) 1984, 1986, 1987, 1988 AT&T */
+/* All Rights Reserved */
+
+
+#ifndef _SYS_DKTP_FDISK_H
+#define _SYS_DKTP_FDISK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * fdisk.h
+ * This file defines the structure of physical disk sector 0 for use on
+ * AT386 systems. The format of this sector is constrained by the ROM
+ * BIOS and MS-DOS conventions.
+ * Note that this block does not define the partitions used by the unix
+ * driver. The unix partitions are obtained from the VTOC.
+ */
+
+/*
+ * the MAX values are the maximum usable values for BIOS chs values
+ * The MAX_CYL value of 1022 is the maximum usable value
+ * the value of 1023 is a fence value,
+ * indicating no CHS geometry exists for the corresponding LBA value.
+ * HEAD range [ 0 .. MAX_HEAD ], so number of heads is (MAX_HEAD + 1)
+ * SECT range [ 1 .. MAX_SECT ], so number of sectors is (MAX_SECT)
+ */
+#define MAX_SECT (63)
+#define MAX_CYL (1022)
+#define MAX_HEAD (254)
+
+/*
+ * BOOTSZ was reduced from 446 to 440 bytes to NOT overwrite the Windows
+ * Vista DISKID. Otherwise Vista won't boot from Solaris GRUB in a dual-boot
+ * setup.
+ * The actual size of mboot code is 425 bytes while that of GRUB stage1 is
+ * 423 bytes. So this changes does not harm them.
+ */
+#define BOOTSZ 440 /* size of boot code in master boot block */
+#define FD_NUMPART 4 /* number of 'partitions' in fdisk table */
+#define MBB_MAGIC 0xAA55 /* magic number for mboot.signature */
+#define DEFAULT_INTLV 4 /* default interleave for testing tracks */
+#define MINPSIZE 4 /* minimum number of cylinders in a partition */
+#define TSTPAT 0xE5 /* test pattern for verifying disk */
+
+/*
+ * structure to hold the fdisk partition table
+ */
+struct ipart {
+ unsigned char bootid; /* bootable or not */
+ unsigned char beghead; /* beginning head, sector, cylinder */
+ unsigned char begsect; /* begcyl is a 10-bit number. High 2 bits */
+ unsigned char begcyl; /* are in begsect. */
+ unsigned char systid; /* OS type */
+ unsigned char endhead; /* ending head, sector, cylinder */
+ unsigned char endsect; /* endcyl is a 10-bit number. High 2 bits */
+ unsigned char endcyl; /* are in endsect. */
+ uint32_t relsect; /* first sector relative to start of disk */
+ uint32_t numsect; /* number of sectors in partition */
+};
+/*
+ * Values for bootid.
+ */
+#define NOTACTIVE 0
+#define ACTIVE 128
+/*
+ * Values for systid.
+ */
+#define UNUSED 0 /* Empty Partition */
+#define DOSOS12 1 /* DOS partition, 12-bit FAT */
+#define PCIXOS 2 /* PC/IX partition */
+#define DOSOS16 4 /* DOS partition, 16-bit FAT */
+#define EXTDOS 5 /* EXT-DOS partition */
+#define DOSHUGE 6 /* Huge DOS partition > 32MB */
+#define FDISK_IFS 7 /* Installable File System (IFS): HPFS & NTFS */
+#define FDISK_AIXBOOT 8 /* AIX Boot */
+#define FDISK_AIXDATA 9 /* AIX Data */
+#define FDISK_OS2BOOT 10 /* OS/2 Boot Manager */
+#define FDISK_WINDOWS 11 /* Windows 95 FAT32 (up to 2047GB) */
+#define FDISK_EXT_WIN 12 /* Windows 95 FAT32 (extended-INT13) */
+#define FDISK_FAT95 14 /* DOS 16-bit FAT, LBA-mapped */
+#define FDISK_EXTLBA 15 /* Extended partition, LBA-mapped */
+#define DIAGPART 18 /* Diagnostic boot partition (OS independent) */
+#define FDISK_LINUX 65 /* Linux */
+#define FDISK_LINUXDSWAP 66 /* Linux swap (sharing disk w/ DRDOS) */
+#define FDISK_LINUXDNAT 67 /* Linux native (sharing disk with DRDOS) */
+#define FDISK_CPM 82 /* CP/M */
+#define DOSDATA 86 /* DOS data partition */
+#define OTHEROS 98 /* part. type for appl. (DB?) needs */
+ /* raw partition. ID was 0 but conflicted */
+ /* with DOS 3.3 fdisk */
+#define UNIXOS 99 /* UNIX V.x partition */
+#define FDISK_NOVELL2 100 /* Novell Netware 286 */
+#define FDISK_NOVELL3 101 /* Novell Netware 3.x and later */
+#define FDISK_QNX4 119 /* QNX 4.x */
+#define FDISK_QNX42 120 /* QNX 4.x 2nd part */
+#define FDISK_QNX43 121 /* QNX 4.x 3rd part */
+#define SUNIXOS 130 /* Solaris UNIX partition */
+#define FDISK_LINUXNAT 131 /* Linux native */
+#define FDISK_NTFSVOL1 134 /* NTFS volume set 1 */
+#define FDISK_NTFSVOL2 135 /* NTFS volume set 2 */
+#define FDISK_BSD 165 /* BSD/386, 386BSD, NetBSD, FreeBSD, OpenBSD */
+#define FDISK_NEXTSTEP 167 /* NeXTSTEP */
+#define FDISK_BSDIFS 183 /* BSDI file system */
+#define FDISK_BSDISWAP 184 /* BSDI swap */
+#define X86BOOT 190 /* x86 Solaris boot partition */
+#define SUNIXOS2 191 /* Solaris UNIX partition */
+#define EFI_PMBR 238 /* EFI PMBR */
+#define EFI_FS 239 /* EFI File System (System Partition) */
+#define MAXDOS 65535L /* max size (sectors) for DOS partition */
+
+/*
+ * structure to hold master boot block in physical sector 0 of the disk.
+ * Note that partitions stuff can't be directly included in the structure
+ * because of lameo '386 compiler alignment design.
+ * Alignment issues also force us to have 2 16bit entities for a single
+ * 32bit win_volserno. It is not used anywhere anyway.
+ */
+
+struct mboot { /* master boot block */
+ char bootinst[BOOTSZ];
+ uint16_t win_volserno_lo;
+ uint16_t win_volserno_hi;
+ uint16_t reserved;
+ char parts[FD_NUMPART * sizeof (struct ipart)];
+ ushort_t signature;
+};
+
+#if defined(__i386) || defined(__amd64)
+
+/* Byte offset of the start of the partition table within the sector */
+#define FDISK_PART_TABLE_START 446
+
+/* Maximum number of valid partitions assumed as 32 */
+#define MAX_EXT_PARTS 32
+
+#else
+
+#define MAX_EXT_PARTS 0
+
+#endif /* if defined(__i386) || defined(__amd64) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_DKTP_FDISK_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h b/sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h
new file mode 100644
index 000000000000..1a68b75f0cdc
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_FEATURE_TESTS_H
+#define _SYS_FEATURE_TESTS_H
+
+#define __NORETURN __attribute__((__noreturn__))
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/int_limits.h b/sys/contrib/openzfs/lib/libspl/include/sys/int_limits.h
new file mode 100644
index 000000000000..7af68cdb2998
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/int_limits.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_INT_LIMITS_H
+#define _LIBSPL_SYS_INT_LIMITS_H
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/int_types.h b/sys/contrib/openzfs/lib/libspl/include/sys/int_types.h
new file mode 100644
index 000000000000..51e9e0285490
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/int_types.h
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SOL_SYS_INT_TYPES_H
+#define _SOL_SYS_INT_TYPES_H
+
+#include <inttypes.h>
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h b/sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h
new file mode 100644
index 000000000000..d7d063985316
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SOL_SYS_INTTYPES_H
+#define _SOL_SYS_INTTYPES_H
+
+#include <inttypes.h>
+
+#define _INT64_TYPE
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h b/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h
new file mode 100644
index 000000000000..8c0932f57654
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h
@@ -0,0 +1,264 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_ISA_DEFS_H
+#define _SYS_ISA_DEFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* x86_64 arch specific defines */
+#if defined(__x86_64) || defined(__x86_64__)
+
+#if !defined(__x86_64)
+#define __x86_64
+#endif
+
+#if !defined(__amd64)
+#define __amd64
+#endif
+
+#if !defined(__x86)
+#define __x86
+#endif
+
+#if defined(_ILP32)
+/* x32-specific defines; careful to *not* define _LP64 here */
+#else
+#if !defined(_LP64)
+#define _LP64
+#endif
+#endif
+
+#if !defined(_ZFS_LITTLE_ENDIAN)
+#define _ZFS_LITTLE_ENDIAN
+#endif
+
+#define _SUNOS_VTOC_16
+#define HAVE_EFFICIENT_UNALIGNED_ACCESS
+
+/* i386 arch specific defines */
+#elif defined(__i386) || defined(__i386__)
+
+#if !defined(__i386)
+#define __i386
+#endif
+
+#if !defined(__x86)
+#define __x86
+#endif
+
+#if !defined(_ILP32)
+#define _ILP32
+#endif
+
+#if !defined(_ZFS_LITTLE_ENDIAN)
+#define _ZFS_LITTLE_ENDIAN
+#endif
+
+#define _SUNOS_VTOC_16
+#define HAVE_EFFICIENT_UNALIGNED_ACCESS
+
+/* powerpc arch specific defines */
+#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__)
+
+#if !defined(__powerpc)
+#define __powerpc
+#endif
+
+#if !defined(__powerpc__)
+#define __powerpc__
+#endif
+
+#if defined(__powerpc64__)
+#if !defined(_LP64)
+#define _LP64
+#endif
+#else
+#if !defined(_ILP32)
+#define _ILP32
+#endif
+#endif
+
+#define _SUNOS_VTOC_16
+#define HAVE_EFFICIENT_UNALIGNED_ACCESS
+
+#if defined(__BYTE_ORDER)
+#if defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
+#define _ZFS_BIG_ENDIAN
+#elif defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
+#define _ZFS_LITTLE_ENDIAN
+#endif
+#elif defined(_BYTE_ORDER)
+#if defined(_BIG_ENDIAN) && _BYTE_ORDER == _BIG_ENDIAN
+#define _ZFS_BIG_ENDIAN
+#elif defined(_LITTLE_ENDIAN) && _BYTE_ORDER == _LITTLE_ENDIAN
+#define _ZFS_LITTLE_ENDIAN
+#endif
+#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
+#define _ZFS_BIG_ENDIAN
+#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#define _ZFS_LITTLE_ENDIAN
+#endif
+
+/* arm arch specific defines */
+#elif defined(__arm) || defined(__arm__) || defined(__aarch64__)
+
+#if !defined(__arm)
+#define __arm
+#endif
+
+#if !defined(__arm__)
+#define __arm__
+#endif
+
+#if defined(__aarch64__)
+#if !defined(_LP64)
+#define _LP64
+#endif
+#else
+#if !defined(_ILP32)
+#define _ILP32
+#endif
+#endif
+
+#if defined(__ARMEL__) || defined(__AARCH64EL__)
+#define _ZFS_LITTLE_ENDIAN
+#else
+#define _ZFS_BIG_ENDIAN
+#endif
+
+#define _SUNOS_VTOC_16
+
+#if defined(__ARM_FEATURE_UNALIGNED)
+#define HAVE_EFFICIENT_UNALIGNED_ACCESS
+#endif
+
+/* sparc arch specific defines */
+#elif defined(__sparc) || defined(__sparc__)
+
+#if !defined(__sparc)
+#define __sparc
+#endif
+
+#if !defined(__sparc__)
+#define __sparc__
+#endif
+
+#define _ZFS_BIG_ENDIAN
+#define _SUNOS_VTOC_16
+
+#if defined(__arch64__)
+#if !defined(_LP64)
+#define _LP64
+#endif
+#else
+#if !defined(_ILP32)
+#define _ILP32
+#endif
+#endif
+
+/* s390 arch specific defines */
+#elif defined(__s390__)
+#if defined(__s390x__)
+#if !defined(_LP64)
+#define _LP64
+#endif
+#else
+#if !defined(_ILP32)
+#define _ILP32
+#endif
+#endif
+
+#define _ZFS_BIG_ENDIAN
+#define _SUNOS_VTOC_16
+
+/* MIPS arch specific defines */
+#elif defined(__mips__)
+
+#if defined(__MIPSEB__)
+#define _ZFS_BIG_ENDIAN
+#elif defined(__MIPSEL__)
+#define _ZFS_LITTLE_ENDIAN
+#else
+#error MIPS no endian specified
+#endif
+
+#if !defined(_LP64) && !defined(_ILP32)
+#define _ILP32
+#endif
+
+#define _SUNOS_VTOC_16
+
+/*
+ * RISC-V arch specific defines
+ * only RV64G (including atomic) LP64 is supported yet
+ */
+#elif defined(__riscv) && defined(_LP64) && _LP64 && \
+ defined(__riscv_atomic) && __riscv_atomic
+
+#ifndef __riscv__
+#define __riscv__
+#endif
+
+#ifndef __rv64g__
+#define __rv64g__
+#endif
+
+#define _ZFS_LITTLE_ENDIAN
+
+#define _SUNOS_VTOC_16
+
+#else
+/*
+ * Currently supported:
+ * x86_64, x32, i386, arm, powerpc, s390, sparc, mips, and RV64G
+ */
+#error "Unsupported ISA type"
+#endif
+
+#if defined(_ILP32) && defined(_LP64)
+#error "Both _ILP32 and _LP64 are defined"
+#endif
+
+#if !defined(_ILP32) && !defined(_LP64)
+#error "Neither _ILP32 or _LP64 are defined"
+#endif
+
+#if defined(_ZFS_LITTLE_ENDIAN) && defined(_ZFS_BIG_ENDIAN)
+#error "Both _ZFS_LITTLE_ENDIAN and _ZFS_BIG_ENDIAN are defined"
+#endif
+
+#if !defined(_ZFS_LITTLE_ENDIAN) && !defined(_ZFS_BIG_ENDIAN)
+#error "Neither _ZFS_LITTLE_ENDIAN nor _ZFS_BIG_ENDIAN are defined"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_ISA_DEFS_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h b/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h
new file mode 100644
index 000000000000..83d47565aeaf
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_KMEM_H
+#define _SYS_KMEM_H
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define KM_SLEEP 0x00000000 /* same as KM_SLEEP */
+#define KM_NOSLEEP 0x00000001 /* same as KM_NOSLEEP */
+
+#define kmem_alloc(size, flags) malloc(size)
+#define kmem_free(ptr, size) free(ptr)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_KMEM_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h b/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h
new file mode 100644
index 000000000000..69fb6d401fc7
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h
@@ -0,0 +1,822 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_KSTAT_H
+#define _SYS_KSTAT_H
+
+
+
+/*
+ * Definition of general kernel statistics structures and /dev/kstat ioctls
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int kid_t; /* unique kstat id */
+
+/*
+ * Kernel statistics driver (/dev/kstat) ioctls
+ */
+
+#define KSTAT_IOC_BASE ('K' << 8)
+
+#define KSTAT_IOC_CHAIN_ID KSTAT_IOC_BASE | 0x01
+#define KSTAT_IOC_READ KSTAT_IOC_BASE | 0x02
+#define KSTAT_IOC_WRITE KSTAT_IOC_BASE | 0x03
+
+/*
+ * /dev/kstat ioctl usage (kd denotes /dev/kstat descriptor):
+ *
+ * kcid = ioctl(kd, KSTAT_IOC_CHAIN_ID, NULL);
+ * kcid = ioctl(kd, KSTAT_IOC_READ, kstat_t *);
+ * kcid = ioctl(kd, KSTAT_IOC_WRITE, kstat_t *);
+ */
+
+#define KSTAT_STRLEN 255 /* 254 chars + NULL; must be 16 * n - 1 */
+
+/*
+ * The generic kstat header
+ */
+
+typedef struct kstat {
+ /*
+ * Fields relevant to both kernel and user
+ */
+ hrtime_t ks_crtime; /* creation time (from gethrtime()) */
+ struct kstat *ks_next; /* kstat chain linkage */
+ kid_t ks_kid; /* unique kstat ID */
+ char ks_module[KSTAT_STRLEN]; /* provider module name */
+ uchar_t ks_resv; /* reserved, currently just padding */
+ int ks_instance; /* provider module's instance */
+ char ks_name[KSTAT_STRLEN]; /* kstat name */
+ uchar_t ks_type; /* kstat data type */
+ char ks_class[KSTAT_STRLEN]; /* kstat class */
+ uchar_t ks_flags; /* kstat flags */
+ void *ks_data; /* kstat type-specific data */
+ uint_t ks_ndata; /* # of type-specific data records */
+ size_t ks_data_size; /* total size of kstat data section */
+ hrtime_t ks_snaptime; /* time of last data snapshot */
+ /*
+ * Fields relevant to kernel only
+ */
+ int (*ks_update)(struct kstat *, int); /* dynamic update */
+ void *ks_private; /* arbitrary provider-private data */
+ int (*ks_snapshot)(struct kstat *, void *, int);
+ void *ks_lock; /* protects this kstat's data */
+} kstat_t;
+
+#ifdef _SYSCALL32
+
+typedef int32_t kid32_t;
+
+typedef struct kstat32 {
+ /*
+ * Fields relevant to both kernel and user
+ */
+ hrtime_t ks_crtime;
+ caddr32_t ks_next; /* struct kstat pointer */
+ kid32_t ks_kid;
+ char ks_module[KSTAT_STRLEN];
+ uint8_t ks_resv;
+ int32_t ks_instance;
+ char ks_name[KSTAT_STRLEN];
+ uint8_t ks_type;
+ char ks_class[KSTAT_STRLEN];
+ uint8_t ks_flags;
+ caddr32_t ks_data; /* type-specific data */
+ uint32_t ks_ndata;
+ size32_t ks_data_size;
+ hrtime_t ks_snaptime;
+ /*
+ * Fields relevant to kernel only (only needed here for padding)
+ */
+ int32_t _ks_update;
+ caddr32_t _ks_private;
+ int32_t _ks_snapshot;
+ caddr32_t _ks_lock;
+} kstat32_t;
+
+#endif /* _SYSCALL32 */
+
+/*
+ * kstat structure and locking strategy
+ *
+ * Each kstat consists of a header section (a kstat_t) and a data section.
+ * The system maintains a set of kstats, protected by kstat_chain_lock.
+ * kstat_chain_lock protects all additions to/deletions from this set,
+ * as well as all changes to kstat headers. kstat data sections are
+ * *optionally* protected by the per-kstat ks_lock. If ks_lock is non-NULL,
+ * kstat clients (e.g. /dev/kstat) will acquire this lock for all of their
+ * operations on that kstat. It is up to the kstat provider to decide whether
+ * guaranteeing consistent data to kstat clients is sufficiently important
+ * to justify the locking cost. Note, however, that most statistic updates
+ * already occur under one of the provider's mutexes, so if the provider sets
+ * ks_lock to point to that mutex, then kstat data locking is free.
+ *
+ * NOTE: variable-size kstats MUST employ kstat data locking, to prevent
+ * data-size races with kstat clients.
+ *
+ * NOTE: ks_lock is really of type (kmutex_t *); it is declared as (void *)
+ * in the kstat header so that users don't have to be exposed to all of the
+ * kernel's lock-related data structures.
+ */
+
+#if defined(_KERNEL)
+
+#define KSTAT_ENTER(k) \
+ { kmutex_t *lp = (k)->ks_lock; if (lp) mutex_enter(lp); }
+
+#define KSTAT_EXIT(k) \
+ { kmutex_t *lp = (k)->ks_lock; if (lp) mutex_exit(lp); }
+
+#define KSTAT_UPDATE(k, rw) (*(k)->ks_update)((k), (rw))
+
+#define KSTAT_SNAPSHOT(k, buf, rw) (*(k)->ks_snapshot)((k), (buf), (rw))
+
+#endif /* defined(_KERNEL) */
+
+/*
+ * kstat time
+ *
+ * All times associated with kstats (e.g. creation time, snapshot time,
+ * kstat_timer_t and kstat_io_t timestamps, etc.) are 64-bit nanosecond values,
+ * as returned by gethrtime(). The accuracy of these timestamps is machine
+ * dependent, but the precision (units) is the same across all platforms.
+ */
+
+/*
+ * kstat identity (KID)
+ *
+ * Each kstat is assigned a unique KID (kstat ID) when it is added to the
+ * global kstat chain. The KID is used as a cookie by /dev/kstat to
+ * request information about the corresponding kstat. There is also
+ * an identity associated with the entire kstat chain, kstat_chain_id,
+ * which is bumped each time a kstat is added or deleted. /dev/kstat uses
+ * the chain ID to detect changes in the kstat chain (e.g., a new disk
+ * coming online) between ioctl()s.
+ */
+
+/*
+ * kstat module, kstat instance
+ *
+ * ks_module and ks_instance contain the name and instance of the module
+ * that created the kstat. In cases where there can only be one instance,
+ * ks_instance is 0. The kernel proper (/kernel/unix) uses "unix" as its
+ * module name.
+ */
+
+/*
+ * kstat name
+ *
+ * ks_name gives a meaningful name to a kstat. The full kstat namespace
+ * is module.instance.name, so the name only need be unique within a
+ * module. kstat_create() will fail if you try to create a kstat with
+ * an already-used (ks_module, ks_instance, ks_name) triplet. Spaces are
+ * allowed in kstat names, but strongly discouraged, since they hinder
+ * awk-style processing at user level.
+ */
+
+/*
+ * kstat type
+ *
+ * The kstat mechanism provides several flavors of kstat data, defined
+ * below. The "raw" kstat type is just treated as an array of bytes; you
+ * can use this to export any kind of data you want.
+ *
+ * Some kstat types allow multiple data structures per kstat, e.g.
+ * KSTAT_TYPE_NAMED; others do not. This is part of the spec for each
+ * kstat data type.
+ *
+ * User-level tools should *not* rely on the #define KSTAT_NUM_TYPES. To
+ * get this information, read out the standard system kstat "kstat_types".
+ */
+
+#define KSTAT_TYPE_RAW 0 /* can be anything */
+ /* ks_ndata >= 1 */
+#define KSTAT_TYPE_NAMED 1 /* name/value pair */
+ /* ks_ndata >= 1 */
+#define KSTAT_TYPE_INTR 2 /* interrupt statistics */
+ /* ks_ndata == 1 */
+#define KSTAT_TYPE_IO 3 /* I/O statistics */
+ /* ks_ndata == 1 */
+#define KSTAT_TYPE_TIMER 4 /* event timer */
+ /* ks_ndata >= 1 */
+
+#define KSTAT_NUM_TYPES 5
+
+/*
+ * kstat class
+ *
+ * Each kstat can be characterized as belonging to some broad class
+ * of statistics, e.g. disk, tape, net, vm, streams, etc. This field
+ * can be used as a filter to extract related kstats. The following
+ * values are currently in use: disk, tape, net, controller, vm, kvm,
+ * hat, streams, kstat, and misc. (The kstat class encompasses things
+ * like kstat_types.)
+ */
+
+/*
+ * kstat flags
+ *
+ * Any of the following flags may be passed to kstat_create(). They are
+ * all zero by default.
+ *
+ * KSTAT_FLAG_VIRTUAL:
+ *
+ * Tells kstat_create() not to allocate memory for the
+ * kstat data section; instead, you will set the ks_data
+ * field to point to the data you wish to export. This
+ * provides a convenient way to export existing data
+ * structures.
+ *
+ * KSTAT_FLAG_VAR_SIZE:
+ *
+ * The size of the kstat you are creating will vary over time.
+ * For example, you may want to use the kstat mechanism to
+ * export a linked list. NOTE: The kstat framework does not
+ * manage the data section, so all variable-size kstats must be
+ * virtual kstats. Moreover, variable-size kstats MUST employ
+ * kstat data locking to prevent data-size races with kstat
+ * clients. See the section on "kstat snapshot" for details.
+ *
+ * KSTAT_FLAG_WRITABLE:
+ *
+ * Makes the kstat's data section writable by root.
+ * The ks_snapshot routine (see below) does not need to check for
+ * this; permission checking is handled in the kstat driver.
+ *
+ * KSTAT_FLAG_PERSISTENT:
+ *
+ * Indicates that this kstat is to be persistent over time.
+ * For persistent kstats, kstat_delete() simply marks the
+ * kstat as dormant; a subsequent kstat_create() reactivates
+ * the kstat. This feature is provided so that statistics
+ * are not lost across driver close/open (e.g., raw disk I/O
+ * on a disk with no mounted partitions.)
+ * NOTE: Persistent kstats cannot be virtual, since ks_data
+ * points to garbage as soon as the driver goes away.
+ *
+ * The following flags are maintained by the kstat framework:
+ *
+ * KSTAT_FLAG_DORMANT:
+ *
+ * For persistent kstats, indicates that the kstat is in the
+ * dormant state (e.g., the corresponding device is closed).
+ *
+ * KSTAT_FLAG_INVALID:
+ *
+ * This flag is set when a kstat is in a transitional state,
+ * e.g. between kstat_create() and kstat_install().
+ * kstat clients must not attempt to access the kstat's data
+ * if this flag is set.
+ */
+
+#define KSTAT_FLAG_VIRTUAL 0x01
+#define KSTAT_FLAG_VAR_SIZE 0x02
+#define KSTAT_FLAG_WRITABLE 0x04
+#define KSTAT_FLAG_PERSISTENT 0x08
+#define KSTAT_FLAG_DORMANT 0x10
+#define KSTAT_FLAG_INVALID 0x20
+#define KSTAT_FLAG_LONGSTRINGS 0x40
+#define KSTAT_FLAG_NO_HEADERS 0x80
+
+/*
+ * Dynamic update support
+ *
+ * The kstat mechanism allows for an optional ks_update function to update
+ * kstat data. This is useful for drivers where the underlying device
+ * keeps cheap hardware stats, but extraction is expensive. Instead of
+ * constantly keeping the kstat data section up to date, you can supply a
+ * ks_update function which updates the kstat's data section on demand.
+ * To take advantage of this feature, simply set the ks_update field before
+ * calling kstat_install().
+ *
+ * The ks_update function, if supplied, must have the following structure:
+ *
+ * int
+ * foo_kstat_update(kstat_t *ksp, int rw)
+ * {
+ * if (rw == KSTAT_WRITE) {
+ * ... update the native stats from ksp->ks_data;
+ * return EACCES if you don't support this
+ * } else {
+ * ... update ksp->ks_data from the native stats
+ * }
+ * }
+ *
+ * The ks_update return codes are: 0 for success, EACCES if you don't allow
+ * KSTAT_WRITE, and EIO for any other type of error.
+ *
+ * In general, the ks_update function may need to refer to provider-private
+ * data; for example, it may need a pointer to the provider's raw statistics.
+ * The ks_private field is available for this purpose. Its use is entirely
+ * at the provider's discretion.
+ *
+ * All variable-size kstats MUST supply a ks_update routine, which computes
+ * and sets ks_data_size (and ks_ndata if that is meaningful), since these
+ * are needed to perform kstat snapshots (see below).
+ *
+ * No kstat locking should be done inside the ks_update routine. The caller
+ * will already be holding the kstat's ks_lock (to ensure consistent data).
+ */
+
+#define KSTAT_READ 0
+#define KSTAT_WRITE 1
+
+/*
+ * Kstat snapshot
+ *
+ * In order to get a consistent view of a kstat's data, clients must obey
+ * the kstat's locking strategy. However, these clients may need to perform
+ * operations on the data which could cause a fault (e.g. copyout()), or
+ * operations which are simply expensive. Doing so could cause deadlock
+ * (e.g. if you're holding a disk's kstat lock which is ultimately required
+ * to resolve a copyout() fault), performance degradation (since the providers'
+ * activity is serialized at the kstat lock), device timing problems, etc.
+ *
+ * To avoid these problems, kstat data is provided via snapshots. Taking
+ * a snapshot is a simple process: allocate a wired-down kernel buffer,
+ * acquire the kstat's data lock, copy the data into the buffer ("take the
+ * snapshot"), and release the lock. This ensures that the kstat's data lock
+ * will be held as briefly as possible, and that no faults will occur while
+ * the lock is held.
+ *
+ * Normally, the snapshot is taken by default_kstat_snapshot(), which
+ * timestamps the data (sets ks_snaptime), copies it, and does a little
+ * massaging to deal with incomplete transactions on i/o kstats. However,
+ * this routine only works for kstats with contiguous data (the typical case).
+ * If you create a kstat whose data is, say, a linked list, you must provide
+ * your own ks_snapshot routine. The routine you supply must have the
+ * following prototype (replace "foo" with something appropriate):
+ *
+ * int foo_kstat_snapshot(kstat_t *ksp, void *buf, int rw);
+ *
+ * The minimal snapshot routine -- one which copies contiguous data that
+ * doesn't need any massaging -- would be this:
+ *
+ * ksp->ks_snaptime = gethrtime();
+ * if (rw == KSTAT_WRITE)
+ * bcopy(buf, ksp->ks_data, ksp->ks_data_size);
+ * else
+ * bcopy(ksp->ks_data, buf, ksp->ks_data_size);
+ * return (0);
+ *
+ * A more illuminating example is taking a snapshot of a linked list:
+ *
+ * ksp->ks_snaptime = gethrtime();
+ * if (rw == KSTAT_WRITE)
+ * return (EACCES); ... See below ...
+ * for (foo = first_foo; foo; foo = foo->next) {
+ * bcopy((char *) foo, (char *) buf, sizeof (struct foo));
+ * buf = ((struct foo *) buf) + 1;
+ * }
+ * return (0);
+ *
+ * In the example above, we have decided that we don't want to allow
+ * KSTAT_WRITE access, so we return EACCES if this is attempted.
+ *
+ * The key points are:
+ *
+ * (1) ks_snaptime must be set (via gethrtime()) to timestamp the data.
+ * (2) Data gets copied from the kstat to the buffer on KSTAT_READ,
+ * and from the buffer to the kstat on KSTAT_WRITE.
+ * (3) ks_snapshot return values are: 0 for success, EACCES if you
+ * don't allow KSTAT_WRITE, and EIO for any other type of error.
+ *
+ * Named kstats (see section on "Named statistics" below) containing long
+ * strings (KSTAT_DATA_STRING) need special handling. The kstat driver
+ * assumes that all strings are copied into the buffer after the array of
+ * named kstats, and the pointers (KSTAT_NAMED_STR_PTR()) are updated to point
+ * into the copy within the buffer. The default snapshot routine does this,
+ * but overriding routines should contain at least the following:
+ *
+ * if (rw == KSTAT_READ) {
+ * kstat_named_t *knp = buf;
+ * char *end = knp + ksp->ks_ndata;
+ * uint_t i;
+ *
+ * ... Do the regular copy ...
+ * bcopy(ksp->ks_data, buf, sizeof (kstat_named_t) * ksp->ks_ndata);
+ *
+ * for (i = 0; i < ksp->ks_ndata; i++, knp++) {
+ * if (knp[i].data_type == KSTAT_DATA_STRING &&
+ * KSTAT_NAMED_STR_PTR(knp) != NULL) {
+ * bcopy(KSTAT_NAMED_STR_PTR(knp), end,
+ * KSTAT_NAMED_STR_BUFLEN(knp));
+ * KSTAT_NAMED_STR_PTR(knp) = end;
+ * end += KSTAT_NAMED_STR_BUFLEN(knp);
+ * }
+ * }
+ */
+
+/*
+ * Named statistics.
+ *
+ * List of arbitrary name=value statistics.
+ */
+
+typedef struct kstat_named {
+ char name[KSTAT_STRLEN]; /* name of counter */
+ uchar_t data_type; /* data type */
+ union {
+ char c[16]; /* enough for 128-bit ints */
+ int32_t i32;
+ uint32_t ui32;
+ struct {
+ union {
+ char *ptr; /* NULL-term string */
+#if defined(_KERNEL) && defined(_MULTI_DATAMODEL)
+ caddr32_t ptr32;
+#endif
+ char __pad[8]; /* 64-bit padding */
+ } addr;
+ uint32_t len; /* # bytes for strlen + '\0' */
+ } str;
+/*
+ * The int64_t and uint64_t types are not valid for a maximally conformant
+ * 32-bit compilation environment (cc -Xc) using compilers prior to the
+ * introduction of C99 conforming compiler (reference ISO/IEC 9899:1990).
+ * In these cases, the visibility of i64 and ui64 is only permitted for
+ * 64-bit compilation environments or 32-bit non-maximally conformant
+ * C89 or C90 ANSI C compilation environments (cc -Xt and cc -Xa). In the
+ * C99 ANSI C compilation environment, the long long type is supported.
+ * The _INT64_TYPE is defined by the implementation (see sys/int_types.h).
+ */
+#if defined(_INT64_TYPE)
+ int64_t i64;
+ uint64_t ui64;
+#endif
+ long l;
+ ulong_t ul;
+
+ /* These structure members are obsolete */
+
+ longlong_t ll;
+ u_longlong_t ull;
+ float f;
+ double d;
+ } value; /* value of counter */
+} kstat_named_t;
+
+#define KSTAT_DATA_CHAR 0
+#define KSTAT_DATA_INT32 1
+#define KSTAT_DATA_UINT32 2
+#define KSTAT_DATA_INT64 3
+#define KSTAT_DATA_UINT64 4
+
+#if !defined(_LP64)
+#define KSTAT_DATA_LONG KSTAT_DATA_INT32
+#define KSTAT_DATA_ULONG KSTAT_DATA_UINT32
+#else
+#if !defined(_KERNEL)
+#define KSTAT_DATA_LONG KSTAT_DATA_INT64
+#define KSTAT_DATA_ULONG KSTAT_DATA_UINT64
+#else
+#define KSTAT_DATA_LONG 7 /* only visible to the kernel */
+#define KSTAT_DATA_ULONG 8 /* only visible to the kernel */
+#endif /* !_KERNEL */
+#endif /* !_LP64 */
+
+/*
+ * Statistics exporting named kstats with long strings (KSTAT_DATA_STRING)
+ * may not make the assumption that ks_data_size is equal to (ks_ndata * sizeof
+ * (kstat_named_t)). ks_data_size in these cases is equal to the sum of the
+ * amount of space required to store the strings (ie, the sum of
+ * KSTAT_NAMED_STR_BUFLEN() for all KSTAT_DATA_STRING statistics) plus the
+ * space required to store the kstat_named_t's.
+ *
+ * The default update routine will update ks_data_size automatically for
+ * variable-length kstats containing long strings (using the default update
+ * routine only makes sense if the string is the only thing that is changing
+ * in size, and ks_ndata is constant). Fixed-length kstats containing long
+ * strings must explicitly change ks_data_size (after creation but before
+ * initialization) to reflect the correct amount of space required for the
+ * long strings and the kstat_named_t's.
+ */
+#define KSTAT_DATA_STRING 9
+
+/* These types are obsolete */
+
+#define KSTAT_DATA_LONGLONG KSTAT_DATA_INT64
+#define KSTAT_DATA_ULONGLONG KSTAT_DATA_UINT64
+#define KSTAT_DATA_FLOAT 5
+#define KSTAT_DATA_DOUBLE 6
+
+#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data)
+
+/*
+ * Retrieve the pointer of the string contained in the given named kstat.
+ */
+#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr)
+
+/*
+ * Retrieve the length of the buffer required to store the string in the given
+ * named kstat.
+ */
+#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.str.len)
+
+/*
+ * Interrupt statistics.
+ *
+ * An interrupt is a hard interrupt (sourced from the hardware device
+ * itself), a soft interrupt (induced by the system via the use of
+ * some system interrupt source), a watchdog interrupt (induced by
+ * a periodic timer call), spurious (an interrupt entry point was
+ * entered but there was no interrupt condition to service),
+ * or multiple service (an interrupt condition was detected and
+ * serviced just prior to returning from any of the other types).
+ *
+ * Measurement of the spurious class of interrupts is useful for
+ * autovectored devices in order to pinpoint any interrupt latency
+ * problems in a particular system configuration.
+ *
+ * Devices that have more than one interrupt of the same
+ * type should use multiple structures.
+ */
+
+#define KSTAT_INTR_HARD 0
+#define KSTAT_INTR_SOFT 1
+#define KSTAT_INTR_WATCHDOG 2
+#define KSTAT_INTR_SPURIOUS 3
+#define KSTAT_INTR_MULTSVC 4
+
+#define KSTAT_NUM_INTRS 5
+
+typedef struct kstat_intr {
+ uint_t intrs[KSTAT_NUM_INTRS]; /* interrupt counters */
+} kstat_intr_t;
+
+#define KSTAT_INTR_PTR(kptr) ((kstat_intr_t *)(kptr)->ks_data)
+
+/*
+ * I/O statistics.
+ */
+
+typedef struct kstat_io {
+
+ /*
+ * Basic counters.
+ *
+ * The counters should be updated at the end of service
+ * (e.g., just prior to calling biodone()).
+ */
+
+ u_longlong_t nread; /* number of bytes read */
+ u_longlong_t nwritten; /* number of bytes written */
+ uint_t reads; /* number of read operations */
+ uint_t writes; /* number of write operations */
+
+ /*
+ * Accumulated time and queue length statistics.
+ *
+ * Accumulated time statistics are kept as a running sum
+ * of "active" time. Queue length statistics are kept as a
+ * running sum of the product of queue length and elapsed time
+ * at that length -- i.e., a Riemann sum for queue length
+ * integrated against time. (You can also think of the active time
+ * as a Riemann sum, for the boolean function (queue_length > 0)
+ * integrated against time, or you can think of it as the
+ * Lebesgue measure of the set on which queue_length > 0.)
+ *
+ * ^
+ * | _________
+ * 8 | i4 |
+ * | | |
+ * Queue 6 | |
+ * Length | _________ | |
+ * 4 | i2 |_______| |
+ * | | i3 |
+ * 2_______| |
+ * | i1 |
+ * |_______________________________|
+ * Time-> t1 t2 t3 t4
+ *
+ * At each change of state (entry or exit from the queue),
+ * we add the elapsed time (since the previous state change)
+ * to the active time if the queue length was non-zero during
+ * that interval; and we add the product of the elapsed time
+ * times the queue length to the running length*time sum.
+ *
+ * This method is generalizable to measuring residency
+ * in any defined system: instead of queue lengths, think
+ * of "outstanding RPC calls to server X".
+ *
+ * A large number of I/O subsystems have at least two basic
+ * "lists" of transactions they manage: one for transactions
+ * that have been accepted for processing but for which processing
+ * has yet to begin, and one for transactions which are actively
+ * being processed (but not done). For this reason, two cumulative
+ * time statistics are defined here: wait (pre-service) time,
+ * and run (service) time.
+ *
+ * All times are 64-bit nanoseconds (hrtime_t), as returned by
+ * gethrtime().
+ *
+ * The units of cumulative busy time are accumulated nanoseconds.
+ * The units of cumulative length*time products are elapsed time
+ * times queue length.
+ *
+ * Updates to the fields below are performed implicitly by calls to
+ * these five functions:
+ *
+ * kstat_waitq_enter()
+ * kstat_waitq_exit()
+ * kstat_runq_enter()
+ * kstat_runq_exit()
+ *
+ * kstat_waitq_to_runq() (see below)
+ * kstat_runq_back_to_waitq() (see below)
+ *
+ * Since kstat_waitq_exit() is typically followed immediately
+ * by kstat_runq_enter(), there is a single kstat_waitq_to_runq()
+ * function which performs both operations. This is a performance
+ * win since only one timestamp is required.
+ *
+ * In some instances, it may be necessary to move a request from
+ * the run queue back to the wait queue, e.g. for write throttling.
+ * For these situations, call kstat_runq_back_to_waitq().
+ *
+ * These fields should never be updated by any other means.
+ */
+
+ hrtime_t wtime; /* cumulative wait (pre-service) time */
+ hrtime_t wlentime; /* cumulative wait length*time product */
+ hrtime_t wlastupdate; /* last time wait queue changed */
+ hrtime_t rtime; /* cumulative run (service) time */
+ hrtime_t rlentime; /* cumulative run length*time product */
+ hrtime_t rlastupdate; /* last time run queue changed */
+
+ uint_t wcnt; /* count of elements in wait state */
+ uint_t rcnt; /* count of elements in run state */
+
+} kstat_io_t;
+
+#define KSTAT_IO_PTR(kptr) ((kstat_io_t *)(kptr)->ks_data)
+
+/*
+ * Event timer statistics - cumulative elapsed time and number of events.
+ *
+ * Updates to these fields are performed implicitly by calls to
+ * kstat_timer_start() and kstat_timer_stop().
+ */
+
+typedef struct kstat_timer {
+ char name[KSTAT_STRLEN]; /* event name */
+ uchar_t resv; /* reserved */
+ u_longlong_t num_events; /* number of events */
+ hrtime_t elapsed_time; /* cumulative elapsed time */
+ hrtime_t min_time; /* shortest event duration */
+ hrtime_t max_time; /* longest event duration */
+ hrtime_t start_time; /* previous event start time */
+ hrtime_t stop_time; /* previous event stop time */
+} kstat_timer_t;
+
+#define KSTAT_TIMER_PTR(kptr) ((kstat_timer_t *)(kptr)->ks_data)
+
+#if defined(_KERNEL)
+
+#include <sys/t_lock.h>
+
+extern kid_t kstat_chain_id; /* bumped at each state change */
+extern void kstat_init(void); /* initialize kstat framework */
+
+/*
+ * Adding and deleting kstats.
+ *
+ * The typical sequence to add a kstat is:
+ *
+ * ksp = kstat_create(module, instance, name, class, type, ndata, flags);
+ * if (ksp) {
+ * ... provider initialization, if necessary
+ * kstat_install(ksp);
+ * }
+ *
+ * There are three logically distinct steps here:
+ *
+ * Step 1: System Initialization (kstat_create)
+ *
+ * kstat_create() performs system initialization. kstat_create()
+ * allocates memory for the entire kstat (header plus data), initializes
+ * all header fields, initializes the data section to all zeroes, assigns
+ * a unique KID, and puts the kstat onto the system's kstat chain.
+ * The returned kstat is marked invalid (KSTAT_FLAG_INVALID is set),
+ * because the provider (caller) has not yet had a chance to initialize
+ * the data section.
+ *
+ * By default, kstats are exported to all zones on the system. A kstat may be
+ * created via kstat_create_zone() to specify a zone to which the statistics
+ * should be exported. kstat_zone_add() may be used to specify additional
+ * zones to which the statistics are to be exported.
+ *
+ * Step 2: Provider Initialization
+ *
+ * The provider performs any necessary initialization of the data section,
+ * e.g. setting the name fields in a KSTAT_TYPE_NAMED. Virtual kstats set
+ * the ks_data field at this time. The provider may also set the ks_update,
+ * ks_snapshot, ks_private, and ks_lock fields if necessary.
+ *
+ * Step 3: Installation (kstat_install)
+ *
+ * Once the kstat is completely initialized, kstat_install() clears the
+ * INVALID flag, thus making the kstat accessible to the outside world.
+ * kstat_install() also clears the DORMANT flag for persistent kstats.
+ *
+ * Removing a kstat from the system
+ *
+ * kstat_delete(ksp) removes ksp from the kstat chain and frees all
+ * associated system resources. NOTE: When you call kstat_delete(),
+ * you must NOT be holding that kstat's ks_lock. Otherwise, you may
+ * deadlock with a kstat reader.
+ *
+ * Persistent kstats
+ *
+ * From the provider's point of view, persistence is transparent. The only
+ * difference between ephemeral (normal) kstats and persistent kstats
+ * is that you pass KSTAT_FLAG_PERSISTENT to kstat_create(). Magically,
+ * this has the effect of making your data visible even when you're
+ * not home. Persistence is important to tools like iostat, which want
+ * to get a meaningful picture of disk activity. Without persistence,
+ * raw disk i/o statistics could never accumulate: they would come and
+ * go with each open/close of the raw device.
+ *
+ * The magic of persistence works by slightly altering the behavior of
+ * kstat_create() and kstat_delete(). The first call to kstat_create()
+ * creates a new kstat, as usual. However, kstat_delete() does not
+ * actually delete the kstat: it performs one final update of the data
+ * (i.e., calls the ks_update routine), marks the kstat as dormant, and
+ * sets the ks_lock, ks_update, ks_private, and ks_snapshot fields back
+ * to their default values (since they might otherwise point to garbage,
+ * e.g. if the provider is going away). kstat clients can still access
+ * the dormant kstat just like a live kstat; they just continue to see
+ * the final data values as long as the kstat remains dormant.
+ * All subsequent kstat_create() calls simply find the already-existing,
+ * dormant kstat and return a pointer to it, without altering any fields.
+ * The provider then performs its usual initialization sequence, and
+ * calls kstat_install(). kstat_install() uses the old data values to
+ * initialize the native data (i.e., ks_update is called with KSTAT_WRITE),
+ * thus making it seem like you were never gone.
+ */
+
+extern kstat_t *kstat_create(const char *, int, const char *, const char *,
+ uchar_t, uint_t, uchar_t);
+extern kstat_t *kstat_create_zone(const char *, int, const char *,
+ const char *, uchar_t, uint_t, uchar_t, zoneid_t);
+extern void kstat_install(kstat_t *);
+extern void kstat_delete(kstat_t *);
+extern void kstat_named_setstr(kstat_named_t *knp, const char *src);
+extern void kstat_set_string(char *, const char *);
+extern void kstat_delete_byname(const char *, int, const char *);
+extern void kstat_delete_byname_zone(const char *, int, const char *, zoneid_t);
+extern void kstat_named_init(kstat_named_t *, const char *, uchar_t);
+extern void kstat_timer_init(kstat_timer_t *, const char *);
+extern void kstat_waitq_enter(kstat_io_t *);
+extern void kstat_waitq_exit(kstat_io_t *);
+extern void kstat_runq_enter(kstat_io_t *);
+extern void kstat_runq_exit(kstat_io_t *);
+extern void kstat_waitq_to_runq(kstat_io_t *);
+extern void kstat_runq_back_to_waitq(kstat_io_t *);
+extern void kstat_timer_start(kstat_timer_t *);
+extern void kstat_timer_stop(kstat_timer_t *);
+
+extern void kstat_zone_add(kstat_t *, zoneid_t);
+extern void kstat_zone_remove(kstat_t *, zoneid_t);
+extern int kstat_zone_find(kstat_t *, zoneid_t);
+
+extern kstat_t *kstat_hold_bykid(kid_t kid, zoneid_t);
+extern kstat_t *kstat_hold_byname(const char *, int, const char *, zoneid_t);
+extern void kstat_rele(kstat_t *);
+
+#endif /* defined(_KERNEL) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_KSTAT_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/list.h b/sys/contrib/openzfs/lib/libspl/include/sys/list.h
new file mode 100644
index 000000000000..6db92ed42955
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/list.h
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_LIST_H
+#define _SYS_LIST_H
+
+#include <sys/list_impl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct list_node list_node_t;
+typedef struct list list_t;
+
+void list_create(list_t *, size_t, size_t);
+void list_destroy(list_t *);
+
+void list_insert_after(list_t *, void *, void *);
+void list_insert_before(list_t *, void *, void *);
+void list_insert_head(list_t *, void *);
+void list_insert_tail(list_t *, void *);
+void list_remove(list_t *, void *);
+void *list_remove_head(list_t *);
+void *list_remove_tail(list_t *);
+void list_move_tail(list_t *, list_t *);
+
+void *list_head(list_t *);
+void *list_tail(list_t *);
+void *list_next(list_t *, void *);
+void *list_prev(list_t *, void *);
+int list_is_empty(list_t *);
+
+void list_link_init(list_node_t *);
+void list_link_replace(list_node_t *, list_node_t *);
+
+int list_link_active(list_node_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_LIST_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/list_impl.h b/sys/contrib/openzfs/lib/libspl/include/sys/list_impl.h
new file mode 100644
index 000000000000..b5655b972c11
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/list_impl.h
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_LIST_IMPL_H
+#define _SYS_LIST_IMPL_H
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct list_node {
+ struct list_node *next;
+ struct list_node *prev;
+};
+
+struct list {
+ size_t list_size;
+ size_t list_offset;
+ struct list_node list_head;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_LIST_IMPL_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/mhd.h b/sys/contrib/openzfs/lib/libspl/include/sys/mhd.h
new file mode 100644
index 000000000000..fcc062d51c84
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/mhd.h
@@ -0,0 +1,159 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_MHD_H
+#define _SYS_MHD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Definitions for multi-host device I/O control commands
+ */
+#define MHIOC ('M'<<8)
+#define MHIOCENFAILFAST (MHIOC|1)
+#define MHIOCTKOWN (MHIOC|2)
+#define MHIOCRELEASE (MHIOC|3)
+#define MHIOCSTATUS (MHIOC|4)
+#define MHIOCGRP_INKEYS (MHIOC|5)
+#define MHIOCGRP_INRESV (MHIOC|6)
+#define MHIOCGRP_REGISTER (MHIOC|7)
+#define MHIOCGRP_RESERVE (MHIOC|8)
+#define MHIOCGRP_PREEMPTANDABORT (MHIOC|9)
+#define MHIOCGRP_PREEMPT (MHIOC|10)
+#define MHIOCGRP_CLEAR (MHIOC|11)
+#define MHIOCGRP_REGISTERANDIGNOREKEY (MHIOC|14)
+#define MHIOCQRESERVE (MHIOC|12)
+#define MHIOCREREGISTERDEVID (MHIOC|13)
+
+/*
+ * Following is the structure to specify the delay parameters in
+ * milliseconds, via the MHIOCTKOWN ioctl.
+ */
+struct mhioctkown {
+ int reinstate_resv_delay;
+ int min_ownership_delay;
+ int max_ownership_delay;
+};
+
+#define MHIOC_RESV_KEY_SIZE 8
+typedef struct mhioc_resv_key {
+ uchar_t key[MHIOC_RESV_KEY_SIZE];
+} mhioc_resv_key_t;
+
+typedef struct mhioc_key_list {
+ uint32_t listsize;
+ uint32_t listlen;
+ mhioc_resv_key_t *list;
+} mhioc_key_list_t;
+
+typedef struct mhioc_inkeys {
+ uint32_t generation;
+ mhioc_key_list_t *li;
+} mhioc_inkeys_t;
+
+#if defined(_SYSCALL32)
+struct mhioc_key_list32 {
+ uint32_t listsize;
+ uint32_t listlen;
+ caddr32_t list;
+} mhioc_key_list32_t;
+
+struct mhioc_inkeys32 {
+ uint32_t generation;
+ caddr32_t li;
+} mhioc_inkeys32_t;
+#endif
+
+typedef struct mhioc_resv_desc {
+ mhioc_resv_key_t key;
+ uint8_t type;
+ uint8_t scope;
+ uint32_t scope_specific_addr;
+} mhioc_resv_desc_t;
+
+typedef struct mhioc_resv_desc_list {
+ uint32_t listsize;
+ uint32_t listlen;
+ mhioc_resv_desc_t *list;
+} mhioc_resv_desc_list_t;
+
+typedef struct mhioc_inresvs {
+ uint32_t generation;
+ mhioc_resv_desc_list_t *li;
+} mhioc_inresvs_t;
+
+#if defined(_SYSCALL32)
+struct mhioc_resv_desc_list32 {
+ uint32_t listsize;
+ uint32_t listlen;
+ caddr32_t list;
+} mhioc_resv_desc_list32_t;
+
+typedef struct mhioc_inresvs32 {
+ uint32_t generation;
+ caddr32_t li;
+} mhioc_inresvs32_t;
+#endif
+
+typedef struct mhioc_register {
+ mhioc_resv_key_t oldkey;
+ mhioc_resv_key_t newkey;
+ boolean_t aptpl; /* True if persistent across power failures */
+} mhioc_register_t;
+
+typedef struct mhioc_preemptandabort {
+ mhioc_resv_desc_t resvdesc;
+ mhioc_resv_key_t victim_key;
+} mhioc_preemptandabort_t;
+
+typedef struct mhioc_registerandignorekey {
+ mhioc_resv_key_t newkey;
+ boolean_t aptpl; /* True if persistent across power failures */
+} mhioc_registerandignorekey_t;
+
+/*
+ * SCSI-3 PGR Reservation Type Codes. Codes with the _OBSOLETE suffix
+ * have been removed from the SCSI3 PGR standard.
+ */
+#define SCSI3_RESV_READSHARED_OBSOLETE 0
+#define SCSI3_RESV_WRITEEXCLUSIVE 1
+#define SCSI3_RESV_READEXCLUSIVE_OBSOLETE 2
+#define SCSI3_RESV_EXCLUSIVEACCESS 3
+#define SCSI3_RESV_SHAREDACCESS_OBSOLETE 4
+#define SCSI3_RESV_WRITEEXCLUSIVEREGISTRANTSONLY 5
+#define SCSI3_RESV_EXCLUSIVEACCESSREGISTRANTSONLY 6
+
+#define SCSI3_SCOPE_LOGICALUNIT 0
+#define SCSI3_SCOPE_EXTENT_OBSOLETE 1
+#define SCSI3_SCOPE_ELEMENT 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MHD_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/mkdev.h b/sys/contrib/openzfs/lib/libspl/include/sys/mkdev.h
new file mode 100644
index 000000000000..5978de65de50
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/mkdev.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_MKDEV_H
+#define _LIBSPL_SYS_MKDEV_H
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/policy.h b/sys/contrib/openzfs/lib/libspl/include/sys/policy.h
new file mode 100644
index 000000000000..2f695b35cd0b
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/policy.h
@@ -0,0 +1,26 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#ifndef _LIBSYS_SYS_POLICY_H
+#define _LIBSYS_SYS_POLICY_H
+
+#endif /* _LIBSYS_SYS_POLICY_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/poll.h b/sys/contrib/openzfs/lib/libspl/include/sys/poll.h
new file mode 100644
index 000000000000..6ab0bddc0be5
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/poll.h
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2017 Zettabyte Software, LLC. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Compiling against musl correctly points out that including sys/poll.h is
+ * disallowed by the Single UNIX Specification when building in userspace. We
+ * implement a dummy header to redirect the include to the proper header.
+ * However, glibc, klibc and uclibc break this shim by including sys/poll.h
+ * from poll.h, so we add explicit exceptions for them.
+ */
+#ifndef _LIBSPL_SYS_POLL_H
+#define _LIBSPL_SYS_POLL_H
+#if defined(__GLIBC__) || defined(__KLIBC__) || defined(__UCLIBC__)
+#include_next <sys/poll.h>
+#else
+#include <poll.h>
+#endif
+#endif /* _LIBSPL_SYS_POLL_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/priv.h b/sys/contrib/openzfs/lib/libspl/include/sys/priv.h
new file mode 100644
index 000000000000..76c76d1830c2
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/priv.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_PRIV_H
+#define _LIBSPL_SYS_PRIV_H
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/processor.h b/sys/contrib/openzfs/lib/libspl/include/sys/processor.h
new file mode 100644
index 000000000000..78e95d01f1b5
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/processor.h
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_PROCESSOR_H
+#define _LIBSPL_SYS_PROCESSOR_H
+
+#define getcpuid() (-1)
+
+typedef int processorid_t;
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/sha2.h b/sys/contrib/openzfs/lib/libspl/include/sys/sha2.h
new file mode 100644
index 000000000000..e2f66d225e25
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/sha2.h
@@ -0,0 +1,151 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/* Copyright 2013 Saso Kiselkov. All rights reserved. */
+
+#ifndef _SYS_SHA2_H
+#define _SYS_SHA2_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SHA2_HMAC_MIN_KEY_LEN 1 /* SHA2-HMAC min key length in bytes */
+#define SHA2_HMAC_MAX_KEY_LEN INT_MAX /* SHA2-HMAC max key length in bytes */
+
+#define SHA256_DIGEST_LENGTH 32 /* SHA256 digest length in bytes */
+#define SHA384_DIGEST_LENGTH 48 /* SHA384 digest length in bytes */
+#define SHA512_DIGEST_LENGTH 64 /* SHA512 digest length in bytes */
+
+/* Truncated versions of SHA-512 according to FIPS-180-4, section 5.3.6 */
+#define SHA512_224_DIGEST_LENGTH 28 /* SHA512/224 digest length */
+#define SHA512_256_DIGEST_LENGTH 32 /* SHA512/256 digest length */
+
+#define SHA256_HMAC_BLOCK_SIZE 64 /* SHA256-HMAC block size */
+#define SHA512_HMAC_BLOCK_SIZE 128 /* SHA512-HMAC block size */
+
+#define SHA256 0
+#define SHA256_HMAC 1
+#define SHA256_HMAC_GEN 2
+#define SHA384 3
+#define SHA384_HMAC 4
+#define SHA384_HMAC_GEN 5
+#define SHA512 6
+#define SHA512_HMAC 7
+#define SHA512_HMAC_GEN 8
+#define SHA512_224 9
+#define SHA512_256 10
+
+/*
+ * SHA2 context.
+ * The contents of this structure are a private interface between the
+ * Init/Update/Final calls of the functions defined below.
+ * Callers must never attempt to read or write any of the fields
+ * in this structure directly.
+ */
+typedef struct {
+ uint32_t algotype; /* Algorithm Type */
+
+ /* state (ABCDEFGH) */
+ union {
+ uint32_t s32[8]; /* for SHA256 */
+ uint64_t s64[8]; /* for SHA384/512 */
+ } state;
+ /* number of bits */
+ union {
+ uint32_t c32[2]; /* for SHA256 , modulo 2^64 */
+ uint64_t c64[2]; /* for SHA384/512, modulo 2^128 */
+ } count;
+ union {
+ uint8_t buf8[128]; /* undigested input */
+ uint32_t buf32[32]; /* realigned input */
+ uint64_t buf64[16]; /* realigned input */
+ } buf_un;
+} SHA2_CTX;
+
+typedef SHA2_CTX SHA256_CTX;
+typedef SHA2_CTX SHA384_CTX;
+typedef SHA2_CTX SHA512_CTX;
+
+extern void SHA256Init(SHA256_CTX *);
+
+extern void SHA256Update(SHA256_CTX *, const void *, size_t);
+
+extern void SHA256Final(void *, SHA256_CTX *);
+
+extern void SHA384Init(SHA384_CTX *);
+
+extern void SHA384Update(SHA384_CTX *, const void *, size_t);
+
+extern void SHA384Final(void *, SHA384_CTX *);
+
+extern void SHA512Init(SHA512_CTX *);
+
+extern void SHA512Update(SHA512_CTX *, const void *, size_t);
+
+extern void SHA512Final(void *, SHA512_CTX *);
+
+extern void SHA2Init(uint64_t mech, SHA2_CTX *);
+
+extern void SHA2Update(SHA2_CTX *, const void *, size_t);
+
+extern void SHA2Final(void *, SHA2_CTX *);
+
+#ifdef _SHA2_IMPL
+/*
+ * The following types/functions are all private to the implementation
+ * of the SHA2 functions and must not be used by consumers of the interface
+ */
+
+/*
+ * List of support mechanisms in this module.
+ *
+ * It is important to note that in the module, division or modulus calculations
+ * are used on the enumerated type to determine which mechanism is being used;
+ * therefore, changing the order or additional mechanisms should be done
+ * carefully
+ */
+typedef enum sha2_mech_type {
+ SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */
+ SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */
+ SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */
+ SHA384_MECH_INFO_TYPE, /* SUN_CKM_SHA384 */
+ SHA384_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC */
+ SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */
+ SHA512_MECH_INFO_TYPE, /* SUN_CKM_SHA512 */
+ SHA512_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC */
+ SHA512_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC_GENERAL */
+ SHA512_224_MECH_INFO_TYPE, /* SUN_CKM_SHA512_224 */
+ SHA512_256_MECH_INFO_TYPE /* SUN_CKM_SHA512_256 */
+} sha2_mech_type_t;
+
+#endif /* _SHA2_IMPL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_SHA2_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/simd.h b/sys/contrib/openzfs/lib/libspl/include/sys/simd.h
new file mode 100644
index 000000000000..dceedb698fe0
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/simd.h
@@ -0,0 +1,502 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_SIMD_H
+#define _LIBSPL_SYS_SIMD_H
+
+#include <sys/isa_defs.h>
+#include <sys/types.h>
+
+#if defined(__x86)
+#include <cpuid.h>
+
+#define kfpu_allowed() 1
+#define kfpu_begin() do {} while (0)
+#define kfpu_end() do {} while (0)
+#define kfpu_init() 0
+#define kfpu_fini() ((void) 0)
+
+/*
+ * CPUID feature tests for user-space.
+ *
+ * x86 registers used implicitly by CPUID
+ */
+typedef enum cpuid_regs {
+ EAX = 0,
+ EBX,
+ ECX,
+ EDX,
+ CPUID_REG_CNT = 4
+} cpuid_regs_t;
+
+/*
+ * List of instruction sets identified by CPUID
+ */
+typedef enum cpuid_inst_sets {
+ SSE = 0,
+ SSE2,
+ SSE3,
+ SSSE3,
+ SSE4_1,
+ SSE4_2,
+ OSXSAVE,
+ AVX,
+ AVX2,
+ BMI1,
+ BMI2,
+ AVX512F,
+ AVX512CD,
+ AVX512DQ,
+ AVX512BW,
+ AVX512IFMA,
+ AVX512VBMI,
+ AVX512PF,
+ AVX512ER,
+ AVX512VL,
+ AES,
+ PCLMULQDQ,
+ MOVBE
+} cpuid_inst_sets_t;
+
+/*
+ * Instruction set descriptor.
+ */
+typedef struct cpuid_feature_desc {
+ uint32_t leaf; /* CPUID leaf */
+ uint32_t subleaf; /* CPUID sub-leaf */
+ uint32_t flag; /* bit mask of the feature */
+ cpuid_regs_t reg; /* which CPUID return register to test */
+} cpuid_feature_desc_t;
+
+#define _AVX512F_BIT (1U << 16)
+#define _AVX512CD_BIT (_AVX512F_BIT | (1U << 28))
+#define _AVX512DQ_BIT (_AVX512F_BIT | (1U << 17))
+#define _AVX512BW_BIT (_AVX512F_BIT | (1U << 30))
+#define _AVX512IFMA_BIT (_AVX512F_BIT | (1U << 21))
+#define _AVX512VBMI_BIT (1U << 1) /* AVX512F_BIT is on another leaf */
+#define _AVX512PF_BIT (_AVX512F_BIT | (1U << 26))
+#define _AVX512ER_BIT (_AVX512F_BIT | (1U << 27))
+#define _AVX512VL_BIT (1U << 31) /* if used also check other levels */
+#define _AES_BIT (1U << 25)
+#define _PCLMULQDQ_BIT (1U << 1)
+#define _MOVBE_BIT (1U << 22)
+
+/*
+ * Descriptions of supported instruction sets
+ */
+static const cpuid_feature_desc_t cpuid_features[] = {
+ [SSE] = {1U, 0U, 1U << 25, EDX },
+ [SSE2] = {1U, 0U, 1U << 26, EDX },
+ [SSE3] = {1U, 0U, 1U << 0, ECX },
+ [SSSE3] = {1U, 0U, 1U << 9, ECX },
+ [SSE4_1] = {1U, 0U, 1U << 19, ECX },
+ [SSE4_2] = {1U, 0U, 1U << 20, ECX },
+ [OSXSAVE] = {1U, 0U, 1U << 27, ECX },
+ [AVX] = {1U, 0U, 1U << 28, ECX },
+ [AVX2] = {7U, 0U, 1U << 5, EBX },
+ [BMI1] = {7U, 0U, 1U << 3, EBX },
+ [BMI2] = {7U, 0U, 1U << 8, EBX },
+ [AVX512F] = {7U, 0U, _AVX512F_BIT, EBX },
+ [AVX512CD] = {7U, 0U, _AVX512CD_BIT, EBX },
+ [AVX512DQ] = {7U, 0U, _AVX512DQ_BIT, EBX },
+ [AVX512BW] = {7U, 0U, _AVX512BW_BIT, EBX },
+ [AVX512IFMA] = {7U, 0U, _AVX512IFMA_BIT, EBX },
+ [AVX512VBMI] = {7U, 0U, _AVX512VBMI_BIT, ECX },
+ [AVX512PF] = {7U, 0U, _AVX512PF_BIT, EBX },
+ [AVX512ER] = {7U, 0U, _AVX512ER_BIT, EBX },
+ [AVX512VL] = {7U, 0U, _AVX512ER_BIT, EBX },
+ [AES] = {1U, 0U, _AES_BIT, ECX },
+ [PCLMULQDQ] = {1U, 0U, _PCLMULQDQ_BIT, ECX },
+ [MOVBE] = {1U, 0U, _MOVBE_BIT, ECX },
+};
+
+/*
+ * Check if OS supports AVX and AVX2 by checking XCR0
+ * Only call this function if CPUID indicates that AVX feature is
+ * supported by the CPU, otherwise it might be an illegal instruction.
+ */
+static inline uint64_t
+xgetbv(uint32_t index)
+{
+ uint32_t eax, edx;
+ /* xgetbv - instruction byte code */
+ __asm__ __volatile__(".byte 0x0f; .byte 0x01; .byte 0xd0"
+ : "=a" (eax), "=d" (edx)
+ : "c" (index));
+
+ return ((((uint64_t)edx)<<32) | (uint64_t)eax);
+}
+
+/*
+ * Check if CPU supports a feature
+ */
+static inline boolean_t
+__cpuid_check_feature(const cpuid_feature_desc_t *desc)
+{
+ uint32_t r[CPUID_REG_CNT];
+
+ if (__get_cpuid_max(0, NULL) >= desc->leaf) {
+ /*
+ * __cpuid_count is needed to properly check
+ * for AVX2. It is a macro, so return parameters
+ * are passed by value.
+ */
+ __cpuid_count(desc->leaf, desc->subleaf,
+ r[EAX], r[EBX], r[ECX], r[EDX]);
+ return ((r[desc->reg] & desc->flag) == desc->flag);
+ }
+ return (B_FALSE);
+}
+
+#define CPUID_FEATURE_CHECK(name, id) \
+static inline boolean_t \
+__cpuid_has_ ## name(void) \
+{ \
+ return (__cpuid_check_feature(&cpuid_features[id])); \
+}
+
+/*
+ * Define functions for user-space CPUID features testing
+ */
+CPUID_FEATURE_CHECK(sse, SSE);
+CPUID_FEATURE_CHECK(sse2, SSE2);
+CPUID_FEATURE_CHECK(sse3, SSE3);
+CPUID_FEATURE_CHECK(ssse3, SSSE3);
+CPUID_FEATURE_CHECK(sse4_1, SSE4_1);
+CPUID_FEATURE_CHECK(sse4_2, SSE4_2);
+CPUID_FEATURE_CHECK(avx, AVX);
+CPUID_FEATURE_CHECK(avx2, AVX2);
+CPUID_FEATURE_CHECK(osxsave, OSXSAVE);
+CPUID_FEATURE_CHECK(bmi1, BMI1);
+CPUID_FEATURE_CHECK(bmi2, BMI2);
+CPUID_FEATURE_CHECK(avx512f, AVX512F);
+CPUID_FEATURE_CHECK(avx512cd, AVX512CD);
+CPUID_FEATURE_CHECK(avx512dq, AVX512DQ);
+CPUID_FEATURE_CHECK(avx512bw, AVX512BW);
+CPUID_FEATURE_CHECK(avx512ifma, AVX512IFMA);
+CPUID_FEATURE_CHECK(avx512vbmi, AVX512VBMI);
+CPUID_FEATURE_CHECK(avx512pf, AVX512PF);
+CPUID_FEATURE_CHECK(avx512er, AVX512ER);
+CPUID_FEATURE_CHECK(avx512vl, AVX512VL);
+CPUID_FEATURE_CHECK(aes, AES);
+CPUID_FEATURE_CHECK(pclmulqdq, PCLMULQDQ);
+CPUID_FEATURE_CHECK(movbe, MOVBE);
+
+/*
+ * Detect register set support
+ */
+static inline boolean_t
+__simd_state_enabled(const uint64_t state)
+{
+ boolean_t has_osxsave;
+ uint64_t xcr0;
+
+ has_osxsave = __cpuid_has_osxsave();
+ if (!has_osxsave)
+ return (B_FALSE);
+
+ xcr0 = xgetbv(0);
+ return ((xcr0 & state) == state);
+}
+
+#define _XSTATE_SSE_AVX (0x2 | 0x4)
+#define _XSTATE_AVX512 (0xE0 | _XSTATE_SSE_AVX)
+
+#define __ymm_enabled() __simd_state_enabled(_XSTATE_SSE_AVX)
+#define __zmm_enabled() __simd_state_enabled(_XSTATE_AVX512)
+
+/*
+ * Check if SSE instruction set is available
+ */
+static inline boolean_t
+zfs_sse_available(void)
+{
+ return (__cpuid_has_sse());
+}
+
+/*
+ * Check if SSE2 instruction set is available
+ */
+static inline boolean_t
+zfs_sse2_available(void)
+{
+ return (__cpuid_has_sse2());
+}
+
+/*
+ * Check if SSE3 instruction set is available
+ */
+static inline boolean_t
+zfs_sse3_available(void)
+{
+ return (__cpuid_has_sse3());
+}
+
+/*
+ * Check if SSSE3 instruction set is available
+ */
+static inline boolean_t
+zfs_ssse3_available(void)
+{
+ return (__cpuid_has_ssse3());
+}
+
+/*
+ * Check if SSE4.1 instruction set is available
+ */
+static inline boolean_t
+zfs_sse4_1_available(void)
+{
+ return (__cpuid_has_sse4_1());
+}
+
+/*
+ * Check if SSE4.2 instruction set is available
+ */
+static inline boolean_t
+zfs_sse4_2_available(void)
+{
+ return (__cpuid_has_sse4_2());
+}
+
+/*
+ * Check if AVX instruction set is available
+ */
+static inline boolean_t
+zfs_avx_available(void)
+{
+ return (__cpuid_has_avx() && __ymm_enabled());
+}
+
+/*
+ * Check if AVX2 instruction set is available
+ */
+static inline boolean_t
+zfs_avx2_available(void)
+{
+ return (__cpuid_has_avx2() && __ymm_enabled());
+}
+
+/*
+ * Check if BMI1 instruction set is available
+ */
+static inline boolean_t
+zfs_bmi1_available(void)
+{
+ return (__cpuid_has_bmi1());
+}
+
+/*
+ * Check if BMI2 instruction set is available
+ */
+static inline boolean_t
+zfs_bmi2_available(void)
+{
+ return (__cpuid_has_bmi2());
+}
+
+/*
+ * Check if AES instruction set is available
+ */
+static inline boolean_t
+zfs_aes_available(void)
+{
+ return (__cpuid_has_aes());
+}
+
+/*
+ * Check if PCLMULQDQ instruction set is available
+ */
+static inline boolean_t
+zfs_pclmulqdq_available(void)
+{
+ return (__cpuid_has_pclmulqdq());
+}
+
+/*
+ * Check if MOVBE instruction is available
+ */
+static inline boolean_t
+zfs_movbe_available(void)
+{
+ return (__cpuid_has_movbe());
+}
+
+/*
+ * AVX-512 family of instruction sets:
+ *
+ * AVX512F Foundation
+ * AVX512CD Conflict Detection Instructions
+ * AVX512ER Exponential and Reciprocal Instructions
+ * AVX512PF Prefetch Instructions
+ *
+ * AVX512BW Byte and Word Instructions
+ * AVX512DQ Double-word and Quadword Instructions
+ * AVX512VL Vector Length Extensions
+ *
+ * AVX512IFMA Integer Fused Multiply Add (Not supported by kernel 4.4)
+ * AVX512VBMI Vector Byte Manipulation Instructions
+ */
+
+/*
+ * Check if AVX512F instruction set is available
+ */
+static inline boolean_t
+zfs_avx512f_available(void)
+{
+ return (__cpuid_has_avx512f() && __zmm_enabled());
+}
+
+/*
+ * Check if AVX512CD instruction set is available
+ */
+static inline boolean_t
+zfs_avx512cd_available(void)
+{
+ return (__cpuid_has_avx512cd() && __zmm_enabled());
+}
+
+/*
+ * Check if AVX512ER instruction set is available
+ */
+static inline boolean_t
+zfs_avx512er_available(void)
+{
+ return (__cpuid_has_avx512er() && __zmm_enabled());
+}
+
+/*
+ * Check if AVX512PF instruction set is available
+ */
+static inline boolean_t
+zfs_avx512pf_available(void)
+{
+ return (__cpuid_has_avx512pf() && __zmm_enabled());
+}
+
+/*
+ * Check if AVX512BW instruction set is available
+ */
+static inline boolean_t
+zfs_avx512bw_available(void)
+{
+ return (__cpuid_has_avx512bw() && __zmm_enabled());
+}
+
+/*
+ * Check if AVX512DQ instruction set is available
+ */
+static inline boolean_t
+zfs_avx512dq_available(void)
+{
+ return (__cpuid_has_avx512dq() && __zmm_enabled());
+}
+
+/*
+ * Check if AVX512VL instruction set is available
+ */
+static inline boolean_t
+zfs_avx512vl_available(void)
+{
+ return (__cpuid_has_avx512vl() && __zmm_enabled());
+}
+
+/*
+ * Check if AVX512IFMA instruction set is available
+ */
+static inline boolean_t
+zfs_avx512ifma_available(void)
+{
+ return (__cpuid_has_avx512ifma() && __zmm_enabled());
+}
+
+/*
+ * Check if AVX512VBMI instruction set is available
+ */
+static inline boolean_t
+zfs_avx512vbmi_available(void)
+{
+ return (__cpuid_has_avx512f() && __cpuid_has_avx512vbmi() &&
+ __zmm_enabled());
+}
+
+#elif defined(__aarch64__)
+
+#define kfpu_allowed() 1
+#define kfpu_initialize(tsk) do {} while (0)
+#define kfpu_begin() do {} while (0)
+#define kfpu_end() do {} while (0)
+
+#elif defined(__powerpc__)
+
+#define kfpu_allowed() 1
+#define kfpu_initialize(tsk) do {} while (0)
+#define kfpu_begin() do {} while (0)
+#define kfpu_end() do {} while (0)
+
+/*
+ * Check if AltiVec instruction set is available
+ * No easy way beyond 'altivec works' :-(
+ */
+#include <signal.h>
+#include <setjmp.h>
+
+#if defined(__ALTIVEC__) && !defined(__FreeBSD__)
+static jmp_buf env;
+static void sigillhandler(int x)
+{
+ longjmp(env, 1);
+}
+#endif
+
+static inline boolean_t
+zfs_altivec_available(void)
+{
+ boolean_t has_altivec = B_FALSE;
+#if defined(__ALTIVEC__) && !defined(__FreeBSD__)
+ sighandler_t savesig;
+ savesig = signal(SIGILL, sigillhandler);
+ if (setjmp(env)) {
+ signal(SIGILL, savesig);
+ has_altivec = B_FALSE;
+ } else {
+ __asm__ __volatile__("vor 0,0,0\n" : : : "v0");
+ signal(SIGILL, savesig);
+ has_altivec = B_TRUE;
+ }
+#endif
+ return (has_altivec);
+}
+#else
+
+#define kfpu_allowed() 0
+#define kfpu_initialize(tsk) do {} while (0)
+#define kfpu_begin() do {} while (0)
+#define kfpu_end() do {} while (0)
+
+#endif
+
+#endif /* _LIBSPL_SYS_SIMD_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/stack.h b/sys/contrib/openzfs/lib/libspl/include/sys/stack.h
new file mode 100644
index 000000000000..59807e97b6a0
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/stack.h
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * This header file distributed under the terms of the CDDL.
+ * Portions Copyright 2008 Sun Microsystems, Inc. All Rights reserved.
+ */
+#ifndef _SYS_STACK_H
+#define _SYS_STACK_H
+
+#include <pthread.h>
+
+#define STACK_BIAS 0
+
+#ifdef __USE_GNU
+
+static inline int
+stack_getbounds(stack_t *sp)
+{
+ pthread_attr_t attr;
+ int rc;
+
+ rc = pthread_getattr_np(pthread_self(), &attr);
+ if (rc)
+ return (rc);
+
+ rc = pthread_attr_getstack(&attr, &sp->ss_sp, &sp->ss_size);
+ if (rc == 0)
+ sp->ss_flags = 0;
+
+ pthread_attr_destroy(&attr);
+
+ return (rc);
+}
+
+static inline int
+thr_stksegment(stack_t *sp)
+{
+ int rc;
+
+ rc = stack_getbounds(sp);
+ if (rc)
+ return (rc);
+
+ /*
+ * thr_stksegment() is expected to set sp.ss_sp to the high stack
+ * address, but the stack_getbounds() interface is expected to
+ * set sp.ss_sp to the low address. Adjust accordingly.
+ */
+ sp->ss_sp = (void *)(((uintptr_t)sp->ss_sp) + sp->ss_size);
+ sp->ss_flags = 0;
+
+ return (rc);
+}
+
+#endif /* __USE_GNU */
+#endif /* _SYS_STACK_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h b/sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h
new file mode 100644
index 000000000000..c26e2dc96c4e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#ifndef __SYS_STDTYPES_H
+#define __SYS_STDTYPES_H
+
+typedef enum {
+ B_FALSE = 0,
+ B_TRUE = 1
+} boolean_t;
+
+typedef unsigned char uchar_t;
+typedef unsigned short ushort_t;
+typedef unsigned int uint_t;
+typedef unsigned long ulong_t;
+typedef unsigned long long u_longlong_t;
+typedef long long longlong_t;
+
+typedef longlong_t offset_t;
+typedef u_longlong_t u_offset_t;
+typedef u_longlong_t len_t;
+typedef longlong_t diskaddr_t;
+
+typedef ulong_t pgcnt_t; /* number of pages */
+typedef long spgcnt_t; /* signed number of pages */
+
+typedef short pri_t;
+typedef ushort_t o_mode_t; /* old file attribute type */
+
+typedef int major_t;
+typedef int minor_t;
+
+typedef short index_t;
+
+#endif /* __SYS_STDTYPES_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/strings.h b/sys/contrib/openzfs/lib/libspl/include/sys/strings.h
new file mode 100644
index 000000000000..c142047dcdb8
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/strings.h
@@ -0,0 +1,33 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_STRINGS_H
+#define _LIBSPL_SYS_STRINGS_H
+
+#include <string.h>
+#include <strings.h>
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/stropts.h b/sys/contrib/openzfs/lib/libspl/include/sys/stropts.h
new file mode 100644
index 000000000000..08c2e79bc53c
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/stropts.h
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_STROPTS_H
+#define _LIBSPL_SYS_STROPTS_H
+
+#endif /* _LIBSPL_SYS_STROPTS_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h b/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h
new file mode 100644
index 000000000000..ccd2b29b9b09
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2008 by Sun Microsystems, Inc.
+ */
+
+#ifndef _SYS_SUNDDI_H
+#define _SYS_SUNDDI_H
+
+#endif /* _SYS_SUNDDI_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/systeminfo.h b/sys/contrib/openzfs/lib/libspl/include/sys/systeminfo.h
new file mode 100644
index 000000000000..cc6c1793c00e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/systeminfo.h
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_SYSTEMINFO_H
+#define _LIBSPL_SYS_SYSTEMINFO_H
+
+#define HOSTID_MASK 0xFFFFFFFF
+#define HW_INVALID_HOSTID 0xFFFFFFFF /* an invalid hostid */
+#define HW_HOSTID_LEN 11 /* minimum buffer size needed */
+ /* to hold a decimal or hex */
+ /* hostid string */
+
+unsigned long get_system_hostid(void);
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/time.h b/sys/contrib/openzfs/lib/libspl/include/sys/time.h
new file mode 100644
index 000000000000..c9f6165047d2
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/time.h
@@ -0,0 +1,107 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_TIME_H
+#define _LIBSPL_SYS_TIME_H
+
+#include <time.h>
+#include <sys/types.h>
+#include_next <sys/time.h>
+
+#ifndef SEC
+#define SEC 1
+#endif
+
+#ifndef MILLISEC
+#define MILLISEC 1000
+#endif
+
+#ifndef MICROSEC
+#define MICROSEC 1000000
+#endif
+
+#ifndef NANOSEC
+#define NANOSEC 1000000000
+#endif
+
+#ifndef NSEC_PER_USEC
+#define NSEC_PER_USEC 1000L
+#endif
+
+#ifndef MSEC2NSEC
+#define MSEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MILLISEC))
+#endif
+
+#ifndef NSEC2MSEC
+#define NSEC2MSEC(n) ((n) / (NANOSEC / MILLISEC))
+#endif
+
+#ifndef USEC2NSEC
+#define USEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MICROSEC))
+#endif
+
+#ifndef NSEC2USEC
+#define NSEC2USEC(n) ((n) / (NANOSEC / MICROSEC))
+#endif
+
+#ifndef NSEC2SEC
+#define NSEC2SEC(n) ((n) / (NANOSEC / SEC))
+#endif
+
+#ifndef SEC2NSEC
+#define SEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / SEC))
+#endif
+
+typedef long long hrtime_t;
+typedef struct timespec timespec_t;
+typedef struct timespec inode_timespec_t;
+
+static inline void
+gethrestime(inode_timespec_t *ts)
+{
+ struct timeval tv;
+ (void) gettimeofday(&tv, NULL);
+ ts->tv_sec = tv.tv_sec;
+ ts->tv_nsec = tv.tv_usec * NSEC_PER_USEC;
+}
+
+static inline uint64_t
+gethrestime_sec(void)
+{
+ struct timeval tv;
+ (void) gettimeofday(&tv, NULL);
+ return (tv.tv_sec);
+}
+
+static inline hrtime_t
+gethrtime(void)
+{
+ struct timespec ts;
+ (void) clock_gettime(CLOCK_MONOTONIC, &ts);
+ return ((((u_int64_t)ts.tv_sec) * NANOSEC) + ts.tv_nsec);
+}
+
+#endif /* _LIBSPL_SYS_TIME_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/trace_spl.h b/sys/contrib/openzfs/lib/libspl/include/sys/trace_spl.h
new file mode 100644
index 000000000000..b80d288f7332
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/trace_spl.h
@@ -0,0 +1,24 @@
+/* Here to keep the libspl build happy */
+
+#ifndef _LIBSPL_SPL_TRACE_H
+#define _LIBSPL_SPL_TRACE_H
+
+/*
+ * The set-error SDT probe is extra static, in that we declare its fake
+ * function literally, rather than with the DTRACE_PROBE1() macro. This is
+ * necessary so that SET_ERROR() can evaluate to a value, which wouldn't
+ * be possible if it required multiple statements (to declare the function
+ * and then call it).
+ *
+ * SET_ERROR() uses the comma operator so that it can be used without much
+ * additional code. For example, "return (EINVAL);" becomes
+ * "return (SET_ERROR(EINVAL));". Note that the argument will be evaluated
+ * twice, so it should not have side effects (e.g. something like:
+ * "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice).
+ */
+#undef SET_ERROR
+#define SET_ERROR(err) \
+ (__set_error(__FILE__, __func__, __LINE__, err), err)
+
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/trace_zfs.h b/sys/contrib/openzfs/lib/libspl/include/sys/trace_zfs.h
new file mode 100644
index 000000000000..87ed5ad3c3be
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/trace_zfs.h
@@ -0,0 +1,24 @@
+/* Here to keep the libspl build happy */
+
+#ifndef _LIBSPL_ZFS_TRACE_H
+#define _LIBSPL_ZFS_TRACE_H
+
+/*
+ * The set-error SDT probe is extra static, in that we declare its fake
+ * function literally, rather than with the DTRACE_PROBE1() macro. This is
+ * necessary so that SET_ERROR() can evaluate to a value, which wouldn't
+ * be possible if it required multiple statements (to declare the function
+ * and then call it).
+ *
+ * SET_ERROR() uses the comma operator so that it can be used without much
+ * additional code. For example, "return (EINVAL);" becomes
+ * "return (SET_ERROR(EINVAL));". Note that the argument will be evaluated
+ * twice, so it should not have side effects (e.g. something like:
+ * "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice).
+ */
+#undef SET_ERROR
+#define SET_ERROR(err) \
+ (__set_error(__FILE__, __func__, __LINE__, err), err)
+
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/types.h b/sys/contrib/openzfs/lib/libspl/include/sys/types.h
new file mode 100644
index 000000000000..ea02ffac93ac
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/types.h
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_TYPES_H
+#define _LIBSPL_SYS_TYPES_H
+
+#if defined(HAVE_MAKEDEV_IN_SYSMACROS)
+#include <sys/sysmacros.h>
+#elif defined(HAVE_MAKEDEV_IN_MKDEV)
+#include <sys/mkdev.h>
+#endif
+
+#include <sys/isa_defs.h>
+#include <sys/feature_tests.h>
+#include_next <sys/types.h>
+#include <sys/types32.h>
+#include <sys/va_list.h>
+#include <sys/stdtypes.h>
+
+#ifndef HAVE_INTTYPES
+#include <inttypes.h>
+#endif /* HAVE_INTTYPES */
+
+typedef int zoneid_t;
+typedef int projid_t;
+
+/*
+ * Definitions remaining from previous partial support for 64-bit file
+ * offsets. This partial support for devices greater than 2gb requires
+ * compiler support for long long.
+ */
+#ifdef _LONG_LONG_LTOH
+typedef union {
+ offset_t _f; /* Full 64 bit offset value */
+ struct {
+ int32_t _l; /* lower 32 bits of offset value */
+ int32_t _u; /* upper 32 bits of offset value */
+ } _p;
+} lloff_t;
+#endif
+
+#ifdef _LONG_LONG_HTOL
+typedef union {
+ offset_t _f; /* Full 64 bit offset value */
+ struct {
+ int32_t _u; /* upper 32 bits of offset value */
+ int32_t _l; /* lower 32 bits of offset value */
+ } _p;
+} lloff_t;
+#endif
+
+#include <sys/param.h> /* for NBBY */
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/types32.h b/sys/contrib/openzfs/lib/libspl/include/sys/types32.h
new file mode 100644
index 000000000000..bb41aa34bee0
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/types32.h
@@ -0,0 +1,89 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_TYPES32_H
+#define _SYS_TYPES32_H
+
+#include <sys/inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Interoperability types for programs. Used for:
+ *
+ * Crossing between 32-bit and 64-bit domains.
+ *
+ * On disk data formats such as filesystem meta data
+ * and disk label.
+ *
+ * Note: Applications should never include this
+ * header file.
+ */
+typedef uint32_t caddr32_t;
+typedef int32_t daddr32_t;
+typedef int32_t off32_t;
+typedef uint32_t ino32_t;
+typedef int32_t blkcnt32_t;
+typedef uint32_t fsblkcnt32_t;
+typedef uint32_t fsfilcnt32_t;
+typedef int32_t id32_t;
+typedef uint32_t major32_t;
+typedef uint32_t minor32_t;
+typedef int32_t key32_t;
+typedef uint32_t mode32_t;
+typedef uint32_t uid32_t;
+typedef uint32_t gid32_t;
+typedef uint32_t nlink32_t;
+typedef uint32_t dev32_t;
+typedef int32_t pid32_t;
+typedef uint32_t size32_t;
+typedef int32_t ssize32_t;
+typedef int32_t time32_t;
+typedef int32_t clock32_t;
+
+struct timeval32 {
+ time32_t tv_sec; /* seconds */
+ int32_t tv_usec; /* and microseconds */
+};
+
+typedef struct timespec32 {
+ time32_t tv_sec; /* seconds */
+ int32_t tv_nsec; /* and nanoseconds */
+} timespec32_t;
+
+typedef struct timespec32 timestruc32_t;
+
+typedef struct itimerspec32 {
+ struct timespec32 it_interval;
+ struct timespec32 it_value;
+} itimerspec32_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_TYPES32_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/tzfile.h b/sys/contrib/openzfs/lib/libspl/include/sys/tzfile.h
new file mode 100644
index 000000000000..e30e7566366e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/tzfile.h
@@ -0,0 +1,164 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * from Arthur Olson's 6.1
+ */
+
+#ifndef _LIBSPL_SYS_TZFILE_H
+#define _LIBSPL_SYS_TZFILE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Information about time zone files.
+ */
+
+#define TZDIR "/usr/share/lib/zoneinfo" /* Time zone object file directory */
+
+#define TZDEFAULT (getenv("TZ"))
+
+#define TZDEFRULES "posixrules"
+
+/*
+ * Each file begins with. . .
+ */
+
+struct tzhead {
+ char tzh_reserved[24]; /* reserved for future use */
+ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
+ char tzh_leapcnt[4]; /* coded number of leap seconds */
+ char tzh_timecnt[4]; /* coded number of transition times */
+ char tzh_typecnt[4]; /* coded number of local time types */
+ char tzh_charcnt[4]; /* coded number of abbr. chars */
+};
+
+/*
+ * . . .followed by. . .
+ *
+ * tzh_timecnt (char [4])s coded transition times a la time(2)
+ * tzh_timecnt (unsigned char)s types of local time starting at above
+ * tzh_typecnt repetitions of
+ * one (char [4]) coded GMT offset in seconds
+ * one (unsigned char) used to set tm_isdst
+ * one (unsigned char) that's an abbreviation list index
+ * tzh_charcnt (char)s '\0'-terminated zone abbreviations
+ * tzh_leapcnt repetitions of
+ * one (char [4]) coded leap second transition times
+ * one (char [4]) total correction after above
+ * tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
+ * time is standard time, if FALSE,
+ * transition time is wall clock time
+ * if absent, transition times are
+ * assumed to be wall clock time
+ */
+
+/*
+ * In the current implementation, "tzset()" refuses to deal with files that
+ * exceed any of the limits below.
+ */
+
+/*
+ * The TZ_MAX_TIMES value below is enough to handle a bit more than a
+ * year's worth of solar time (corrected daily to the nearest second) or
+ * 138 years of Pacific Presidential Election time
+ * (where there are three time zone transitions every fourth year).
+ */
+#define TZ_MAX_TIMES 370
+
+#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
+
+#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
+
+#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
+
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+#define DAYSPERWEEK 7
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((long)SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR 12
+
+#define TM_SUNDAY 0
+#define TM_MONDAY 1
+#define TM_TUESDAY 2
+#define TM_WEDNESDAY 3
+#define TM_THURSDAY 4
+#define TM_FRIDAY 5
+#define TM_SATURDAY 6
+
+#define TM_JANUARY 0
+#define TM_FEBRUARY 1
+#define TM_MARCH 2
+#define TM_APRIL 3
+#define TM_MAY 4
+#define TM_JUNE 5
+#define TM_JULY 6
+#define TM_AUGUST 7
+#define TM_SEPTEMBER 8
+#define TM_OCTOBER 9
+#define TM_NOVEMBER 10
+#define TM_DECEMBER 11
+
+#define TM_YEAR_BASE 1900
+
+#define EPOCH_YEAR 1970
+#define EPOCH_WDAY TM_THURSDAY
+
+/*
+ * Accurate only for the past couple of centuries;
+ * that will probably do.
+ */
+
+#define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)
+
+/*
+ * Use of the underscored variants may cause problems if you move your code to
+ * certain System-V-based systems; for maximum portability, use the
+ * underscore-free variants. The underscored variants are provided for
+ * backward compatibility only; they may disappear from future versions of
+ * this file.
+ */
+
+#define SECS_PER_MIN SECSPERMIN
+#define MINS_PER_HOUR MINSPERHOUR
+#define HOURS_PER_DAY HOURSPERDAY
+#define DAYS_PER_WEEK DAYSPERWEEK
+#define DAYS_PER_NYEAR DAYSPERNYEAR
+#define DAYS_PER_LYEAR DAYSPERLYEAR
+#define SECS_PER_HOUR SECSPERHOUR
+#define SECS_PER_DAY SECSPERDAY
+#define MONS_PER_YEAR MONSPERYEAR
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBSPL_SYS_TZFILE_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/uio.h b/sys/contrib/openzfs/lib/libspl/include/sys/uio.h
new file mode 100644
index 000000000000..3a834b996add
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/uio.h
@@ -0,0 +1,153 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+
+#ifndef _LIBSPL_SYS_UIO_H
+#define _LIBSPL_SYS_UIO_H
+
+#include <sys/types.h>
+#include_next <sys/uio.h>
+
+#ifdef __APPLE__
+#include <sys/_types/_iovec_t.h>
+#endif
+
+#include <stdint.h>
+typedef struct iovec iovec_t;
+
+#if defined(__linux__) || defined(__APPLE__)
+typedef enum uio_rw {
+ UIO_READ = 0,
+ UIO_WRITE = 1,
+} uio_rw_t;
+
+typedef enum uio_seg {
+ UIO_USERSPACE = 0,
+ UIO_SYSSPACE = 1,
+ UIO_USERISPACE = 2,
+} uio_seg_t;
+
+#elif defined(__FreeBSD__)
+typedef enum uio_seg uio_seg_t;
+#endif
+
+typedef struct uio {
+ struct iovec *uio_iov; /* pointer to array of iovecs */
+ int uio_iovcnt; /* number of iovecs */
+ offset_t uio_loffset; /* file offset */
+ uio_seg_t uio_segflg; /* address space (kernel or user) */
+ uint16_t uio_fmode; /* file mode flags */
+ uint16_t uio_extflg; /* extended flags */
+ offset_t uio_limit; /* u-limit (maximum byte offset) */
+ ssize_t uio_resid; /* residual count */
+} uio_t;
+
+typedef enum xuio_type {
+ UIOTYPE_ASYNCIO,
+ UIOTYPE_ZEROCOPY,
+} xuio_type_t;
+
+#define UIOA_IOV_MAX 16
+
+typedef struct uioa_page_s { /* locked uio_iov state */
+ int uioa_pfncnt; /* count of pfn_t(s) in *uioa_ppp */
+ void **uioa_ppp; /* page_t or pfn_t array */
+ caddr_t uioa_base; /* address base */
+ size_t uioa_len; /* span length */
+} uioa_page_t;
+
+typedef struct xuio {
+ uio_t xu_uio; /* embedded UIO structure */
+
+ /* Extended uio fields */
+ enum xuio_type xu_type; /* uio type */
+ union {
+ struct {
+ uint32_t xu_a_state; /* state of async i/o */
+ ssize_t xu_a_mbytes; /* bytes moved */
+ uioa_page_t *xu_a_lcur; /* uioa_locked[] pointer */
+ void **xu_a_lppp; /* lcur->uioa_pppp[] pointer */
+ void *xu_a_hwst[4]; /* opaque hardware state */
+ uioa_page_t xu_a_locked[UIOA_IOV_MAX];
+ } xu_aio;
+
+ struct {
+ int xu_zc_rw; /* read or write buffer */
+ void *xu_zc_priv; /* fs specific */
+ } xu_zc;
+ } xu_ext;
+} xuio_t;
+
+#define XUIO_XUZC_PRIV(xuio) xuio->xu_ext.xu_zc.xu_zc_priv
+#define XUIO_XUZC_RW(xuio) xuio->xu_ext.xu_zc.xu_zc_rw
+
+#define uio_segflg(uio) (uio)->uio_segflg
+#define uio_offset(uio) (uio)->uio_loffset
+#define uio_resid(uio) (uio)->uio_resid
+#define uio_iovcnt(uio) (uio)->uio_iovcnt
+#define uio_iovlen(uio, idx) (uio)->uio_iov[(idx)].iov_len
+#define uio_iovbase(uio, idx) (uio)->uio_iov[(idx)].iov_base
+
+static inline void
+uio_iov_at_index(uio_t *uio, uint_t idx, void **base, uint64_t *len)
+{
+ *base = uio_iovbase(uio, idx);
+ *len = uio_iovlen(uio, idx);
+}
+
+static inline void
+uio_advance(uio_t *uio, size_t size)
+{
+ uio->uio_resid -= size;
+ uio->uio_loffset += size;
+}
+
+static inline offset_t
+uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx)
+{
+ *vec_idx = 0;
+ while (*vec_idx < (uint_t)uio_iovcnt(uio) &&
+ off >= (offset_t)uio_iovlen(uio, *vec_idx)) {
+ off -= uio_iovlen(uio, *vec_idx);
+ (*vec_idx)++;
+ }
+
+ return (off);
+}
+
+#endif /* _SYS_UIO_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/va_list.h b/sys/contrib/openzfs/lib/libspl/include/sys/va_list.h
new file mode 100644
index 000000000000..a36f5c77daa9
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/va_list.h
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_VA_LIST_H
+#define _SYS_VA_LIST_H
+
+#include <stdarg.h>
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/varargs.h b/sys/contrib/openzfs/lib/libspl/include/sys/varargs.h
new file mode 100644
index 000000000000..3d00a3361d87
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/varargs.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_VARARGS_H
+#define _LIBSPL_SYS_VARARGS_H
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h b/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h
new file mode 100644
index 000000000000..efcdd2c5a5ae
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_VNODE_H
+#define _LIBSPL_SYS_VNODE_H
+
+#endif /* _LIBSPL_SYS_VNODE_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/vtoc.h b/sys/contrib/openzfs/lib/libspl/include/sys/vtoc.h
new file mode 100644
index 000000000000..5d8448b628dc
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/vtoc.h
@@ -0,0 +1,350 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+
+#ifndef _SYS_VTOC_H
+#define _SYS_VTOC_H
+
+#include <sys/dklabel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Note: the VTOC is not implemented fully, nor in the manner
+ * that AT&T implements it. AT&T puts the vtoc structure
+ * into a sector, usually the second sector (pdsector is first).
+ *
+ * Sun incorporates the tag, flag, version, and volume vtoc fields into
+ * its Disk Label, which already has some vtoc-equivalent fields.
+ * Upon reading the vtoc with read_vtoc(), the following exceptions
+ * occur:
+ * v_bootinfo [all] returned as zero
+ * v_sanity returned as VTOC_SANE
+ * if Disk Label was sane
+ * v_sectorsz returned as 512
+ * v_reserved [all] returned as zero
+ * timestamp [all] returned as zero
+ *
+ * See dklabel.h, read_vtoc(), and write_vtoc().
+ */
+
+#define V_NUMPAR NDKMAP /* The number of partitions */
+ /* (from dkio.h) */
+
+#define VTOC_SANE 0x600DDEEE /* Indicates a sane VTOC */
+#define V_VERSION 0x01 /* layout version number */
+#define V_EXTVERSION V_VERSION /* extvtoc layout version number */
+
+/*
+ * Partition identification tags
+ */
+#define V_UNASSIGNED 0x00 /* unassigned partition */
+#define V_BOOT 0x01 /* Boot partition */
+#define V_ROOT 0x02 /* Root filesystem */
+#define V_SWAP 0x03 /* Swap filesystem */
+#define V_USR 0x04 /* Usr filesystem */
+#define V_BACKUP 0x05 /* full disk */
+#define V_STAND 0x06 /* Stand partition */
+#define V_VAR 0x07 /* Var partition */
+#define V_HOME 0x08 /* Home partition */
+#define V_ALTSCTR 0x09 /* Alternate sector partition */
+#define V_CACHE 0x0a /* Cache (cachefs) partition */
+#define V_RESERVED 0x0b /* SMI reserved data */
+
+/*
+ * Partition permission flags
+ */
+#define V_UNMNT 0x01 /* Unmountable partition */
+#define V_RONLY 0x10 /* Read only */
+
+/*
+ * error codes for reading & writing vtoc
+ */
+#define VT_ERROR (-2) /* errno supplies specific error */
+#define VT_EIO (-3) /* I/O error accessing vtoc */
+#define VT_EINVAL (-4) /* illegal value in vtoc or request */
+#define VT_ENOTSUP (-5) /* VTOC op. not supported */
+#define VT_ENOSPC (-6) /* requested space not found */
+#define VT_EOVERFLOW (-7) /* VTOC op. data struct limited */
+
+struct partition {
+ ushort_t p_tag; /* ID tag of partition */
+ ushort_t p_flag; /* permission flags */
+ uint64_t p_start; /* start sector no of partition */
+ long p_size; /* # of blocks in partition */
+};
+
+struct vtoc {
+ unsigned long v_bootinfo[3]; /* info needed by mboot (unsupported) */
+ unsigned long v_sanity; /* to verify vtoc sanity */
+ unsigned long v_version; /* layout version */
+ char v_volume[LEN_DKL_VVOL]; /* volume name */
+ ushort_t v_sectorsz; /* sector size in bytes */
+ ushort_t v_nparts; /* number of partitions */
+ unsigned long v_reserved[10]; /* free space */
+ struct partition v_part[V_NUMPAR]; /* partition headers */
+ time_t timestamp[V_NUMPAR]; /* partition timestamp (unsupported) */
+ char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */
+};
+
+struct extpartition {
+ ushort_t p_tag; /* ID tag of partition */
+ ushort_t p_flag; /* permission flags */
+ ushort_t p_pad[2];
+ diskaddr_t p_start; /* start sector no of partition */
+ diskaddr_t p_size; /* # of blocks in partition */
+};
+
+
+struct extvtoc {
+ uint64_t v_bootinfo[3]; /* info needed by mboot (unsupported) */
+ uint64_t v_sanity; /* to verify vtoc sanity */
+ uint64_t v_version; /* layout version */
+ char v_volume[LEN_DKL_VVOL]; /* volume name */
+ ushort_t v_sectorsz; /* sector size in bytes */
+ ushort_t v_nparts; /* number of partitions */
+ ushort_t pad[2];
+ uint64_t v_reserved[10];
+ struct extpartition v_part[V_NUMPAR]; /* partition headers */
+ uint64_t timestamp[V_NUMPAR]; /* partition timestamp (unsupported) */
+ char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */
+};
+
+#ifdef _KERNEL
+#define extvtoctovtoc(extv, v) \
+ { \
+ int i; \
+ v.v_bootinfo[0] = (unsigned long)extv.v_bootinfo[0]; \
+ v.v_bootinfo[1] = (unsigned long)extv.v_bootinfo[1]; \
+ v.v_bootinfo[2] = (unsigned long)extv.v_bootinfo[2]; \
+ v.v_sanity = (unsigned long)extv.v_sanity; \
+ v.v_version = (unsigned long)extv.v_version; \
+ bcopy(extv.v_volume, v.v_volume, LEN_DKL_VVOL); \
+ v.v_sectorsz = extv.v_sectorsz; \
+ v.v_nparts = extv.v_nparts; \
+ for (i = 0; i < 10; i++) \
+ v.v_reserved[i] = (unsigned long)extv.v_reserved[i]; \
+ for (i = 0; i < V_NUMPAR; i++) { \
+ v.v_part[i].p_tag = extv.v_part[i].p_tag; \
+ v.v_part[i].p_flag = extv.v_part[i].p_flag; \
+ v.v_part[i].p_start = (uint64_t)extv.v_part[i].p_start; \
+ v.v_part[i].p_size = (long)extv.v_part[i].p_size; \
+ v.timestamp[i] = (time_t)extv.timestamp[i]; \
+ } \
+ bcopy(extv.v_asciilabel, v.v_asciilabel, LEN_DKL_ASCII); \
+ }
+
+#define vtoctoextvtoc(v, extv) \
+ { \
+ int i; \
+ extv.v_bootinfo[0] = (uint64_t)v.v_bootinfo[0]; \
+ extv.v_bootinfo[1] = (uint64_t)v.v_bootinfo[1]; \
+ extv.v_bootinfo[2] = (uint64_t)v.v_bootinfo[2]; \
+ extv.v_sanity = (uint64_t)v.v_sanity; \
+ extv.v_version = (uint64_t)v.v_version; \
+ bcopy(v.v_volume, extv.v_volume, LEN_DKL_VVOL); \
+ extv.v_sectorsz = v.v_sectorsz; \
+ extv.v_nparts = v.v_nparts; \
+ for (i = 0; i < 10; i++) \
+ extv.v_reserved[i] = (uint64_t)v.v_reserved[i]; \
+ for (i = 0; i < V_NUMPAR; i++) { \
+ extv.v_part[i].p_tag = v.v_part[i].p_tag; \
+ extv.v_part[i].p_flag = v.v_part[i].p_flag; \
+ extv.v_part[i].p_start = \
+ (diskaddr_t)(unsigned long)v.v_part[i].p_start; \
+ extv.v_part[i].p_size = \
+ (diskaddr_t)(unsigned long)v.v_part[i].p_size; \
+ extv.timestamp[i] = (uint64_t)v.timestamp[i]; \
+ } \
+ bcopy(v.v_asciilabel, extv.v_asciilabel, LEN_DKL_ASCII); \
+ }
+#endif /* _KERNEL */
+
+#if defined(_SYSCALL32)
+struct partition32 {
+ uint16_t p_tag; /* ID tag of partition */
+ uint16_t p_flag; /* permission flags */
+ daddr32_t p_start; /* start sector no of partition */
+ int32_t p_size; /* # of blocks in partition */
+};
+
+struct vtoc32 {
+ uint32_t v_bootinfo[3]; /* info needed by mboot (unsupported) */
+ uint32_t v_sanity; /* to verify vtoc sanity */
+ uint32_t v_version; /* layout version */
+ char v_volume[LEN_DKL_VVOL]; /* volume name */
+ uint16_t v_sectorsz; /* sector size in bytes */
+ uint16_t v_nparts; /* number of partitions */
+ uint32_t v_reserved[10]; /* free space */
+ struct partition32 v_part[V_NUMPAR]; /* partition headers */
+ time32_t timestamp[V_NUMPAR]; /* partition timestamp (unsupported) */
+ char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */
+};
+
+#define vtoc32tovtoc(v32, v) \
+ { \
+ int i; \
+ v.v_bootinfo[0] = v32.v_bootinfo[0]; \
+ v.v_bootinfo[1] = v32.v_bootinfo[1]; \
+ v.v_bootinfo[2] = v32.v_bootinfo[2]; \
+ v.v_sanity = v32.v_sanity; \
+ v.v_version = v32.v_version; \
+ bcopy(v32.v_volume, v.v_volume, LEN_DKL_VVOL); \
+ v.v_sectorsz = v32.v_sectorsz; \
+ v.v_nparts = v32.v_nparts; \
+ v.v_version = v32.v_version; \
+ for (i = 0; i < 10; i++) \
+ v.v_reserved[i] = v32.v_reserved[i]; \
+ for (i = 0; i < V_NUMPAR; i++) { \
+ v.v_part[i].p_tag = (ushort_t)v32.v_part[i].p_tag; \
+ v.v_part[i].p_flag = (ushort_t)v32.v_part[i].p_flag; \
+ v.v_part[i].p_start = (unsigned)v32.v_part[i].p_start; \
+ v.v_part[i].p_size = (unsigned)v32.v_part[i].p_size; \
+ } \
+ for (i = 0; i < V_NUMPAR; i++) \
+ v.timestamp[i] = (time_t)v32.timestamp[i]; \
+ bcopy(v32.v_asciilabel, v.v_asciilabel, LEN_DKL_ASCII); \
+ }
+
+#define vtoc32toextvtoc(v32, extv) \
+ { \
+ int i; \
+ extv.v_bootinfo[0] = v32.v_bootinfo[0]; \
+ extv.v_bootinfo[1] = v32.v_bootinfo[1]; \
+ extv.v_bootinfo[2] = v32.v_bootinfo[2]; \
+ extv.v_sanity = v32.v_sanity; \
+ extv.v_version = v32.v_version; \
+ bcopy(v32.v_volume, extv.v_volume, LEN_DKL_VVOL); \
+ extv.v_sectorsz = v32.v_sectorsz; \
+ extv.v_nparts = v32.v_nparts; \
+ extv.v_version = v32.v_version; \
+ for (i = 0; i < 10; i++) \
+ extv.v_reserved[i] = v32.v_reserved[i]; \
+ for (i = 0; i < V_NUMPAR; i++) { \
+ extv.v_part[i].p_tag = (ushort_t)v32.v_part[i].p_tag; \
+ extv.v_part[i].p_flag = (ushort_t)v32.v_part[i].p_flag; \
+ extv.v_part[i].p_start = (diskaddr_t)v32.v_part[i].p_start; \
+ extv.v_part[i].p_size = (diskaddr_t)v32.v_part[i].p_size; \
+ extv.timestamp[i] = (time_t)v32.timestamp[i]; \
+ } \
+ bcopy(v32.v_asciilabel, extv.v_asciilabel, LEN_DKL_ASCII); \
+ }
+
+
+#define vtoctovtoc32(v, v32) \
+ { \
+ int i; \
+ v32.v_bootinfo[0] = v.v_bootinfo[0]; \
+ v32.v_bootinfo[1] = v.v_bootinfo[1]; \
+ v32.v_bootinfo[2] = v.v_bootinfo[2]; \
+ v32.v_sanity = v.v_sanity; \
+ v32.v_version = v.v_version; \
+ bcopy(v.v_volume, v32.v_volume, LEN_DKL_VVOL); \
+ v32.v_sectorsz = v.v_sectorsz; \
+ v32.v_nparts = v.v_nparts; \
+ v32.v_version = v.v_version; \
+ for (i = 0; i < 10; i++) \
+ v32.v_reserved[i] = v.v_reserved[i]; \
+ for (i = 0; i < V_NUMPAR; i++) { \
+ v32.v_part[i].p_tag = (ushort_t)v.v_part[i].p_tag; \
+ v32.v_part[i].p_flag = (ushort_t)v.v_part[i].p_flag; \
+ v32.v_part[i].p_start = (unsigned)v.v_part[i].p_start; \
+ v32.v_part[i].p_size = (unsigned)v.v_part[i].p_size; \
+ } \
+ for (i = 0; i < V_NUMPAR; i++) { \
+ if (v.timestamp[i] > TIME32_MAX) \
+ v32.timestamp[i] = TIME32_MAX; \
+ else \
+ v32.timestamp[i] = (time32_t)v.timestamp[i]; \
+ } \
+ bcopy(v.v_asciilabel, v32.v_asciilabel, LEN_DKL_ASCII); \
+ }
+
+#define extvtoctovtoc32(extv, v32) \
+ { \
+ int i; \
+ v32.v_bootinfo[0] = extv.v_bootinfo[0]; \
+ v32.v_bootinfo[1] = extv.v_bootinfo[1]; \
+ v32.v_bootinfo[2] = extv.v_bootinfo[2]; \
+ v32.v_sanity = extv.v_sanity; \
+ v32.v_version = extv.v_version; \
+ bcopy(extv.v_volume, v32.v_volume, LEN_DKL_VVOL); \
+ v32.v_sectorsz = extv.v_sectorsz; \
+ v32.v_nparts = extv.v_nparts; \
+ v32.v_version = extv.v_version; \
+ for (i = 0; i < 10; i++) \
+ v32.v_reserved[i] = extv.v_reserved[i]; \
+ for (i = 0; i < V_NUMPAR; i++) { \
+ v32.v_part[i].p_tag = (ushort_t)extv.v_part[i].p_tag; \
+ v32.v_part[i].p_flag = (ushort_t)extv.v_part[i].p_flag; \
+ v32.v_part[i].p_start = (unsigned)extv.v_part[i].p_start; \
+ v32.v_part[i].p_size = (unsigned)extv.v_part[i].p_size; \
+ } \
+ for (i = 0; i < V_NUMPAR; i++) { \
+ if (extv.timestamp[i] > TIME32_MAX) \
+ v32.timestamp[i] = TIME32_MAX; \
+ else \
+ v32.timestamp[i] = (time32_t)extv.timestamp[i]; \
+ } \
+ bcopy(extv.v_asciilabel, v32.v_asciilabel, LEN_DKL_ASCII); \
+ }
+
+
+#endif /* _SYSCALL32 */
+
+/*
+ * These defines are the mode parameter for the checksum routines.
+ */
+#define CK_CHECKSUM 0 /* check checksum */
+#define CK_MAKESUM 1 /* generate checksum */
+
+#if defined(__STDC__)
+
+extern int read_vtoc(int, struct vtoc *);
+extern int write_vtoc(int, struct vtoc *);
+extern int read_extvtoc(int, struct extvtoc *);
+extern int write_extvtoc(int, struct extvtoc *);
+
+#else
+
+extern int read_vtoc();
+extern int write_vtoc();
+extern int read_extvtoc();
+extern int write_extvtoc();
+
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_VTOC_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/zone.h b/sys/contrib/openzfs/lib/libspl/include/sys/zone.h
new file mode 100644
index 000000000000..bbb964dcef22
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/zone.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_ZONE_H
+#define _LIBSPL_SYS_ZONE_H
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/thread.h b/sys/contrib/openzfs/lib/libspl/include/thread.h
new file mode 100644
index 000000000000..74694e23eed5
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/thread.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_THREAD_H
+#define _LIBSPL_THREAD_H
+
+#endif /* _LIBSPL_THREAD_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/tzfile.h b/sys/contrib/openzfs/lib/libspl/include/tzfile.h
new file mode 100644
index 000000000000..7bd4087cd5d1
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/tzfile.h
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_TZFILE_H
+#define _LIBSPL_TZFILE_H
+
+#include <sys/tzfile.h>
+
+#endif /* _LIBSPL_TZFILE_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/ucred.h b/sys/contrib/openzfs/lib/libspl/include/ucred.h
new file mode 100644
index 000000000000..8178fdec4c74
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/ucred.h
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_UCRED_H
+#define _LIBSPL_UCRED_H
+
+typedef int ucred_t;
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/umem.h b/sys/contrib/openzfs/lib/libspl/include/umem.h
new file mode 100644
index 000000000000..65f12595e64f
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/umem.h
@@ -0,0 +1,208 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_UMEM_H
+#define _LIBSPL_UMEM_H
+
+/*
+ * XXX: We should use the real portable umem library if it is detected
+ * at configure time. However, if the library is not available, we can
+ * use a trivial malloc based implementation. This obviously impacts
+ * performance, but unless you are using a full userspace build of zpool for
+ * something other than ztest, you are likely not going to notice or care.
+ *
+ * https://labs.omniti.com/trac/portableumem
+ */
+#include <sys/debug.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void vmem_t;
+
+/*
+ * Flags for umem_alloc/umem_free
+ */
+#define UMEM_DEFAULT 0x0000 /* normal -- may fail */
+#define UMEM_NOFAIL 0x0100 /* Never fails */
+
+/*
+ * Flags for umem_cache_create()
+ */
+#define UMC_NODEBUG 0x00020000
+
+#define UMEM_CACHE_NAMELEN 31
+
+typedef int umem_nofail_callback_t(void);
+typedef int umem_constructor_t(void *, void *, int);
+typedef void umem_destructor_t(void *, void *);
+typedef void umem_reclaim_t(void *);
+
+typedef struct umem_cache {
+ char cache_name[UMEM_CACHE_NAMELEN + 1];
+ size_t cache_bufsize;
+ size_t cache_align;
+ umem_constructor_t *cache_constructor;
+ umem_destructor_t *cache_destructor;
+ umem_reclaim_t *cache_reclaim;
+ void *cache_private;
+ void *cache_arena;
+ int cache_cflags;
+} umem_cache_t;
+
+/* Prototypes for functions to provide defaults for umem envvars */
+const char *_umem_debug_init(void);
+const char *_umem_options_init(void);
+const char *_umem_logging_init(void);
+
+static inline void *
+umem_alloc(size_t size, int flags)
+{
+ void *ptr = NULL;
+
+ do {
+ ptr = malloc(size);
+ } while (ptr == NULL && (flags & UMEM_NOFAIL));
+
+ return (ptr);
+}
+
+static inline void *
+umem_alloc_aligned(size_t size, size_t align, int flags)
+{
+ void *ptr = NULL;
+ int rc = EINVAL;
+
+ do {
+ rc = posix_memalign(&ptr, align, size);
+ } while (rc == ENOMEM && (flags & UMEM_NOFAIL));
+
+ if (rc == EINVAL) {
+ fprintf(stderr, "%s: invalid memory alignment (%zd)\n",
+ __func__, align);
+ if (flags & UMEM_NOFAIL)
+ abort();
+ return (NULL);
+ }
+
+ return (ptr);
+}
+
+static inline void *
+umem_zalloc(size_t size, int flags)
+{
+ void *ptr = NULL;
+
+ ptr = umem_alloc(size, flags);
+ if (ptr)
+ memset(ptr, 0, size);
+
+ return (ptr);
+}
+
+static inline void
+umem_free(void *ptr, size_t size __maybe_unused)
+{
+ free(ptr);
+}
+
+static inline void
+umem_nofail_callback(umem_nofail_callback_t *cb __maybe_unused)
+{}
+
+static inline umem_cache_t *
+umem_cache_create(
+ char *name, size_t bufsize, size_t align,
+ umem_constructor_t *constructor,
+ umem_destructor_t *destructor,
+ umem_reclaim_t *reclaim,
+ void *priv, void *vmp, int cflags)
+{
+ umem_cache_t *cp;
+
+ cp = (umem_cache_t *)umem_alloc(sizeof (umem_cache_t), UMEM_DEFAULT);
+ if (cp) {
+ strlcpy(cp->cache_name, name, UMEM_CACHE_NAMELEN);
+ cp->cache_bufsize = bufsize;
+ cp->cache_align = align;
+ cp->cache_constructor = constructor;
+ cp->cache_destructor = destructor;
+ cp->cache_reclaim = reclaim;
+ cp->cache_private = priv;
+ cp->cache_arena = vmp;
+ cp->cache_cflags = cflags;
+ }
+
+ return (cp);
+}
+
+static inline void
+umem_cache_destroy(umem_cache_t *cp)
+{
+ umem_free(cp, sizeof (umem_cache_t));
+}
+
+static inline void *
+umem_cache_alloc(umem_cache_t *cp, int flags)
+{
+ void *ptr = NULL;
+
+ if (cp->cache_align != 0)
+ ptr = umem_alloc_aligned(
+ cp->cache_bufsize, cp->cache_align, flags);
+ else
+ ptr = umem_alloc(cp->cache_bufsize, flags);
+
+ if (ptr && cp->cache_constructor)
+ cp->cache_constructor(ptr, cp->cache_private, UMEM_DEFAULT);
+
+ return (ptr);
+}
+
+static inline void
+umem_cache_free(umem_cache_t *cp, void *ptr)
+{
+ if (cp->cache_destructor)
+ cp->cache_destructor(ptr, cp->cache_private);
+
+ umem_free(ptr, cp->cache_bufsize);
+}
+
+static inline void
+umem_cache_reap_now(umem_cache_t *cp __maybe_unused)
+{
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/unistd.h b/sys/contrib/openzfs/lib/libspl/include/unistd.h
new file mode 100644
index 000000000000..0246991b4b61
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/unistd.h
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include_next <unistd.h>
+
+#ifndef _LIBSPL_UNISTD_H
+#define _LIBSPL_UNISTD_H
+
+#include <sys/ioctl.h>
+
+#if !defined(HAVE_ISSETUGID)
+#include <sys/types.h>
+#define issetugid() (geteuid() == 0 || getegid() == 0)
+#endif
+
+#endif /* _LIBSPL_UNISTD_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/util/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/util/Makefile.am
new file mode 100644
index 000000000000..ab553bc80313
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/util/Makefile.am
@@ -0,0 +1,3 @@
+libspldir = $(includedir)/libspl
+libspl_HEADERS = \
+ sscanf.h
diff --git a/sys/contrib/openzfs/lib/libspl/include/util/sscanf.h b/sys/contrib/openzfs/lib/libspl/include/util/sscanf.h
new file mode 100644
index 000000000000..ead36acaba3e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/util/sscanf.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_UTIL_SSCANF_H
+#define _LIBSPL_UTIL_SSCANF_H
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/zone.h b/sys/contrib/openzfs/lib/libspl/include/zone.h
new file mode 100644
index 000000000000..b4a6deb40ce4
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/zone.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_ZONE_H
+#define _LIBSPL_ZONE_H
+
+
+
+#include <sys/types.h>
+#include <sys/zone.h>
+#include <sys/priv.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GLOBAL_ZONEID 0
+#define GLOBAL_ZONEID_NAME "global"
+
+/*
+ * Functions for mapping between id and name for active zones.
+ */
+extern zoneid_t getzoneid(void);
+extern zoneid_t getzoneidbyname(const char *);
+extern ssize_t getzonenamebyid(zoneid_t, char *, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBSPL_ZONE_H */
diff --git a/sys/contrib/openzfs/lib/libspl/list.c b/sys/contrib/openzfs/lib/libspl/list.c
new file mode 100644
index 000000000000..0f2f3731b235
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/list.c
@@ -0,0 +1,243 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Generic doubly-linked list implementation
+ */
+
+#include <sys/list.h>
+#include <sys/list_impl.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/debug.h>
+
+#define list_d2l(a, obj) ((list_node_t *)(((char *)obj) + (a)->list_offset))
+#define list_object(a, node) ((void *)(((char *)node) - (a)->list_offset))
+#define list_empty(a) ((a)->list_head.next == &(a)->list_head)
+
+#define list_insert_after_node(list, node, object) { \
+ list_node_t *lnew = list_d2l(list, object); \
+ lnew->prev = (node); \
+ lnew->next = (node)->next; \
+ (node)->next->prev = lnew; \
+ (node)->next = lnew; \
+}
+
+#define list_insert_before_node(list, node, object) { \
+ list_node_t *lnew = list_d2l(list, object); \
+ lnew->next = (node); \
+ lnew->prev = (node)->prev; \
+ (node)->prev->next = lnew; \
+ (node)->prev = lnew; \
+}
+
+#define list_remove_node(node) \
+ (node)->prev->next = (node)->next; \
+ (node)->next->prev = (node)->prev; \
+ (node)->next = (node)->prev = NULL
+
+void
+list_create(list_t *list, size_t size, size_t offset)
+{
+ ASSERT(list);
+ ASSERT(size > 0);
+ ASSERT(size >= offset + sizeof (list_node_t));
+
+ list->list_size = size;
+ list->list_offset = offset;
+ list->list_head.next = list->list_head.prev = &list->list_head;
+}
+
+void
+list_destroy(list_t *list)
+{
+ list_node_t *node = &list->list_head;
+
+ ASSERT(list);
+ ASSERT(list->list_head.next == node);
+ ASSERT(list->list_head.prev == node);
+
+ node->next = node->prev = NULL;
+}
+
+void
+list_insert_after(list_t *list, void *object, void *nobject)
+{
+ if (object == NULL) {
+ list_insert_head(list, nobject);
+ } else {
+ list_node_t *lold = list_d2l(list, object);
+ list_insert_after_node(list, lold, nobject);
+ }
+}
+
+void
+list_insert_before(list_t *list, void *object, void *nobject)
+{
+ if (object == NULL) {
+ list_insert_tail(list, nobject);
+ } else {
+ list_node_t *lold = list_d2l(list, object);
+ list_insert_before_node(list, lold, nobject);
+ }
+}
+
+void
+list_insert_head(list_t *list, void *object)
+{
+ list_node_t *lold = &list->list_head;
+ list_insert_after_node(list, lold, object);
+}
+
+void
+list_insert_tail(list_t *list, void *object)
+{
+ list_node_t *lold = &list->list_head;
+ list_insert_before_node(list, lold, object);
+}
+
+void
+list_remove(list_t *list, void *object)
+{
+ list_node_t *lold = list_d2l(list, object);
+ ASSERT(!list_empty(list));
+ ASSERT(lold->next != NULL);
+ list_remove_node(lold);
+}
+
+void *
+list_remove_head(list_t *list)
+{
+ list_node_t *head = list->list_head.next;
+ if (head == &list->list_head)
+ return (NULL);
+ list_remove_node(head);
+ return (list_object(list, head));
+}
+
+void *
+list_remove_tail(list_t *list)
+{
+ list_node_t *tail = list->list_head.prev;
+ if (tail == &list->list_head)
+ return (NULL);
+ list_remove_node(tail);
+ return (list_object(list, tail));
+}
+
+void *
+list_head(list_t *list)
+{
+ if (list_empty(list))
+ return (NULL);
+ return (list_object(list, list->list_head.next));
+}
+
+void *
+list_tail(list_t *list)
+{
+ if (list_empty(list))
+ return (NULL);
+ return (list_object(list, list->list_head.prev));
+}
+
+void *
+list_next(list_t *list, void *object)
+{
+ list_node_t *node = list_d2l(list, object);
+
+ if (node->next != &list->list_head)
+ return (list_object(list, node->next));
+
+ return (NULL);
+}
+
+void *
+list_prev(list_t *list, void *object)
+{
+ list_node_t *node = list_d2l(list, object);
+
+ if (node->prev != &list->list_head)
+ return (list_object(list, node->prev));
+
+ return (NULL);
+}
+
+/*
+ * Insert src list after dst list. Empty src list thereafter.
+ */
+void
+list_move_tail(list_t *dst, list_t *src)
+{
+ list_node_t *dstnode = &dst->list_head;
+ list_node_t *srcnode = &src->list_head;
+
+ ASSERT(dst->list_size == src->list_size);
+ ASSERT(dst->list_offset == src->list_offset);
+
+ if (list_empty(src))
+ return;
+
+ dstnode->prev->next = srcnode->next;
+ srcnode->next->prev = dstnode->prev;
+ dstnode->prev = srcnode->prev;
+ srcnode->prev->next = dstnode;
+
+ /* empty src list */
+ srcnode->next = srcnode->prev = srcnode;
+}
+
+void
+list_link_replace(list_node_t *lold, list_node_t *lnew)
+{
+ ASSERT(list_link_active(lold));
+ ASSERT(!list_link_active(lnew));
+
+ lnew->next = lold->next;
+ lnew->prev = lold->prev;
+ lold->prev->next = lnew;
+ lold->next->prev = lnew;
+ lold->next = lold->prev = NULL;
+}
+
+void
+list_link_init(list_node_t *ln)
+{
+ ln->next = NULL;
+ ln->prev = NULL;
+}
+
+int
+list_link_active(list_node_t *ln)
+{
+ EQUIV(ln->next == NULL, ln->prev == NULL);
+ return (ln->next != NULL);
+}
+
+int
+list_is_empty(list_t *list)
+{
+ return (list_empty(list));
+}
diff --git a/sys/contrib/openzfs/lib/libspl/mkdirp.c b/sys/contrib/openzfs/lib/libspl/mkdirp.c
new file mode 100644
index 000000000000..fce2c1c82eb7
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/mkdirp.c
@@ -0,0 +1,212 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+/*
+ * Creates directory and it's parents if the parents do not
+ * exist yet.
+ *
+ * Returns -1 if fails for reasons other than non-existing
+ * parents.
+ * Does NOT simplify pathnames with . or .. in them.
+ */
+
+#include <sys/types.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+static char *simplify(const char *str);
+
+int
+mkdirp(const char *d, mode_t mode)
+{
+ char *endptr, *ptr, *slash, *str;
+
+ str = simplify(d);
+
+ /* If space couldn't be allocated for the simplified names, return. */
+
+ if (str == NULL)
+ return (-1);
+
+ /* Try to make the directory */
+
+ if (mkdir(str, mode) == 0) {
+ free(str);
+ return (0);
+ }
+ if (errno != ENOENT) {
+ free(str);
+ return (-1);
+ }
+ endptr = strrchr(str, '\0');
+ slash = strrchr(str, '/');
+
+ /* Search upward for the non-existing parent */
+
+ while (slash != NULL) {
+
+ ptr = slash;
+ *ptr = '\0';
+
+ /* If reached an existing parent, break */
+
+ if (access(str, F_OK) == 0)
+ break;
+
+ /* If non-existing parent */
+
+ else {
+ slash = strrchr(str, '/');
+
+ /* If under / or current directory, make it. */
+
+ if (slash == NULL || slash == str) {
+ if (mkdir(str, mode) != 0 && errno != EEXIST) {
+ free(str);
+ return (-1);
+ }
+ break;
+ }
+ }
+ }
+
+ /* Create directories starting from upmost non-existing parent */
+
+ while ((ptr = strchr(str, '\0')) != endptr) {
+ *ptr = '/';
+ if (mkdir(str, mode) != 0 && errno != EEXIST) {
+ /*
+ * If the mkdir fails because str already
+ * exists (EEXIST), then str has the form
+ * "existing-dir/..", and this is really
+ * ok. (Remember, this loop is creating the
+ * portion of the path that didn't exist)
+ */
+ free(str);
+ return (-1);
+ }
+ }
+ free(str);
+ return (0);
+}
+
+/*
+ * simplify - given a pathname, simplify that path by removing
+ * duplicate contiguous slashes.
+ *
+ * A simplified copy of the argument is returned to the
+ * caller, or NULL is returned on error.
+ *
+ * The caller should handle error reporting based upon the
+ * returned value, and should free the returned value,
+ * when appropriate.
+ */
+
+static char *
+simplify(const char *str)
+{
+ int i;
+ size_t mbPathlen; /* length of multi-byte path */
+ size_t wcPathlen; /* length of wide-character path */
+ wchar_t *wptr; /* scratch pointer */
+ wchar_t *wcPath; /* wide-character version of the path */
+ char *mbPath; /* The copy fo the path to be returned */
+
+ /*
+ * bail out if there is nothing there.
+ */
+
+ if (!str) {
+ errno = ENOENT;
+ return (NULL);
+ }
+
+ /*
+ * Get a copy of the argument.
+ */
+
+ if ((mbPath = strdup(str)) == NULL) {
+ return (NULL);
+ }
+
+ /*
+ * convert the multi-byte version of the path to a
+ * wide-character rendering, for doing our figuring.
+ */
+
+ mbPathlen = strlen(mbPath);
+
+ if ((wcPath = calloc(mbPathlen+1, sizeof (wchar_t))) == NULL) {
+ free(mbPath);
+ return (NULL);
+ }
+
+ if ((wcPathlen = mbstowcs(wcPath, mbPath, mbPathlen)) == (size_t)-1) {
+ free(mbPath);
+ free(wcPath);
+ return (NULL);
+ }
+
+ /*
+ * remove duplicate slashes first ("//../" -> "/")
+ */
+
+ for (wptr = wcPath, i = 0; i < wcPathlen; i++) {
+ *wptr++ = wcPath[i];
+
+ if (wcPath[i] == '/') {
+ i++;
+
+ while (wcPath[i] == '/') {
+ i++;
+ }
+
+ i--;
+ }
+ }
+
+ *wptr = '\0';
+
+ /*
+ * now convert back to the multi-byte format.
+ */
+
+ if (wcstombs(mbPath, wcPath, mbPathlen) == (size_t)-1) {
+ free(mbPath);
+ free(wcPath);
+ return (NULL);
+ }
+
+ free(wcPath);
+ return (mbPath);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c
new file mode 100644
index 000000000000..2b057cc73016
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+const char *
+getexecname(void)
+{
+ static char execname[PATH_MAX + 1] = "";
+ static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+ char *ptr = NULL;
+ ssize_t rc;
+
+ (void) pthread_mutex_lock(&mtx);
+
+ if (strlen(execname) == 0) {
+ int error, name[4];
+ size_t len;
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = KERN_PROC_PATHNAME;
+ name[3] = -1;
+ len = PATH_MAX;
+ error = sysctl(name, nitems(name), execname, &len, NULL, 0);
+ if (error != 0) {
+ rc = -1;
+ } else {
+ rc = len;
+ }
+ if (rc == -1) {
+ execname[0] = '\0';
+ } else {
+ execname[rc] = '\0';
+ ptr = execname;
+ }
+ } else {
+ ptr = execname;
+ }
+
+ (void) pthread_mutex_unlock(&mtx);
+ return (ptr);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/gethostid.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/gethostid.c
new file mode 100644
index 000000000000..7bd567fe61b5
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/gethostid.c
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2017, Lawrence Livermore National Security, LLC.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/systeminfo.h>
+
+unsigned long
+get_system_hostid(void)
+{
+ return (gethostid());
+}
diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/getmntany.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/getmntany.c
new file mode 100644
index 000000000000..b41e763cee43
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/getmntany.c
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Ricardo Correia. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <sys/mnttab.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define BUFSIZE (MNT_LINE_MAX + 2)
+
+__thread char buf[BUFSIZE];
+
+int
+getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
+{
+ struct statfs sfs;
+
+ if (strlen(path) >= MAXPATHLEN) {
+ (void) fprintf(stderr, "invalid object; pathname too long\n");
+ return (-1);
+ }
+
+ if (stat64(path, statbuf) != 0) {
+ (void) fprintf(stderr, "cannot open '%s': %s\n",
+ path, strerror(errno));
+ return (-1);
+ }
+
+ if (statfs(path, &sfs) != 0) {
+ (void) fprintf(stderr, "%s: %s\n", path,
+ strerror(errno));
+ return (-1);
+ }
+ statfs2mnttab(&sfs, (struct mnttab *)entry);
+ return (0);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c
new file mode 100644
index 000000000000..5b9e6429d9e3
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This file implements Solaris compatible getmntany() and hasmntopt()
+ * functions.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char *
+mntopt(char **p)
+{
+ char *cp = *p;
+ char *retstr;
+
+ while (*cp && isspace(*cp))
+ cp++;
+
+ retstr = cp;
+ while (*cp && *cp != ',')
+ cp++;
+
+ if (*cp) {
+ *cp = '\0';
+ cp++;
+ }
+
+ *p = cp;
+ return (retstr);
+}
+
+char *
+hasmntopt(struct mnttab *mnt, char *opt)
+{
+ char tmpopts[MNT_LINE_MAX];
+ char *f, *opts = tmpopts;
+
+ if (mnt->mnt_mntopts == NULL)
+ return (NULL);
+ (void) strcpy(opts, mnt->mnt_mntopts);
+ f = mntopt(&opts);
+ for (; *f; f = mntopt(&opts)) {
+ if (strncmp(opt, f, strlen(opt)) == 0)
+ return (f - tmpopts + mnt->mnt_mntopts);
+ }
+ return (NULL);
+}
+
+static void
+optadd(char *mntopts, size_t size, const char *opt)
+{
+
+ if (mntopts[0] != '\0')
+ strlcat(mntopts, ",", size);
+ strlcat(mntopts, opt, size);
+}
+
+void
+statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
+{
+ static char mntopts[MNTMAXSTR];
+ long flags;
+
+ mntopts[0] = '\0';
+
+ flags = sfs->f_flags;
+#define OPTADD(opt) optadd(mntopts, sizeof (mntopts), (opt))
+ if (flags & MNT_RDONLY)
+ OPTADD(MNTOPT_RO);
+ else
+ OPTADD(MNTOPT_RW);
+ if (flags & MNT_NOSUID)
+ OPTADD(MNTOPT_NOSETUID);
+ else
+ OPTADD(MNTOPT_SETUID);
+ if (flags & MNT_UPDATE)
+ OPTADD(MNTOPT_REMOUNT);
+ if (flags & MNT_NOATIME)
+ OPTADD(MNTOPT_NOATIME);
+ else
+ OPTADD(MNTOPT_ATIME);
+ OPTADD(MNTOPT_NOXATTR);
+ if (flags & MNT_NOEXEC)
+ OPTADD(MNTOPT_NOEXEC);
+ else
+ OPTADD(MNTOPT_EXEC);
+#undef OPTADD
+ mp->mnt_special = strdup(sfs->f_mntfromname);
+ mp->mnt_mountp = strdup(sfs->f_mntonname);
+ mp->mnt_fstype = strdup(sfs->f_fstypename);
+ mp->mnt_mntopts = strdup(mntopts);
+}
+
+static struct statfs *gsfs = NULL;
+static int allfs = 0;
+
+static int
+statfs_init(void)
+{
+ struct statfs *sfs;
+ int error;
+
+ if (gsfs != NULL) {
+ free(gsfs);
+ gsfs = NULL;
+ }
+ allfs = getfsstat(NULL, 0, MNT_WAIT);
+ if (allfs == -1)
+ goto fail;
+ gsfs = malloc(sizeof (gsfs[0]) * allfs * 2);
+ if (gsfs == NULL)
+ goto fail;
+ allfs = getfsstat(gsfs, (long)(sizeof (gsfs[0]) * allfs * 2),
+ MNT_WAIT);
+ if (allfs == -1)
+ goto fail;
+ sfs = realloc(gsfs, allfs * sizeof (gsfs[0]));
+ if (sfs != NULL)
+ gsfs = sfs;
+ return (0);
+fail:
+ error = errno;
+ if (gsfs != NULL)
+ free(gsfs);
+ gsfs = NULL;
+ allfs = 0;
+ return (error);
+}
+
+int
+getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
+{
+ // struct statfs *sfs;
+ int i, error;
+
+ error = statfs_init();
+ if (error != 0)
+ return (error);
+
+ for (i = 0; i < allfs; i++) {
+ if (mrefp->mnt_special != NULL &&
+ strcmp(mrefp->mnt_special, gsfs[i].f_mntfromname) != 0) {
+ continue;
+ }
+ if (mrefp->mnt_mountp != NULL &&
+ strcmp(mrefp->mnt_mountp, gsfs[i].f_mntonname) != 0) {
+ continue;
+ }
+ if (mrefp->mnt_fstype != NULL &&
+ strcmp(mrefp->mnt_fstype, gsfs[i].f_fstypename) != 0) {
+ continue;
+ }
+ statfs2mnttab(&gsfs[i], mgetp);
+ return (0);
+ }
+ return (-1);
+}
+
+int
+getmntent(FILE *fp, struct mnttab *mp)
+{
+ // struct statfs *sfs;
+ int error, nfs;
+
+ nfs = (int)lseek(fileno(fp), 0, SEEK_CUR);
+ if (nfs == -1)
+ return (errno);
+ /* If nfs is 0, we want to refresh out cache. */
+ if (nfs == 0 || gsfs == NULL) {
+ error = statfs_init();
+ if (error != 0)
+ return (error);
+ }
+ if (nfs >= allfs)
+ return (-1);
+ statfs2mnttab(&gsfs[nfs], mp);
+ if (lseek(fileno(fp), 1, SEEK_CUR) == -1)
+ return (errno);
+ return (0);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c b/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c
new file mode 100644
index 000000000000..6352a1a34015
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#include <limits.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+const char *
+getexecname(void)
+{
+ static char execname[PATH_MAX + 1] = "";
+ static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+ char *ptr = NULL;
+ ssize_t rc;
+
+ (void) pthread_mutex_lock(&mtx);
+
+ if (strlen(execname) == 0) {
+ rc = readlink("/proc/self/exe",
+ execname, sizeof (execname) - 1);
+ if (rc == -1) {
+ execname[0] = '\0';
+ } else {
+ execname[rc] = '\0';
+ ptr = execname;
+ }
+ } else {
+ ptr = execname;
+ }
+
+ (void) pthread_mutex_unlock(&mtx);
+ return (ptr);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c b/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c
new file mode 100644
index 000000000000..1eb93f441142
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c
@@ -0,0 +1,86 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2017, Lawrence Livermore National Security, LLC.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/systeminfo.h>
+
+static unsigned long
+get_spl_hostid(void)
+{
+ FILE *f;
+ unsigned long hostid;
+ char *env;
+
+ /*
+ * Allow the hostid to be subverted for testing.
+ */
+ env = getenv("ZFS_HOSTID");
+ if (env) {
+ hostid = strtoull(env, NULL, 0);
+ return (hostid & HOSTID_MASK);
+ }
+
+ f = fopen("/sys/module/spl/parameters/spl_hostid", "r");
+ if (!f)
+ return (0);
+
+ if (fscanf(f, "%lu", &hostid) != 1)
+ hostid = 0;
+
+ fclose(f);
+
+ return (hostid & HOSTID_MASK);
+}
+
+unsigned long
+get_system_hostid(void)
+{
+ unsigned long system_hostid = get_spl_hostid();
+ /*
+ * We do not use the library call gethostid() because
+ * it generates a hostid value that the kernel is
+ * unaware of, if the spl_hostid module parameter has not
+ * been set and there is no system hostid file (e.g.
+ * /etc/hostid). The kernel and userspace must agree.
+ * See comments above hostid_read() in the SPL.
+ */
+ if (system_hostid == 0) {
+ int fd, rc;
+ unsigned long hostid;
+ int hostid_size = 4; /* 4 bytes regardless of arch */
+
+ fd = open("/etc/hostid", O_RDONLY);
+ if (fd >= 0) {
+ rc = read(fd, &hostid, hostid_size);
+ if (rc > 0)
+ system_hostid = (hostid & HOSTID_MASK);
+ close(fd);
+ }
+ }
+ return (system_hostid);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c b/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c
new file mode 100644
index 000000000000..f42fcc047893
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c
@@ -0,0 +1,165 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Ricardo Correia. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+#include <stdio.h>
+#include <string.h>
+#include <mntent.h>
+#include <sys/errno.h>
+#include <sys/mnttab.h>
+
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define BUFSIZE (MNT_LINE_MAX + 2)
+
+__thread char buf[BUFSIZE];
+
+#define DIFF(xx) ( \
+ (mrefp->xx != NULL) && \
+ (mgetp->xx == NULL || strcmp(mrefp->xx, mgetp->xx) != 0))
+
+int
+getmntany(FILE *fp, struct mnttab *mgetp, struct mnttab *mrefp)
+{
+ int ret;
+
+ while (
+ ((ret = _sol_getmntent(fp, mgetp)) == 0) && (
+ DIFF(mnt_special) || DIFF(mnt_mountp) ||
+ DIFF(mnt_fstype) || DIFF(mnt_mntopts))) { }
+
+ return (ret);
+}
+
+int
+_sol_getmntent(FILE *fp, struct mnttab *mgetp)
+{
+ struct mntent mntbuf;
+ struct mntent *ret;
+
+ ret = getmntent_r(fp, &mntbuf, buf, BUFSIZE);
+
+ if (ret != NULL) {
+ mgetp->mnt_special = mntbuf.mnt_fsname;
+ mgetp->mnt_mountp = mntbuf.mnt_dir;
+ mgetp->mnt_fstype = mntbuf.mnt_type;
+ mgetp->mnt_mntopts = mntbuf.mnt_opts;
+ return (0);
+ }
+
+ if (feof(fp))
+ return (-1);
+
+ return (MNT_TOOLONG);
+}
+
+static int
+getextmntent_impl(FILE *fp, struct extmnttab *mp, int len)
+{
+ int ret;
+ struct stat64 st;
+
+ ret = _sol_getmntent(fp, (struct mnttab *)mp);
+ if (ret == 0) {
+ if (stat64(mp->mnt_mountp, &st) != 0) {
+ mp->mnt_major = 0;
+ mp->mnt_minor = 0;
+ return (ret);
+ }
+ mp->mnt_major = major(st.st_dev);
+ mp->mnt_minor = minor(st.st_dev);
+ }
+
+ return (ret);
+}
+
+int
+getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
+{
+ struct stat64 st;
+ FILE *fp;
+ int match;
+
+ if (strlen(path) >= MAXPATHLEN) {
+ (void) fprintf(stderr, "invalid object; pathname too long\n");
+ return (-1);
+ }
+
+ /*
+ * Search for the path in /proc/self/mounts. Rather than looking for the
+ * specific path, which can be fooled by non-standard paths (i.e. ".."
+ * or "//"), we stat() the path and search for the corresponding
+ * (major,minor) device pair.
+ */
+ if (stat64(path, statbuf) != 0) {
+ (void) fprintf(stderr, "cannot open '%s': %s\n",
+ path, strerror(errno));
+ return (-1);
+ }
+
+
+#ifdef HAVE_SETMNTENT
+ if ((fp = setmntent(MNTTAB, "r")) == NULL) {
+#else
+ if ((fp = fopen(MNTTAB, "r")) == NULL) {
+#endif
+ (void) fprintf(stderr, "cannot open %s\n", MNTTAB);
+ return (-1);
+ }
+
+ /*
+ * Search for the given (major,minor) pair in the mount table.
+ */
+
+ match = 0;
+ while (getextmntent_impl(fp, entry, sizeof (*entry)) == 0) {
+ if (makedev(entry->mnt_major, entry->mnt_minor) ==
+ statbuf->st_dev) {
+ match = 1;
+ break;
+ }
+ }
+
+ if (!match) {
+ (void) fprintf(stderr, "cannot find mountpoint for '%s'\n",
+ path);
+ return (-1);
+ }
+
+ if (stat64(entry->mnt_mountp, &st) != 0) {
+ entry->mnt_major = 0;
+ entry->mnt_minor = 0;
+ return (-1);
+ }
+
+ return (0);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/page.c b/sys/contrib/openzfs/lib/libspl/page.c
new file mode 100644
index 000000000000..06d9fcfa05cc
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/page.c
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#include <unistd.h>
+
+size_t pagesize = 0;
+
+size_t
+spl_pagesize(void)
+{
+ if (pagesize == 0)
+ pagesize = sysconf(_SC_PAGESIZE);
+
+ return (pagesize);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/strlcat.c b/sys/contrib/openzfs/lib/libspl/strlcat.c
new file mode 100644
index 000000000000..4528d875ed5e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/strlcat.c
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef HAVE_STRLCAT
+
+#include <string.h>
+#include <sys/types.h>
+
+/*
+ * Appends src to the dstsize buffer at dst. The append will never
+ * overflow the destination buffer and the buffer will always be null
+ * terminated. Never reference beyond &dst[dstsize-1] when computing
+ * the length of the pre-existing string.
+ */
+
+size_t
+strlcat(char *dst, const char *src, size_t dstsize)
+{
+ char *df = dst;
+ size_t left = dstsize;
+ size_t l1;
+ size_t l2 = strlen(src);
+ size_t copied;
+
+ while (left-- != 0 && *df != '\0')
+ df++;
+ l1 = df - dst;
+ if (dstsize == l1)
+ return (l1 + l2);
+
+ copied = l1 + l2 >= dstsize ? dstsize - l1 - 1 : l2;
+ (void) memcpy(dst + l1, src, copied);
+ dst[l1+copied] = '\0';
+
+ return (l1 + l2);
+}
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/strlcpy.c b/sys/contrib/openzfs/lib/libspl/strlcpy.c
new file mode 100644
index 000000000000..d483b91f6121
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/strlcpy.c
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef HAVE_STRLCPY
+
+#include <string.h>
+#include <sys/types.h>
+
+/*
+ * Copies src to the dstsize buffer at dst. The copy will never
+ * overflow the destination buffer and the buffer will always be null
+ * terminated.
+ */
+
+size_t
+strlcpy(char *dst, const char *src, size_t len)
+{
+ size_t slen = strlen(src);
+ size_t copied;
+
+ if (len == 0)
+ return (slen);
+
+ if (slen >= len)
+ copied = len - 1;
+ else
+ copied = slen;
+ (void) memcpy(dst, src, copied);
+ dst[copied] = '\0';
+ return (slen);
+}
+
+#endif /* HAVE_STRLCPY */
diff --git a/sys/contrib/openzfs/lib/libspl/timestamp.c b/sys/contrib/openzfs/lib/libspl/timestamp.c
new file mode 100644
index 000000000000..22ecb3940739
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/timestamp.c
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <langinfo.h>
+#include "statcommon.h"
+
+#ifndef _DATE_FMT
+#ifdef D_T_FMT
+#define _DATE_FMT D_T_FMT
+#else /* D_T_FMT */
+#define _DATE_FMT "%+"
+#endif /* !D_T_FMT */
+#endif /* _DATE_FMT */
+
+/*
+ * Print timestamp as decimal reprentation of time_t value (-T u was specified)
+ * or in date(1) format (-T d was specified).
+ */
+void
+print_timestamp(uint_t timestamp_fmt)
+{
+ time_t t = time(NULL);
+ static char *fmt = NULL;
+
+ /* We only need to retrieve this once per invocation */
+ if (fmt == NULL)
+ fmt = nl_langinfo(_DATE_FMT);
+
+ if (timestamp_fmt == UDATE) {
+ (void) printf("%lld\n", (longlong_t)t);
+ } else if (timestamp_fmt == DDATE) {
+ char dstr[64];
+ int len;
+
+ len = strftime(dstr, sizeof (dstr), fmt, localtime(&t));
+ if (len > 0)
+ (void) printf("%s\n", dstr);
+ }
+}
diff --git a/sys/contrib/openzfs/lib/libspl/zone.c b/sys/contrib/openzfs/lib/libspl/zone.c
new file mode 100644
index 000000000000..5ca93b224d9e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/zone.c
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Ricardo Correia. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <zone.h>
+#include <string.h>
+#include <errno.h>
+
+zoneid_t
+getzoneid()
+{
+ return (GLOBAL_ZONEID);
+}
+
+zoneid_t
+getzoneidbyname(const char *name)
+{
+ if (name == NULL)
+ return (GLOBAL_ZONEID);
+
+ if (strcmp(name, GLOBAL_ZONEID_NAME) == 0)
+ return (GLOBAL_ZONEID);
+
+ return (EINVAL);
+}
+
+ssize_t
+getzonenamebyid(zoneid_t id, char *buf, size_t buflen)
+{
+ if (id != GLOBAL_ZONEID)
+ return (EINVAL);
+
+ ssize_t ret = strlen(GLOBAL_ZONEID_NAME) + 1;
+
+ if (buf == NULL || buflen == 0)
+ return (ret);
+
+ strncpy(buf, GLOBAL_ZONEID_NAME, buflen);
+ buf[buflen - 1] = '\0';
+
+ return (ret);
+}