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.am27
-rw-r--r--sys/contrib/openzfs/lib/libspl/assert.c70
-rw-r--r--sys/contrib/openzfs/lib/libspl/atomic.c37
-rw-r--r--sys/contrib/openzfs/lib/libspl/backtrace.c303
-rw-r--r--sys/contrib/openzfs/lib/libspl/condvar.c153
-rw-r--r--sys/contrib/openzfs/lib/libspl/cred.c64
-rw-r--r--sys/contrib/openzfs/lib/libspl/getexecname.c3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/Makefile.am38
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/assert.h157
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/atomic.h10
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/libgen.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/libshare.h6
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/libspl.h40
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/fcntl.h1
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/byteorder.h17
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/fcntl.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/file.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/ia32/asm_linkage.h185
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mnttab.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h5
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h7
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/stat.h9
-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.h1
-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/sys/byteorder.h17
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/errno.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/ia32/asm_linkage.h212
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mnttab.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mount.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h5
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/stat.h8
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h33
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/rpc/xdr.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/statcommon.h7
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/stdlib.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/string.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/acl.h7
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/acl_impl.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/asm_linkage.h47
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/backtrace.h (renamed from sys/contrib/openzfs/lib/libspl/include/os/linux/sys/zfs_context_os.h)13
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/callb.h32
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h64
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/condvar.h70
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/cred.h21
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/debug.h31
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/dkio.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/dklabel.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/dktp/fdisk.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h27
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/kmem.h71
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/kstat.h746
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/list.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/list_impl.h4
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/mhd.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/misc.h40
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/mkdev.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/mod.h56
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/mutex.h58
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/policy.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/poll.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/priv.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/processor.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/procfs_list.h71
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/random.h54
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/rwlock.h62
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/sha2.h148
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/sid.h44
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/simd.h192
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/stack.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/string.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h11
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/sysmacros.h (renamed from sys/contrib/openzfs/lib/libspl/include/os/linux/sys/sysmacros.h)55
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/systeminfo.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/systm.h36
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/taskq.h119
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/thread.h79
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/time.h14
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/timer.h64
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/trace.h73
-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/tsd.h42
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/tunables.h63
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/types.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/types32.h8
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/uio.h35
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/vnode.h38
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/wmsum.h1
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/zone.h21
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/umem.h30
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/unistd.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/zone.h3
-rw-r--r--sys/contrib/openzfs/lib/libspl/kmem.c102
-rw-r--r--sys/contrib/openzfs/lib/libspl/kstat.c64
-rw-r--r--sys/contrib/openzfs/lib/libspl/libspl.c67
-rw-r--r--sys/contrib/openzfs/lib/libspl/libspl_impl.h10
-rw-r--r--sys/contrib/openzfs/lib/libspl/list.c7
-rw-r--r--sys/contrib/openzfs/lib/libspl/mkdirp.c3
-rw-r--r--sys/contrib/openzfs/lib/libspl/mutex.c89
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c3
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/freebsd/gethostid.c3
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/freebsd/getmntany.c8
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c6
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/freebsd/zone.c1
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c3
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c9
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c42
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/zone.c13
-rw-r--r--sys/contrib/openzfs/lib/libspl/page.c3
-rw-r--r--sys/contrib/openzfs/lib/libspl/procfs_list.c93
-rw-r--r--sys/contrib/openzfs/lib/libspl/random.c101
-rw-r--r--sys/contrib/openzfs/lib/libspl/rwlock.c108
-rw-r--r--sys/contrib/openzfs/lib/libspl/sid.c47
-rw-r--r--sys/contrib/openzfs/lib/libspl/strlcat.c3
-rw-r--r--sys/contrib/openzfs/lib/libspl/strlcpy.c3
-rw-r--r--sys/contrib/openzfs/lib/libspl/taskq.c425
-rw-r--r--sys/contrib/openzfs/lib/libspl/thread.c118
-rw-r--r--sys/contrib/openzfs/lib/libspl/timestamp.c45
-rw-r--r--sys/contrib/openzfs/lib/libspl/tunables.c319
123 files changed, 4636 insertions, 1221 deletions
diff --git a/sys/contrib/openzfs/lib/libspl/Makefile.am b/sys/contrib/openzfs/lib/libspl/Makefile.am
index 822bef7e7a8d..27f004634487 100644
--- a/sys/contrib/openzfs/lib/libspl/Makefile.am
+++ b/sys/contrib/openzfs/lib/libspl/Makefile.am
@@ -1,24 +1,41 @@
include $(srcdir)/%D%/include/Makefile.am
-libspl_assert_la_CFLAGS = $(AM_CFLAGS) $(LIBRARY_CFLAGS)
+libspl_assert_la_CFLAGS = $(AM_CFLAGS) $(LIBRARY_CFLAGS) $(LIBUNWIND_CFLAGS)
libspl_la_CFLAGS = $(libspl_assert_la_CFLAGS)
+if TARGET_CPU_I386
+libspl_la_CFLAGS += $(NO_ATOMIC_ALIGNMENT)
+endif
noinst_LTLIBRARIES += libspl_assert.la libspl.la
CPPCHECKTARGETS += libspl_assert.la libspl.la
libspl_assert_la_SOURCES = \
- %D%/assert.c
+ %D%/assert.c \
+ %D%/backtrace.c
libspl_la_SOURCES = \
%D%/libspl_impl.h \
%D%/atomic.c \
+ %D%/condvar.c \
+ %D%/cred.c \
%D%/getexecname.c \
+ %D%/kmem.c \
+ %D%/kstat.c \
+ %D%/libspl.c \
%D%/list.c \
%D%/mkdirp.c \
+ %D%/mutex.c \
%D%/page.c \
+ %D%/procfs_list.c \
+ %D%/random.c \
+ %D%/rwlock.c \
+ %D%/sid.c \
%D%/strlcat.c \
%D%/strlcpy.c \
+ %D%/taskq.c \
+ %D%/thread.c \
%D%/timestamp.c \
+ %D%/tunables.c \
%D%/include/sys/list.h \
%D%/include/sys/list_impl.h
@@ -43,3 +60,9 @@ libspl_la_LIBADD = \
libspl_assert.la
libspl_la_LIBADD += $(LIBATOMIC_LIBS) $(LIBCLOCK_GETTIME)
+
+libspl_assert_la_LIBADD = $(BACKTRACE_LIBS) $(LIBUNWIND_LIBS)
+
+if BUILD_FREEBSD
+libspl_assert_la_LIBADD += -lpthread
+endif
diff --git a/sys/contrib/openzfs/lib/libspl/assert.c b/sys/contrib/openzfs/lib/libspl/assert.c
index ad8fdcd8cf0a..54d931104814 100644
--- a/sys/contrib/openzfs/lib/libspl/assert.c
+++ b/sys/contrib/openzfs/lib/libspl/assert.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -22,8 +23,48 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
+ */
#include <assert.h>
+#include <pthread.h>
+#include <sys/backtrace.h>
+
+#if defined(__linux__)
+#include <errno.h>
+#include <sys/prctl.h>
+#ifdef HAVE_GETTID
+#define libspl_gettid() gettid()
+#else
+#include <sys/syscall.h>
+#define libspl_gettid() ((pid_t)syscall(__NR_gettid))
+#endif
+#define libspl_getprogname() (program_invocation_short_name)
+#define libspl_getthreadname(buf, len) \
+ prctl(PR_GET_NAME, (unsigned long)(buf), 0, 0, 0)
+#elif defined(__FreeBSD__) || defined(__APPLE__)
+#if !defined(__APPLE__)
+#include <pthread_np.h>
+#define libspl_gettid() pthread_getthreadid_np()
+#endif
+#define libspl_getprogname() getprogname()
+#define libspl_getthreadname(buf, len) \
+ pthread_getname_np(pthread_self(), buf, len);
+#endif
+
+#if defined(__APPLE__)
+static inline uint64_t
+libspl_gettid(void)
+{
+ uint64_t tid;
+
+ if (pthread_threadid_np(NULL, &tid) != 0)
+ tid = 0;
+
+ return (tid);
+}
+#endif
static boolean_t libspl_assert_ok = B_FALSE;
@@ -33,20 +74,43 @@ libspl_set_assert_ok(boolean_t val)
libspl_assert_ok = val;
}
+static pthread_mutex_t assert_lock = PTHREAD_MUTEX_INITIALIZER;
+
/* printf version of libspl_assert */
void
libspl_assertf(const char *file, const char *func, int line,
const char *format, ...)
{
+ pthread_mutex_lock(&assert_lock);
+
va_list args;
+ char tname[64];
+
+ libspl_getthreadname(tname, sizeof (tname));
+
+ fprintf(stderr, "ASSERT at %s:%d:%s()\n", file, line, func);
va_start(args, format);
vfprintf(stderr, format, args);
- fprintf(stderr, "\n");
- fprintf(stderr, "ASSERT at %s:%d:%s()", file, line, func);
va_end(args);
+
+ fprintf(stderr, "\n"
+ " PID: %-8u COMM: %s\n"
+#if defined(__APPLE__)
+ " TID: %-8" PRIu64 " NAME: %s\n",
+#else
+ " TID: %-8u NAME: %s\n",
+#endif
+ getpid(), libspl_getprogname(),
+ libspl_gettid(), tname);
+
+ libspl_backtrace(STDERR_FILENO);
+
+#if !__has_feature(attribute_analyzer_noreturn) && !defined(__COVERITY__)
if (libspl_assert_ok) {
+ pthread_mutex_unlock(&assert_lock);
return;
}
+#endif
abort();
}
diff --git a/sys/contrib/openzfs/lib/libspl/atomic.c b/sys/contrib/openzfs/lib/libspl/atomic.c
index 9307cea194e6..b5cc4ab2a55f 100644
--- a/sys/contrib/openzfs/lib/libspl/atomic.c
+++ b/sys/contrib/openzfs/lib/libspl/atomic.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -35,7 +36,6 @@
(void) __atomic_add_fetch(target, 1, __ATOMIC_SEQ_CST); \
}
-/* BEGIN CSTYLED */
ATOMIC_INC(8, uint8_t)
ATOMIC_INC(16, uint16_t)
ATOMIC_INC(32, uint32_t)
@@ -44,7 +44,6 @@ ATOMIC_INC(uchar, uchar_t)
ATOMIC_INC(ushort, ushort_t)
ATOMIC_INC(uint, uint_t)
ATOMIC_INC(ulong, ulong_t)
-/* END CSTYLED */
#define ATOMIC_DEC(name, type) \
@@ -53,7 +52,6 @@ ATOMIC_INC(ulong, ulong_t)
(void) __atomic_sub_fetch(target, 1, __ATOMIC_SEQ_CST); \
}
-/* BEGIN CSTYLED */
ATOMIC_DEC(8, uint8_t)
ATOMIC_DEC(16, uint16_t)
ATOMIC_DEC(32, uint32_t)
@@ -62,7 +60,6 @@ ATOMIC_DEC(uchar, uchar_t)
ATOMIC_DEC(ushort, ushort_t)
ATOMIC_DEC(uint, uint_t)
ATOMIC_DEC(ulong, ulong_t)
-/* END CSTYLED */
#define ATOMIC_ADD(name, type1, type2) \
@@ -77,7 +74,6 @@ atomic_add_ptr(volatile void *target, ssize_t bits)
(void) __atomic_add_fetch((void **)target, bits, __ATOMIC_SEQ_CST);
}
-/* BEGIN CSTYLED */
ATOMIC_ADD(8, uint8_t, int8_t)
ATOMIC_ADD(16, uint16_t, int16_t)
ATOMIC_ADD(32, uint32_t, int32_t)
@@ -86,7 +82,6 @@ ATOMIC_ADD(char, uchar_t, signed char)
ATOMIC_ADD(short, ushort_t, short)
ATOMIC_ADD(int, uint_t, int)
ATOMIC_ADD(long, ulong_t, long)
-/* END CSTYLED */
#define ATOMIC_SUB(name, type1, type2) \
@@ -101,7 +96,6 @@ atomic_sub_ptr(volatile void *target, ssize_t bits)
(void) __atomic_sub_fetch((void **)target, bits, __ATOMIC_SEQ_CST);
}
-/* BEGIN CSTYLED */
ATOMIC_SUB(8, uint8_t, int8_t)
ATOMIC_SUB(16, uint16_t, int16_t)
ATOMIC_SUB(32, uint32_t, int32_t)
@@ -110,7 +104,6 @@ ATOMIC_SUB(char, uchar_t, signed char)
ATOMIC_SUB(short, ushort_t, short)
ATOMIC_SUB(int, uint_t, int)
ATOMIC_SUB(long, ulong_t, long)
-/* END CSTYLED */
#define ATOMIC_OR(name, type) \
@@ -119,7 +112,6 @@ ATOMIC_SUB(long, ulong_t, long)
(void) __atomic_or_fetch(target, bits, __ATOMIC_SEQ_CST); \
}
-/* BEGIN CSTYLED */
ATOMIC_OR(8, uint8_t)
ATOMIC_OR(16, uint16_t)
ATOMIC_OR(32, uint32_t)
@@ -128,7 +120,6 @@ ATOMIC_OR(uchar, uchar_t)
ATOMIC_OR(ushort, ushort_t)
ATOMIC_OR(uint, uint_t)
ATOMIC_OR(ulong, ulong_t)
-/* END CSTYLED */
#define ATOMIC_AND(name, type) \
@@ -137,7 +128,6 @@ ATOMIC_OR(ulong, ulong_t)
(void) __atomic_and_fetch(target, bits, __ATOMIC_SEQ_CST); \
}
-/* BEGIN CSTYLED */
ATOMIC_AND(8, uint8_t)
ATOMIC_AND(16, uint16_t)
ATOMIC_AND(32, uint32_t)
@@ -146,7 +136,6 @@ ATOMIC_AND(uchar, uchar_t)
ATOMIC_AND(ushort, ushort_t)
ATOMIC_AND(uint, uint_t)
ATOMIC_AND(ulong, ulong_t)
-/* END CSTYLED */
/*
@@ -159,7 +148,6 @@ ATOMIC_AND(ulong, ulong_t)
return (__atomic_add_fetch(target, 1, __ATOMIC_SEQ_CST)); \
}
-/* BEGIN CSTYLED */
ATOMIC_INC_NV(8, uint8_t)
ATOMIC_INC_NV(16, uint16_t)
ATOMIC_INC_NV(32, uint32_t)
@@ -168,7 +156,6 @@ ATOMIC_INC_NV(uchar, uchar_t)
ATOMIC_INC_NV(ushort, ushort_t)
ATOMIC_INC_NV(uint, uint_t)
ATOMIC_INC_NV(ulong, ulong_t)
-/* END CSTYLED */
#define ATOMIC_DEC_NV(name, type) \
@@ -177,7 +164,6 @@ ATOMIC_INC_NV(ulong, ulong_t)
return (__atomic_sub_fetch(target, 1, __ATOMIC_SEQ_CST)); \
}
-/* BEGIN CSTYLED */
ATOMIC_DEC_NV(8, uint8_t)
ATOMIC_DEC_NV(16, uint16_t)
ATOMIC_DEC_NV(32, uint32_t)
@@ -186,7 +172,6 @@ ATOMIC_DEC_NV(uchar, uchar_t)
ATOMIC_DEC_NV(ushort, ushort_t)
ATOMIC_DEC_NV(uint, uint_t)
ATOMIC_DEC_NV(ulong, ulong_t)
-/* END CSTYLED */
#define ATOMIC_ADD_NV(name, type1, type2) \
@@ -201,7 +186,6 @@ atomic_add_ptr_nv(volatile void *target, ssize_t bits)
return (__atomic_add_fetch((void **)target, bits, __ATOMIC_SEQ_CST));
}
-/* BEGIN CSTYLED */
ATOMIC_ADD_NV(8, uint8_t, int8_t)
ATOMIC_ADD_NV(16, uint16_t, int16_t)
ATOMIC_ADD_NV(32, uint32_t, int32_t)
@@ -210,7 +194,6 @@ ATOMIC_ADD_NV(char, uchar_t, signed char)
ATOMIC_ADD_NV(short, ushort_t, short)
ATOMIC_ADD_NV(int, uint_t, int)
ATOMIC_ADD_NV(long, ulong_t, long)
-/* END CSTYLED */
#define ATOMIC_SUB_NV(name, type1, type2) \
@@ -225,7 +208,6 @@ atomic_sub_ptr_nv(volatile void *target, ssize_t bits)
return (__atomic_sub_fetch((void **)target, bits, __ATOMIC_SEQ_CST));
}
-/* BEGIN CSTYLED */
ATOMIC_SUB_NV(8, uint8_t, int8_t)
ATOMIC_SUB_NV(char, uchar_t, signed char)
ATOMIC_SUB_NV(16, uint16_t, int16_t)
@@ -234,7 +216,6 @@ 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)
-/* END CSTYLED */
#define ATOMIC_OR_NV(name, type) \
@@ -243,7 +224,6 @@ ATOMIC_SUB_NV(64, uint64_t, int64_t)
return (__atomic_or_fetch(target, bits, __ATOMIC_SEQ_CST)); \
}
-/* BEGIN CSTYLED */
ATOMIC_OR_NV(8, uint8_t)
ATOMIC_OR_NV(16, uint16_t)
ATOMIC_OR_NV(32, uint32_t)
@@ -252,7 +232,6 @@ ATOMIC_OR_NV(uchar, uchar_t)
ATOMIC_OR_NV(ushort, ushort_t)
ATOMIC_OR_NV(uint, uint_t)
ATOMIC_OR_NV(ulong, ulong_t)
-/* END CSTYLED */
#define ATOMIC_AND_NV(name, type) \
@@ -261,7 +240,6 @@ ATOMIC_OR_NV(ulong, ulong_t)
return (__atomic_and_fetch(target, bits, __ATOMIC_SEQ_CST)); \
}
-/* BEGIN CSTYLED */
ATOMIC_AND_NV(8, uint8_t)
ATOMIC_AND_NV(16, uint16_t)
ATOMIC_AND_NV(32, uint32_t)
@@ -270,7 +248,6 @@ ATOMIC_AND_NV(uchar, uchar_t)
ATOMIC_AND_NV(ushort, ushort_t)
ATOMIC_AND_NV(uint, uint_t)
ATOMIC_AND_NV(ulong, ulong_t)
-/* END CSTYLED */
/*
@@ -300,7 +277,6 @@ atomic_cas_ptr(volatile void *target, void *exp, void *des)
return (exp);
}
-/* BEGIN CSTYLED */
ATOMIC_CAS(8, uint8_t)
ATOMIC_CAS(16, uint16_t)
ATOMIC_CAS(32, uint32_t)
@@ -309,7 +285,6 @@ ATOMIC_CAS(uchar, uchar_t)
ATOMIC_CAS(ushort, ushort_t)
ATOMIC_CAS(uint, uint_t)
ATOMIC_CAS(ulong, ulong_t)
-/* END CSTYLED */
/*
@@ -322,7 +297,6 @@ ATOMIC_CAS(ulong, ulong_t)
return (__atomic_exchange_n(target, bits, __ATOMIC_SEQ_CST)); \
}
-/* BEGIN CSTYLED */
ATOMIC_SWAP(8, uint8_t)
ATOMIC_SWAP(16, uint16_t)
ATOMIC_SWAP(32, uint32_t)
@@ -331,7 +305,6 @@ ATOMIC_SWAP(uchar, uchar_t)
ATOMIC_SWAP(ushort, ushort_t)
ATOMIC_SWAP(uint, uint_t)
ATOMIC_SWAP(ulong, ulong_t)
-/* END CSTYLED */
void *
atomic_swap_ptr(volatile void *target, void *bits)
@@ -382,6 +355,12 @@ membar_exit(void)
}
void
+membar_sync(void)
+{
+ __atomic_thread_fence(__ATOMIC_SEQ_CST);
+}
+
+void
membar_producer(void)
{
__atomic_thread_fence(__ATOMIC_RELEASE);
diff --git a/sys/contrib/openzfs/lib/libspl/backtrace.c b/sys/contrib/openzfs/lib/libspl/backtrace.c
new file mode 100644
index 000000000000..c4a7006a9692
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/backtrace.c
@@ -0,0 +1,303 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2024, Rob Norris <robn@despairlabs.com>
+ * Copyright (c) 2024, Klara Inc.
+ */
+
+#include <sys/backtrace.h>
+#include <sys/types.h>
+#include <sys/debug.h>
+#include <unistd.h>
+
+/*
+ * Output helpers. libspl_backtrace() must not block, must be thread-safe and
+ * must be safe to call from a signal handler. At least, that means not having
+ * printf, so we end up having to call write() directly on the fd. That's
+ * awkward, as we always have to pass through a length, and some systems will
+ * complain if we don't consume the return. So we have some macros to make
+ * things a little more palatable.
+ */
+#define spl_bt_write_n(fd, s, n) \
+ do { ssize_t r __maybe_unused = write(fd, s, n); } while (0)
+#define spl_bt_write(fd, s) spl_bt_write_n(fd, s, sizeof (s)-1)
+
+#ifdef HAVE_LIBUNWIND
+/*
+ * libunwind-gcc and libunwind-llvm both list registers using an enum,
+ * unw_regnum_t, however they indicate the highest numbered register for
+ * a given architecture in different ways. We can check which one is defined
+ * and mark which libunwind is in use
+ */
+#ifdef IS_LIBUNWIND_LLVM
+#include <libunwind.h>
+#define LAST_REG_INDEX _LIBUNWIND_HIGHEST_DWARF_REGISTER
+#else
+/*
+ * Need to define UNW_LOCAL_ONLY before importing libunwind.h
+ * if using libgcc libunwind.
+ */
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#define LAST_REG_INDEX UNW_TDEP_LAST_REG
+#endif
+
+
+/*
+ * Convert `v` to ASCII hex characters. The bottom `n` nybbles (4-bits ie one
+ * hex digit) will be written, up to `buflen`. The buffer will not be
+ * null-terminated. Returns the number of digits written.
+ */
+static size_t
+spl_bt_u64_to_hex_str(uint64_t v, size_t n, char *buf, size_t buflen)
+{
+ static const char hexdigits[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+
+ size_t pos = 0;
+ boolean_t want = (n == 0);
+ for (int i = 15; i >= 0; i--) {
+ const uint64_t d = v >> (i * 4) & 0xf;
+ if (!want && (d != 0 || n > i))
+ want = B_TRUE;
+ if (want) {
+ buf[pos++] = hexdigits[d];
+ if (pos == buflen)
+ break;
+ }
+ }
+ return (pos);
+}
+
+void
+libspl_backtrace(int fd)
+{
+ unw_context_t uc;
+ unw_cursor_t cp;
+ unw_word_t v;
+ char buf[128];
+ size_t n;
+ int err;
+
+ /* Snapshot the current frame and state. */
+ unw_getcontext(&uc);
+
+ /*
+ * TODO: walk back to the frame that tripped the assertion / the place
+ * where the signal was recieved.
+ */
+
+ /*
+ * Register dump. We're going to loop over all the registers in the
+ * top frame, and show them, with names, in a nice three-column
+ * layout, which keeps us within 80 columns.
+ */
+ spl_bt_write(fd, "Registers:\n");
+
+ /* Initialise a frame cursor, starting at the current frame */
+ unw_init_local(&cp, &uc);
+
+ /*
+ * Iterate over all registers for the architecture. We've figured
+ * out the highest number above, however, not all register numbers in
+ * this range are defined by the architecture, and not all defined
+ * registers will be present on every implementation of that
+ * architecture. Moreover, libunwind provides nice names for most, but
+ * not all registers, but these are hardcoded; a name being available
+ * does not mean that register is available.
+ *
+ * So, we have to pull this all together here. We try to get the value
+ * of every possible register. If we get a value for it, then the
+ * register must exist, and so we get its name. If libunwind has no
+ * name for it, we synthesize something. These cases should be rare,
+ * and they're usually for uninteresting or niche registers, so it
+ * shouldn't really matter. We can see the value, and that's the main
+ * thing.
+ */
+ uint_t cols = 0;
+ for (uint_t regnum = 0; regnum <= LAST_REG_INDEX; regnum++) {
+ /*
+ * Get the value. Any error probably means the register
+ * doesn't exist, and we skip it. LLVM libunwind iterates over
+ * fp registers in the same list, however they have to be
+ * accessed using unw_get_fpreg instead. Here, we just ignore
+ * them.
+ */
+#ifdef IS_LIBUNWIND_LLVM
+ if (unw_is_fpreg(&cp, regnum) ||
+ unw_get_reg(&cp, regnum, &v) < 0)
+ continue;
+#else
+ if (unw_get_reg(&cp, regnum, &v) < 0)
+ continue;
+#endif
+
+ /*
+ * Register name. If GCC libunwind doesn't have a name for it,
+ * it will return "???". As a shortcut, we just treat '?'
+ * is an alternate end-of-string character. LLVM libunwind will
+ * return the string 'unknown register', which we detect by
+ * checking if the register name is longer than 5 characters.
+ */
+#ifdef IS_LIBUNWIND_LLVM
+ const char *name = unw_regname(&cp, regnum);
+#else
+ const char *name = unw_regname(regnum);
+#endif
+ for (n = 0; name[n] != '\0' && name[n] != '?'; n++) {}
+ if (n == 0 || n > 5) {
+ /*
+ * No valid name, or likely llvm_libunwind returned
+ * unknown_register, so make one of the form "?xx",
+ * where "xx" is the two-char hex of libunwind's
+ * register number.
+ */
+ buf[0] = '?';
+ n = spl_bt_u64_to_hex_str(regnum, 2,
+ &buf[1], sizeof (buf)-1) + 1;
+ name = buf;
+ }
+
+ /*
+ * Two spaces of padding before each column, plus extra
+ * spaces to align register names shorter than three chars.
+ */
+ spl_bt_write_n(fd, " ", 5-MIN(n, 3));
+
+ /* Register name and column punctuation */
+ spl_bt_write_n(fd, name, n);
+ spl_bt_write(fd, ": 0x");
+
+ /*
+ * Convert register value (from unw_get_reg()) to hex. We're
+ * assuming that all registers are 64-bits wide, which is
+ * probably fine for any general-purpose registers on any
+ * machine currently in use. A more generic way would be to
+ * look at the width of unw_word_t, but that would also
+ * complicate the column code a bit. This is fine.
+ */
+ n = spl_bt_u64_to_hex_str(v, 16, buf, sizeof (buf));
+ spl_bt_write_n(fd, buf, n);
+
+ /* Every third column, emit a newline */
+ if (!(++cols % 3))
+ spl_bt_write(fd, "\n");
+ }
+
+ /* If we finished before the third column, emit a newline. */
+ if (cols % 3)
+ spl_bt_write(fd, "\n");
+
+ /* Now the main event, the backtrace. */
+ spl_bt_write(fd, "Call trace:\n");
+
+ /* Reset the cursor to the top again. */
+ unw_init_local(&cp, &uc);
+
+ do {
+ /*
+ * Getting the IP should never fail; libunwind handles it
+ * specially, because its used a lot internally. Still, no
+ * point being silly about it, as the last thing we want is
+ * our crash handler to crash. So if it ever does fail, we'll
+ * show an error line, but keep going to the next frame.
+ */
+ if (unw_get_reg(&cp, UNW_REG_IP, &v) < 0) {
+ spl_bt_write(fd, " [couldn't get IP register; "
+ "corrupt frame?]");
+ continue;
+ }
+
+ /* IP & punctuation */
+ n = spl_bt_u64_to_hex_str(v, 16, buf, sizeof (buf));
+ spl_bt_write(fd, " [0x");
+ spl_bt_write_n(fd, buf, n);
+ spl_bt_write(fd, "] ");
+
+ /*
+ * Function ("procedure") name for the current frame. `v`
+ * receives the offset from the named function to the IP, which
+ * we show as a "+offset" suffix.
+ *
+ * If libunwind can't determine the name, we just show "???"
+ * instead. We've already displayed the IP above; that will
+ * have to do.
+ *
+ * unw_get_proc_name() will return ENOMEM if the buffer is too
+ * small, instead truncating the name. So we treat that as a
+ * success and use whatever is in the buffer.
+ */
+ err = unw_get_proc_name(&cp, buf, sizeof (buf), &v);
+ if (err == 0 || err == -UNW_ENOMEM) {
+ for (n = 0; n < sizeof (buf) && buf[n] != '\0'; n++) {}
+ spl_bt_write_n(fd, buf, n);
+
+ /* Offset from proc name */
+ spl_bt_write(fd, "+0x");
+ n = spl_bt_u64_to_hex_str(v, 2, buf, sizeof (buf));
+ spl_bt_write_n(fd, buf, n);
+ } else
+ spl_bt_write(fd, "???");
+
+#ifdef HAVE_LIBUNWIND_ELF
+ /*
+ * Newer libunwind has unw_get_elf_filename(), which gets
+ * the name of the ELF object that the frame was executing in.
+ * Like `unw_get_proc_name()`, `v` recieves the offset within
+ * the file, and UNW_ENOMEM indicates that a truncate filename
+ * was left in the buffer.
+ */
+ err = unw_get_elf_filename(&cp, buf, sizeof (buf), &v);
+ if (err == 0 || err == -UNW_ENOMEM) {
+ for (n = 0; n < sizeof (buf) && buf[n] != '\0'; n++) {}
+ spl_bt_write(fd, " (in ");
+ spl_bt_write_n(fd, buf, n);
+
+ /* Offset within file */
+ spl_bt_write(fd, " +0x");
+ n = spl_bt_u64_to_hex_str(v, 2, buf, sizeof (buf));
+ spl_bt_write_n(fd, buf, n);
+ spl_bt_write(fd, ")");
+ }
+#endif
+ spl_bt_write(fd, "\n");
+ } while (unw_step(&cp) > 0);
+}
+#elif defined(HAVE_BACKTRACE)
+#include <execinfo.h>
+
+void
+libspl_backtrace(int fd)
+{
+ void *btptrs[64];
+ size_t nptrs = backtrace(btptrs, 64);
+ spl_bt_write(fd, "Call trace:\n");
+ backtrace_symbols_fd(btptrs, nptrs, fd);
+}
+#else
+void
+libspl_backtrace(int fd __maybe_unused)
+{
+}
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/condvar.c b/sys/contrib/openzfs/lib/libspl/condvar.c
new file mode 100644
index 000000000000..3d70fe152089
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/condvar.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <assert.h>
+#include <pthread.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/timer.h>
+#include <sys/condvar.h>
+
+/*
+ * =========================================================================
+ * condition variables
+ * =========================================================================
+ */
+
+void
+cv_init(kcondvar_t *cv, char *name, int type, void *arg)
+{
+ (void) name, (void) type, (void) arg;
+ VERIFY0(pthread_cond_init(cv, NULL));
+}
+
+void
+cv_destroy(kcondvar_t *cv)
+{
+ VERIFY0(pthread_cond_destroy(cv));
+}
+
+void
+cv_wait(kcondvar_t *cv, kmutex_t *mp)
+{
+ memset(&mp->m_owner, 0, sizeof (pthread_t));
+ VERIFY0(pthread_cond_wait(cv, &mp->m_lock));
+ mp->m_owner = pthread_self();
+}
+
+int
+cv_wait_sig(kcondvar_t *cv, kmutex_t *mp)
+{
+ cv_wait(cv, mp);
+ return (1);
+}
+
+int
+cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
+{
+ int error;
+ struct timeval tv;
+ struct timespec ts;
+ clock_t delta;
+
+ delta = abstime - ddi_get_lbolt();
+ if (delta <= 0)
+ return (-1);
+
+ VERIFY0(gettimeofday(&tv, NULL));
+
+ ts.tv_sec = tv.tv_sec + delta / hz;
+ ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz);
+ if (ts.tv_nsec >= NANOSEC) {
+ ts.tv_sec++;
+ ts.tv_nsec -= NANOSEC;
+ }
+
+ memset(&mp->m_owner, 0, sizeof (pthread_t));
+ error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
+ mp->m_owner = pthread_self();
+
+ if (error == ETIMEDOUT)
+ return (-1);
+
+ VERIFY0(error);
+
+ return (1);
+}
+
+int
+cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
+ int flag)
+{
+ (void) res;
+ int error;
+ struct timeval tv;
+ struct timespec ts;
+ hrtime_t delta;
+
+ ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);
+
+ delta = tim;
+ if (flag & CALLOUT_FLAG_ABSOLUTE)
+ delta -= gethrtime();
+
+ if (delta <= 0)
+ return (-1);
+
+ VERIFY0(gettimeofday(&tv, NULL));
+
+ ts.tv_sec = tv.tv_sec + delta / NANOSEC;
+ ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC);
+ if (ts.tv_nsec >= NANOSEC) {
+ ts.tv_sec++;
+ ts.tv_nsec -= NANOSEC;
+ }
+
+ memset(&mp->m_owner, 0, sizeof (pthread_t));
+ error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
+ mp->m_owner = pthread_self();
+
+ if (error == ETIMEDOUT)
+ return (-1);
+
+ VERIFY0(error);
+
+ return (1);
+}
+
+void
+cv_signal(kcondvar_t *cv)
+{
+ VERIFY0(pthread_cond_signal(cv));
+}
+
+void
+cv_broadcast(kcondvar_t *cv)
+{
+ VERIFY0(pthread_cond_broadcast(cv));
+}
diff --git a/sys/contrib/openzfs/lib/libspl/cred.c b/sys/contrib/openzfs/lib/libspl/cred.c
new file mode 100644
index 000000000000..130323ea91a7
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/cred.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <sys/cred.h>
+
+uid_t
+crgetuid(cred_t *cr)
+{
+ (void) cr;
+ return (0);
+}
+
+uid_t
+crgetruid(cred_t *cr)
+{
+ (void) cr;
+ return (0);
+}
+
+gid_t
+crgetgid(cred_t *cr)
+{
+ (void) cr;
+ return (0);
+}
+
+int
+crgetngroups(cred_t *cr)
+{
+ (void) cr;
+ return (0);
+}
+
+gid_t *
+crgetgroups(cred_t *cr)
+{
+ (void) cr;
+ return (NULL);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/getexecname.c b/sys/contrib/openzfs/lib/libspl/getexecname.c
index dca7162034f7..56ba5aa86058 100644
--- a/sys/contrib/openzfs/lib/libspl/getexecname.c
+++ b/sys/contrib/openzfs/lib/libspl/getexecname.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/Makefile.am
index 6f0e1818d22e..e68742409839 100644
--- a/sys/contrib/openzfs/lib/libspl/include/Makefile.am
+++ b/sys/contrib/openzfs/lib/libspl/include/Makefile.am
@@ -4,6 +4,7 @@ libspl_HEADERS = \
%D%/atomic.h \
%D%/libgen.h \
%D%/libshare.h \
+ %D%/libspl.h \
%D%/statcommon.h \
%D%/stdlib.h \
%D%/string.h \
@@ -26,8 +27,11 @@ libspl_sysdir = $(libspldir)/sys
libspl_sys_HEADERS = \
%D%/sys/acl.h \
%D%/sys/acl_impl.h \
+ %D%/sys/asm_linkage.h \
+ %D%/sys/backtrace.h \
%D%/sys/callb.h \
%D%/sys/cmn_err.h \
+ %D%/sys/condvar.h \
%D%/sys/cred.h \
%D%/sys/debug.h \
%D%/sys/dkio.h \
@@ -39,22 +43,34 @@ libspl_sys_HEADERS = \
%D%/sys/kstat.h \
%D%/sys/list.h \
%D%/sys/list_impl.h \
+ %D%/sys/misc.h \
%D%/sys/mhd.h \
%D%/sys/mkdev.h \
+ %D%/sys/mod.h \
+ %D%/sys/mutex.h \
%D%/sys/policy.h \
%D%/sys/poll.h \
%D%/sys/priv.h \
%D%/sys/processor.h \
- %D%/sys/sha2.h \
+ %D%/sys/procfs_list.h \
+ %D%/sys/random.h \
+ %D%/sys/rwlock.h \
+ %D%/sys/sid.h \
%D%/sys/simd.h \
%D%/sys/stack.h \
%D%/sys/stdtypes.h \
%D%/sys/string.h \
%D%/sys/sunddi.h \
+ %D%/sys/sysmacros.h \
%D%/sys/systeminfo.h \
+ %D%/sys/systm.h \
+ %D%/sys/thread.h \
+ %D%/sys/taskq.h \
%D%/sys/time.h \
- %D%/sys/trace_spl.h \
- %D%/sys/trace_zfs.h \
+ %D%/sys/timer.h \
+ %D%/sys/trace.h \
+ %D%/sys/tsd.h \
+ %D%/sys/tunables.h \
%D%/sys/types.h \
%D%/sys/types32.h \
%D%/sys/uio.h \
@@ -62,6 +78,8 @@ libspl_sys_HEADERS = \
%D%/sys/wmsum.h \
%D%/sys/zone.h
+libspl_ia32dir = $(libspldir)/sys/ia32
+
if BUILD_LINUX
libspl_sys_HEADERS += \
%D%/os/linux/sys/byteorder.h \
@@ -70,8 +88,10 @@ libspl_sys_HEADERS += \
%D%/os/linux/sys/mount.h \
%D%/os/linux/sys/param.h \
%D%/os/linux/sys/stat.h \
- %D%/os/linux/sys/sysmacros.h \
- %D%/os/linux/sys/zfs_context_os.h
+ %D%/os/linux/sys/vfs.h
+
+libspl_ia32_HEADERS = \
+ %D%/os/linux/sys/ia32/asm_linkage.h
endif
if BUILD_FREEBSD
@@ -83,12 +103,14 @@ libspl_sys_HEADERS += \
%D%/os/freebsd/sys/mount.h \
%D%/os/freebsd/sys/param.h \
%D%/os/freebsd/sys/stat.h \
- %D%/os/freebsd/sys/sysmacros.h \
- %D%/os/freebsd/sys/vfs.h \
- %D%/os/freebsd/sys/zfs_context_os.h
+ %D%/os/freebsd/sys/vfs.h
+
+libspl_ia32_HEADERS = \
+ %D%/os/freebsd/sys/ia32/asm_linkage.h
endif
libspl_sys_dktpdir = $(libspl_sysdir)/dktp
libspl_sys_dktp_HEADERS = \
%D%/sys/dktp/fdisk.h
+
diff --git a/sys/contrib/openzfs/lib/libspl/include/assert.h b/sys/contrib/openzfs/lib/libspl/include/assert.h
index e968a2310774..e704a899e748 100644
--- a/sys/contrib/openzfs/lib/libspl/include/assert.h
+++ b/sys/contrib/openzfs/lib/libspl/include/assert.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -34,12 +35,24 @@
#include <stdarg.h>
#include <sys/types.h>
+/* Workaround for non-Clang compilers */
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+/* We need to workaround libspl_set_assert_ok() that we have for zdb */
+#if __has_feature(attribute_analyzer_noreturn) || defined(__COVERITY__)
+#define NORETURN __attribute__((__noreturn__))
+#else
+#define NORETURN
+#endif
+
/* Set to non-zero to avoid abort()ing on an assertion failure */
extern void libspl_set_assert_ok(boolean_t val);
/* printf version of libspl_assert */
extern void libspl_assertf(const char *file, const char *func, int line,
- const char *format, ...);
+ const char *format, ...) NORETURN __attribute__((format(printf, 4, 5)));
static inline int
libspl_assert(const char *buf, const char *file, const char *func, int line)
@@ -52,21 +65,34 @@ libspl_assert(const char *buf, const char *file, const char *func, int line)
#undef verify
#endif
+#define PANIC(fmt, a...) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
+
#define VERIFY(cond) \
(void) ((!(cond)) && \
libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
+
+#define VERIFYF(cond, STR, ...) \
+do { \
+ if (!(cond)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "%s " STR, #cond, \
+ __VA_ARGS__); \
+} while (0)
+
#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); \
+ 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); \
+ "VERIFY3B(%s, %s, %s) failed " \
+ "(%d %s %d)", #LEFT, #OP, #RIGHT, \
+ __left, #OP, __right); \
} while (0)
#define VERIFY3S(LEFT, OP, RIGHT) \
@@ -75,8 +101,9 @@ do { \
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); \
+ "VERIFY3S(%s, %s, %s) failed " \
+ "(%lld %s 0x%lld)", #LEFT, #OP, #RIGHT, \
+ (longlong_t)__left, #OP, (longlong_t)__right); \
} while (0)
#define VERIFY3U(LEFT, OP, RIGHT) \
@@ -85,7 +112,8 @@ do { \
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, \
+ "VERIFY3U(%s, %s, %s) failed " \
+ "(%llu %s %llu)", #LEFT, #OP, #RIGHT, \
(u_longlong_t)__left, #OP, (u_longlong_t)__right); \
} while (0)
@@ -95,8 +123,9 @@ do { \
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); \
+ "VERIFY3P(%s, %s, %s) failed " \
+ "(%p %s %p)", #LEFT, #OP, #RIGHT, \
+ (void *)__left, #OP, (void *)__right); \
} while (0)
#define VERIFY0(LEFT) \
@@ -104,10 +133,92 @@ do { \
const uint64_t __left = (uint64_t)(LEFT); \
if (!(__left == 0)) \
libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
- "%s == 0 (0x%llx == 0)", #LEFT, \
+ "VERIFY0(%s) failed (%lld)", #LEFT, \
(u_longlong_t)__left); \
} while (0)
+#define VERIFY0P(LEFT) \
+do { \
+ const uintptr_t __left = (uintptr_t)(LEFT); \
+ if (!(__left == 0)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "VERIFY0P(%s) failed (%p)", #LEFT, \
+ (void *)__left); \
+} while (0)
+
+/*
+ * This is just here because cstyle gets upset about #LEFT
+ * on a newline.
+ */
+
+/* BEGIN CSTYLED */
+#define VERIFY3BF(LEFT, OP, RIGHT, STR, ...) \
+do { \
+ const boolean_t __left = (boolean_t)!!(LEFT); \
+ const boolean_t __right = (boolean_t)!!(RIGHT); \
+ if (!(__left OP __right)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "VERIFY3B(%s, %s, %s) failed " \
+ "(%d %s %d) " STR, #LEFT, #OP, #RIGHT, \
+ __left, #OP, __right, \
+ __VA_ARGS__); \
+} while (0)
+
+#define VERIFY3SF(LEFT, OP, RIGHT, STR, ...) \
+do { \
+ const int64_t __left = (int64_t)(LEFT); \
+ const int64_t __right = (int64_t)(RIGHT); \
+ if (!(__left OP __right)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "VERIFY3S(%s, %s, %s) failed " \
+ "(%lld %s %lld) " STR, #LEFT, #OP, #RIGHT, \
+ (longlong_t)__left, #OP, (longlong_t)__right, \
+ __VA_ARGS__); \
+} while (0)
+
+#define VERIFY3UF(LEFT, OP, RIGHT, STR, ...) \
+do { \
+ const uint64_t __left = (uint64_t)(LEFT); \
+ const uint64_t __right = (uint64_t)(RIGHT); \
+ if (!(__left OP __right)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "VERIFY3U(%s, %s, %s) failed " \
+ "(%llu %s %llu) " STR, #LEFT, #OP, #RIGHT, \
+ (u_longlong_t)__left, #OP, (u_longlong_t)__right, \
+ __VA_ARGS__); \
+} while (0)
+
+#define VERIFY3PF(LEFT, OP, RIGHT, STR, ...) \
+do { \
+ const uintptr_t __left = (uintptr_t)(LEFT); \
+ const uintptr_t __right = (uintptr_t)(RIGHT); \
+ if (!(__left OP __right)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "VERIFY3P(%s, %s, %s) failed " \
+ "(%p %s %p) " STR, #LEFT, #OP, #RIGHT, \
+ (void *)__left, #OP, (void *)__right, \
+ __VA_ARGS__); \
+} while (0)
+/* END CSTYLED */
+
+#define VERIFY0F(LEFT, STR, ...) \
+do { \
+ const int64_t __left = (int64_t)(LEFT); \
+ if (!(__left == 0)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "VERIFY0(%s) failed (%lld) " STR, #LEFT, \
+ (longlong_t)__left, __VA_ARGS__); \
+} while (0)
+
+#define VERIFY0PF(LEFT, STR, ...) \
+do { \
+ const uintptr_t __left = (uintptr_t)(LEFT); \
+ if (!(__left == 0)) \
+ libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
+ "VERIFY0P(%s) failed (%p) " STR, #LEFT, \
+ (void *)__left, __VA_ARGS__); \
+} while (0)
+
#ifdef assert
#undef assert
#endif
@@ -122,7 +233,16 @@ do { \
#define ASSERT3P(x, y, z) \
((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
#define ASSERT0(x) ((void) sizeof ((uintptr_t)(x)))
+#define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))
+#define ASSERT3BF(x, y, z, str, ...) ASSERT3B(x, y, z)
+#define ASSERT3SF(x, y, z, str, ...) ASSERT3S(x, y, z)
+#define ASSERT3UF(x, y, z, str, ...) ASSERT3U(x, y, z)
+#define ASSERT3PF(x, y, z, str, ...) ASSERT3P(x, y, z)
+#define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))
+#define ASSERT0PF(x, str, ...) ASSERT0P(x)
+#define ASSERT0F(x, str, ...) ASSERT0(x)
#define ASSERT(x) ((void) sizeof ((uintptr_t)(x)))
+#define ASSERTF(x, str, ...) ASSERT(x)
#define assert(x) ((void) sizeof ((uintptr_t)(x)))
#define IMPLY(A, B) \
((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
@@ -134,16 +254,21 @@ do { \
#define ASSERT3U VERIFY3U
#define ASSERT3P VERIFY3P
#define ASSERT0 VERIFY0
+#define ASSERT0P VERIFY0P
+#define ASSERT3BF VERIFY3BF
+#define ASSERT3SF VERIFY3SF
+#define ASSERT3UF VERIFY3UF
+#define ASSERT3PF VERIFY3PF
+#define ASSERT0PF VERIFY0PF
+#define ASSERT0F VERIFY0F
#define ASSERT VERIFY
+#define ASSERTF VERIFYF
#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__)))
+#define EQUIV(A, B) VERIFY3B(A, ==, B)
#endif /* NDEBUG */
diff --git a/sys/contrib/openzfs/lib/libspl/include/atomic.h b/sys/contrib/openzfs/lib/libspl/include/atomic.h
index 8dd1d654a486..cc6f2e2ce988 100644
--- a/sys/contrib/openzfs/lib/libspl/include/atomic.h
+++ b/sys/contrib/openzfs/lib/libspl/include/atomic.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -314,6 +315,13 @@ extern void membar_enter(void);
extern void membar_exit(void);
/*
+ * Make all stores and loads emitted prior to the the barrier complete before
+ * crossing it, while also making sure stores and loads emitted after the
+ * barrier only start being executed after crossing it.
+ */
+extern void membar_sync(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.
diff --git a/sys/contrib/openzfs/lib/libspl/include/libgen.h b/sys/contrib/openzfs/lib/libspl/include/libgen.h
index c46d7454e49f..18d3e1d891b8 100644
--- a/sys/contrib/openzfs/lib/libspl/include/libgen.h
+++ b/sys/contrib/openzfs/lib/libspl/include/libgen.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/libshare.h b/sys/contrib/openzfs/lib/libspl/include/libshare.h
index ae0e2c39dc6d..bfa78bffd461 100644
--- a/sys/contrib/openzfs/lib/libspl/include/libshare.h
+++ b/sys/contrib/openzfs/lib/libspl/include/libshare.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -22,7 +23,7 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright (c) 2019, 2020 by Delphix. All rights reserved.
+ * Copyright (c) 2019, 2022 by Delphix. All rights reserved.
*/
#ifndef _LIBSPL_LIBSHARE_H
#define _LIBSPL_LIBSHARE_H extern __attribute__((visibility("default")))
@@ -88,6 +89,7 @@ _LIBSPL_LIBSHARE_H int sa_enable_share(const char *, const char *, const char *,
_LIBSPL_LIBSHARE_H int sa_disable_share(const char *, enum sa_protocol);
_LIBSPL_LIBSHARE_H boolean_t sa_is_shared(const char *, enum sa_protocol);
_LIBSPL_LIBSHARE_H void sa_commit_shares(enum sa_protocol);
+_LIBSPL_LIBSHARE_H void sa_truncate_shares(enum sa_protocol);
/* protocol specific interfaces */
_LIBSPL_LIBSHARE_H int sa_validate_shareopts(const char *, enum sa_protocol);
diff --git a/sys/contrib/openzfs/lib/libspl/include/libspl.h b/sys/contrib/openzfs/lib/libspl/include/libspl.h
new file mode 100644
index 000000000000..68756bb9597b
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/libspl.h
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2025, Rob Norris <robn@despairlabs.com>
+ */
+
+#ifndef _LIBSPL_H
+#define _LIBSPL_H extern __attribute__((visibility("default")))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LIBSPL_H void libspl_init(void);
+_LIBSPL_H void libspl_fini(void);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* _LIBSPL_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/fcntl.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/fcntl.h
index 26d571ad8926..1222b3d7a6b5 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/fcntl.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/fcntl.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2021 iXsystems, Inc.
*
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
index d4227ddc5465..116ce991b89b 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/byteorder.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/byteorder.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -59,6 +60,18 @@ extern "C" {
*/
#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
+#ifdef __COVERITY__
+/*
+ * Coverity's taint warnings from byteswapping are false positives for us.
+ * Suppress them by hiding byteswapping from Coverity.
+ */
+#define BSWAP_8(x) ((x) & 0xff)
+#define BSWAP_16(x) ((x) & 0xffff)
+#define BSWAP_32(x) ((x) & 0xffffffff)
+#define BSWAP_64(x) (x)
+
+#else /* __COVERITY__ */
+
/*
* Macros to reverse byte order
*/
@@ -67,6 +80,8 @@ extern "C" {
#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
+#endif /* __COVERITY__ */
+
#define BMASK_8(x) ((x) & 0xff)
#define BMASK_16(x) ((x) & 0xffff)
#define BMASK_32(x) ((x) & 0xffffffff)
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/fcntl.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/fcntl.h
index c8a37a193850..04fcc9f85c91 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/fcntl.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/fcntl.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2021 iXsystems, Inc.
*
@@ -26,7 +27,9 @@
#ifndef _LIBSPL_SYS_FCNTL_H_
#define _LIBSPL_SYS_FCNTL_H_
+#if !defined(__linux__) || !defined(IN_BASE)
#include_next <sys/fcntl.h>
+#endif
#define O_LARGEFILE 0
#define O_RSYNC 0
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
index 5a20686dc069..75c3b23860bb 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/file.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/file.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/ia32/asm_linkage.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/ia32/asm_linkage.h
new file mode 100644
index 000000000000..f9c34d282d46
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/ia32/asm_linkage.h
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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 _IA32_SYS_ASM_LINKAGE_H
+#define _IA32_SYS_ASM_LINKAGE_H
+
+#if defined(__linux__) && defined(CONFIG_SLS)
+#define RET ret; int3
+#else
+#define RET ret
+#endif
+
+/* Tell compiler to call assembler like Unix */
+#undef ASMABI
+#define ASMABI __attribute__((sysv_abi))
+
+#define ENDBR
+
+#define SECTION_TEXT .text
+#define SECTION_STATIC .section .rodata
+
+#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
+
+/*
+ * 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; \
+ .balign ASM_ENTRY_ALIGN; \
+ .globl x; \
+x: MCOUNT(x)
+
+#define ENTRY_NP(x) \
+ .text; \
+ .balign ASM_ENTRY_ALIGN; \
+ .globl x; \
+x:
+
+#define ENTRY_ALIGN(x, a) \
+ .text; \
+ .balign a; \
+ .globl x; \
+x:
+
+#define FUNCTION(x) \
+ .type x, @function; \
+x:
+
+/*
+ * ENTRY2 is identical to ENTRY but provides two labels for the entry point.
+ */
+#define ENTRY2(x, y) \
+ .text; \
+ .balign ASM_ENTRY_ALIGN; \
+ .globl x, y; \
+x:; \
+y: MCOUNT(x)
+
+#define ENTRY_NP2(x, y) \
+ .text; \
+ .balign ASM_ENTRY_ALIGN; \
+ .globl x, y; \
+x:; \
+y:
+
+
+/*
+ * SET_SIZE trails a function and set the size for the ELF symbol table.
+ */
+#define SET_SIZE(x)
+
+#define SET_OBJ(x)
+
+#endif /* _ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IA32_SYS_ASM_LINKAGE_H */
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
index aa3132fb3cc0..e520bf5ef3bb 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mnttab.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mnttab.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
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
index e99518571270..5548ad7d22b2 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -28,8 +29,10 @@
#ifndef _LIBSPL_SYS_MOUNT_H
#define _LIBSPL_SYS_MOUNT_H
+#if !defined(__linux__) || !defined(IN_BASE)
#undef _SYS_MOUNT_H_
#include_next <sys/mount.h>
+#endif
#include <assert.h>
#include <string.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
index cb5260ea3d7e..a693149115db 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -57,6 +58,10 @@
extern size_t spl_pagesize(void);
#define PAGESIZE (spl_pagesize())
+#define ptob(x) ((x) * PAGESIZE)
+
+#ifndef HAVE_EXECVPE
extern int execvpe(const char *name, char * const argv[], char * const envp[]);
+#endif
#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
index 38c684d62a1b..666f2ec6d760 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/stat.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/stat.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -76,8 +77,12 @@ fstat64_blk(int fd, struct stat64 *st)
/*
* Only Intel-based Macs have a separate stat64; Arm-based Macs are like
* FreeBSD and have a full 64-bit stat from the start.
+ *
+ * On Linux, musl libc is full 64-bit too and has deprecated its own version
+ * of these defines since version 1.2.4.
*/
-#if defined(__APPLE__) && !(defined(__i386__) || defined(__x86_64__))
+#if (defined(__APPLE__) && !(defined(__i386__) || defined(__x86_64__))) || \
+ (defined(__linux__) && !defined(__GLIBC__))
#define stat64 stat
#define fstat64 fstat
#endif
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
deleted file mode 100644
index d9639d27b60e..000000000000
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/sysmacros.h
+++ /dev/null
@@ -1 +0,0 @@
-/* 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
index 55eb3c23b22e..228ec5905240 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/vfs.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/vfs.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2020 iXsystems, Inc.
* All rights reserved.
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
deleted file mode 100644
index 9b9d69bddcf7..000000000000
--- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/zfs_context_os.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 HAVE_LARGE_STACKS 1
-
-#endif
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
index 47af7700f031..4fba62addd3b 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/byteorder.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/byteorder.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -90,6 +91,18 @@ extern in_port_t ntohs(in_port_t);
#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
+#ifdef __COVERITY__
+/*
+ * Coverity's taint warnings from byteswapping are false positives for us.
+ * Suppress them by hiding byteswapping from Coverity.
+ */
+#define BSWAP_8(x) ((x) & 0xff)
+#define BSWAP_16(x) ((x) & 0xffff)
+#define BSWAP_32(x) ((x) & 0xffffffff)
+#define BSWAP_64(x) (x)
+
+#else /* __COVERITY__ */
+
/*
* Macros to reverse byte order
*/
@@ -98,6 +111,8 @@ extern in_port_t ntohs(in_port_t);
#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
+#endif /* __COVERITY__ */
+
#define BMASK_8(x) ((x) & 0xff)
#define BMASK_16(x) ((x) & 0xffff)
#define BMASK_32(x) ((x) & 0xffffffff)
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
index 30d20ab895c5..dd0120100a3d 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/errno.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/errno.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/ia32/asm_linkage.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/ia32/asm_linkage.h
new file mode 100644
index 000000000000..e1d25346b13e
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/ia32/asm_linkage.h
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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 _IA32_SYS_ASM_LINKAGE_H
+#define _IA32_SYS_ASM_LINKAGE_H
+
+#if defined(_KERNEL) && defined(__linux__)
+#include <linux/linkage.h>
+#endif
+
+#ifndef ENDBR
+#if defined(__ELF__) && defined(__CET__) && defined(__has_include)
+/* CSTYLED */
+#if __has_include(<cet.h>)
+
+#include <cet.h>
+
+#ifdef _CET_ENDBR
+#define ENDBR _CET_ENDBR
+#endif /* _CET_ENDBR */
+
+#endif /* <cet.h> */
+#endif /* __ELF__ && __CET__ && __has_include */
+#endif /* !ENDBR */
+
+#ifndef ENDBR
+#define ENDBR
+#endif
+#ifndef RET
+#define RET ret
+#endif
+
+/* You can set to nothing on Unix platforms */
+#undef ASMABI
+#define ASMABI __attribute__((sysv_abi))
+
+#define SECTION_TEXT .text
+#define SECTION_STATIC .section .rodata
+
+#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
+
+/*
+ * 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.
+ */
+#undef ENTRY
+#define ENTRY(x) \
+ .text; \
+ .balign ASM_ENTRY_ALIGN; \
+ .globl x; \
+ .type x, @function; \
+x: MCOUNT(x)
+
+#define ENTRY_NP(x) \
+ .text; \
+ .balign ASM_ENTRY_ALIGN; \
+ .globl x; \
+ .type x, @function; \
+x:
+
+#define ENTRY_ALIGN(x, a) \
+ .text; \
+ .balign a; \
+ .globl x; \
+ .type x, @function; \
+x:
+
+#define FUNCTION(x) \
+ .type x, @function; \
+x:
+
+/*
+ * ENTRY2 is identical to ENTRY but provides two labels for the entry point.
+ */
+#define ENTRY2(x, y) \
+ .text; \
+ .balign ASM_ENTRY_ALIGN; \
+ .globl x, y; \
+ .type x, @function; \
+ .type y, @function; \
+x:; \
+y: MCOUNT(x)
+
+#define ENTRY_NP2(x, y) \
+ .text; \
+ .balign ASM_ENTRY_ALIGN; \
+ .globl x, y; \
+ .type x, @function; \
+ .type y, @function; \
+x:; \
+y:
+
+
+/*
+ * SET_SIZE trails a function and set the size for the ELF symbol table.
+ */
+#define SET_SIZE(x) \
+ .size x, [.-x]
+
+#define SET_OBJ(x) .type x, @object
+
+#endif /* _ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IA32_SYS_ASM_LINKAGE_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
index 21592aaaacee..c1b7f3b389c0 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mnttab.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mnttab.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
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
index d7c6f750e23d..c4a291f5c22d 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mount.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/mount.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
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
index 26335187fdca..169d5875fcf0 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -64,4 +65,6 @@
extern size_t spl_pagesize(void);
#define PAGESIZE (spl_pagesize())
+#define ptob(x) ((x) * 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
index 3e8d27e4c19a..13cc0b46ac93 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/stat.h
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/stat.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -30,6 +31,11 @@
#include <sys/mount.h> /* for BLKGETSIZE64 */
+#ifdef HAVE_STATX
+#include <fcntl.h>
+#include <sys/stat.h>
+#endif
+
/*
* Emulate Solaris' behavior of returning the block device size in fstat64().
*/
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h
new file mode 100644
index 000000000000..c7b567ff44a4
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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 2025 by Lawrence Livermore National Security, LLC. */
+
+/* This is the Linux userspace version of include/os/linux/spl/sys/vfs.h */
+
+#ifndef _LIBSPL_SYS_VFS_H
+#define _LIBSPL_SYS_VFS_H
+
+#include <linux/fs.h>
+#include <sys/statfs.h>
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/rpc/xdr.h b/sys/contrib/openzfs/lib/libspl/include/rpc/xdr.h
index 51d71f693bbf..85f718c275a5 100644
--- a/sys/contrib/openzfs/lib/libspl/include/rpc/xdr.h
+++ b/sys/contrib/openzfs/lib/libspl/include/rpc/xdr.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/statcommon.h b/sys/contrib/openzfs/lib/libspl/include/statcommon.h
index 1f376f5c7c24..21c64ed4a9f8 100644
--- a/sys/contrib/openzfs/lib/libspl/include/statcommon.h
+++ b/sys/contrib/openzfs/lib/libspl/include/statcommon.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -37,5 +38,9 @@
/* Print a timestamp in either Unix or standard format. */
void print_timestamp(uint_t);
+/* Return timestamp in either Unix or standard format in provided buffer */
+void get_timestamp(uint_t, char *, int);
+/* convert time_t to standard format */
+void format_timestamp(time_t, char *, int);
#endif /* _STATCOMMON_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/stdlib.h b/sys/contrib/openzfs/lib/libspl/include/stdlib.h
index a4ce4f781fc5..f381f21345fa 100644
--- a/sys/contrib/openzfs/lib/libspl/include/stdlib.h
+++ b/sys/contrib/openzfs/lib/libspl/include/stdlib.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/string.h b/sys/contrib/openzfs/lib/libspl/include/string.h
index a7d40fa61943..52f268b1d931 100644
--- a/sys/contrib/openzfs/lib/libspl/include/string.h
+++ b/sys/contrib/openzfs/lib/libspl/include/string.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/acl.h b/sys/contrib/openzfs/lib/libspl/include/sys/acl.h
index 31168421b088..3e79040c5307 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/acl.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/acl.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -140,8 +141,6 @@ typedef struct acl_info acl_t;
#define ACE_ALL_TYPES 0x001F
-#if defined(_KERNEL)
-
typedef struct ace_object {
uid_t a_who; /* uid or gid */
uint32_t a_access_mask; /* read,write,... */
@@ -151,8 +150,6 @@ typedef struct ace_object {
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| \
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/acl_impl.h b/sys/contrib/openzfs/lib/libspl/include/sys/acl_impl.h
index 717334906415..2850eacf61f4 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/acl_impl.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/acl_impl.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/asm_linkage.h b/sys/contrib/openzfs/lib/libspl/include/sys/asm_linkage.h
new file mode 100644
index 000000000000..1a0f2864a178
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/asm_linkage.h
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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_ASM_LINKAGE_H
+#define _SYS_ASM_LINKAGE_H
+
+#if defined(__i386) || defined(__amd64)
+
+#include <sys/ia32/asm_linkage.h> /* XX64 x86/sys/asm_linkage.h */
+
+#endif
+
+#if defined(_KERNEL) && defined(HAVE_KERNEL_OBJTOOL)
+
+#include <asm/frame.h>
+
+#else /* userspace */
+#define FRAME_BEGIN
+#define FRAME_END
+#endif
+
+
+#endif /* _SYS_ASM_LINKAGE_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/zfs_context_os.h b/sys/contrib/openzfs/lib/libspl/include/sys/backtrace.h
index 81ced5207749..3a2077f32e6c 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/zfs_context_os.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/backtrace.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -19,10 +20,14 @@
*
* CDDL HEADER END
*/
+/*
+ * Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
+ * Copyright (c) 2024, Klara Inc.
+ */
-#ifndef ZFS_CONTEXT_OS_H
-#define ZFS_CONTEXT_OS_H
+#ifndef _LIBSPL_SYS_BACKTRACE_H
+#define _LIBSPL_SYS_BACKTRACE_H
-#define HAVE_LARGE_STACKS 1
+void libspl_backtrace(int fd);
#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/callb.h b/sys/contrib/openzfs/lib/libspl/include/sys/callb.h
index 8ffd18788865..6e8e22338b8b 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/callb.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/callb.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -20,11 +21,36 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_CALLB_H
#define _SYS_CALLB_H
+#include <sys/mutex.h>
+
+typedef struct callb_cpr {
+ kmutex_t *cc_lockp;
+} callb_cpr_t;
+
+#define CALLB_CPR_INIT(cp, lockp, func, name) { \
+ (cp)->cc_lockp = lockp; \
+}
+
+#define CALLB_CPR_SAFE_BEGIN(cp) { \
+ ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
+}
+
+#define CALLB_CPR_SAFE_END(cp, lockp) { \
+ ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
+}
+
+#define CALLB_CPR_EXIT(cp) { \
+ ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
+ mutex_exit((cp)->cc_lockp); \
+}
+
#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
index 63ff4eb29bc8..5e7136f7fdc2 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -27,4 +28,65 @@
#ifndef _LIBSPL_SYS_CMN_ERR_H
#define _LIBSPL_SYS_CMN_ERR_H
+#include <atomic.h>
+
+#define cmn_err_once(ce, ...) \
+do { \
+ static volatile uint32_t printed = 0; \
+ if (atomic_cas_32(&printed, 0, 1) == 0) { \
+ cmn_err(ce, __VA_ARGS__); \
+ } \
+} while (0)
+
+#define vcmn_err_once(ce, fmt, ap) \
+do { \
+ static volatile uint32_t printed = 0; \
+ if (atomic_cas_32(&printed, 0, 1) == 0) { \
+ vcmn_err(ce, fmt, ap); \
+ } \
+} while (0)
+
+#define zcmn_err_once(zone, ce, ...) \
+do { \
+ static volatile uint32_t printed = 0; \
+ if (atomic_cas_32(&printed, 0, 1) == 0) { \
+ zcmn_err(zone, ce, __VA_ARGS__); \
+ } \
+} while (0)
+
+#define vzcmn_err_once(zone, ce, fmt, ap) \
+do { \
+ static volatile uint32_t printed = 0; \
+ if (atomic_cas_32(&printed, 0, 1) == 0) { \
+ vzcmn_err(zone, ce, fmt, ap); \
+ } \
+} while (0)
+
+/*
+ * Note that we are not using the debugging levels.
+ */
+
+#define CE_CONT 0 /* continuation */
+#define CE_NOTE 1 /* notice */
+#define CE_WARN 2 /* warning */
+#define CE_PANIC 3 /* panic */
+#define CE_IGNORE 4 /* print nothing */
+
+/*
+ * ZFS debugging
+ */
+
+extern void dprintf_setup(int *argc, char **argv);
+
+extern void cmn_err(int, const char *, ...)
+ __attribute__((format(printf, 2, 3)));
+extern void vcmn_err(int, const char *, va_list)
+ __attribute__((format(printf, 2, 0)));
+extern void panic(const char *, ...)
+ __attribute__((format(printf, 1, 2), noreturn));
+extern void vpanic(const char *, va_list)
+ __attribute__((format(printf, 1, 0), noreturn));
+
+#define fm_panic panic
+
#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/condvar.h b/sys/contrib/openzfs/lib/libspl/include/sys/condvar.h
new file mode 100644
index 000000000000..fb8f7c9bf6b1
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/condvar.h
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_CONDVAR_H
+#define _SYS_CONDVAR_H
+
+#ifdef SKIP_SPL_SYS_CONDVAR_H
+#include_next <sys/condvar.h>
+#else
+
+#include <pthread.h>
+#include <sys/time.h>
+#include <sys/mutex.h>
+
+/*
+ * Condition variables
+ */
+typedef pthread_cond_t kcondvar_t;
+
+#define CV_DEFAULT 0
+#define CALLOUT_FLAG_ABSOLUTE 0x2
+
+extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
+extern void cv_destroy(kcondvar_t *cv);
+extern void cv_wait(kcondvar_t *cv, kmutex_t *mp);
+extern int cv_wait_sig(kcondvar_t *cv, kmutex_t *mp);
+extern int cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime);
+extern int cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
+ hrtime_t res, int flag);
+extern void cv_signal(kcondvar_t *cv);
+extern void cv_broadcast(kcondvar_t *cv);
+
+#define cv_timedwait_io(cv, mp, at) cv_timedwait(cv, mp, at)
+#define cv_timedwait_idle(cv, mp, at) cv_timedwait(cv, mp, at)
+#define cv_timedwait_sig(cv, mp, at) cv_timedwait(cv, mp, at)
+#define cv_wait_io(cv, mp) cv_wait(cv, mp)
+#define cv_wait_idle(cv, mp) cv_wait(cv, mp)
+#define cv_wait_io_sig(cv, mp) cv_wait_sig(cv, mp)
+#define cv_timedwait_sig_hires(cv, mp, t, r, f) \
+ cv_timedwait_hires(cv, mp, t, r, f)
+#define cv_timedwait_idle_hires(cv, mp, t, r, f) \
+ cv_timedwait_hires(cv, mp, t, r, f)
+
+#endif /* SKIP_SPL_CONDVAR_H */
+#endif /* _SYS_CONDVAR_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/cred.h b/sys/contrib/openzfs/lib/libspl/include/sys/cred.h
index 463b3abfc977..deceecee0f19 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/cred.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/cred.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -27,6 +28,24 @@
#ifndef _LIBSPL_SYS_CRED_H
#define _LIBSPL_SYS_CRED_H
+#include <sys/stat.h>
+
+/*
+ * Credentials
+ */
+
typedef struct cred cred_t;
+extern uid_t crgetuid(cred_t *cr);
+extern uid_t crgetruid(cred_t *cr);
+extern gid_t crgetgid(cred_t *cr);
+extern int crgetngroups(cred_t *cr);
+extern gid_t *crgetgroups(cred_t *cr);
+
+#define kcred NULL
+#define CRED() NULL
+
+#define crhold(cr) ((void)cr)
+#define crfree(cr) ((void)cr)
+
#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/debug.h b/sys/contrib/openzfs/lib/libspl/include/sys/debug.h
index af18da94804c..2bd077686f1c 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/debug.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/debug.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -23,6 +24,12 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
#ifndef _LIBSPL_SYS_DEBUG_H
#define _LIBSPL_SYS_DEBUG_H
@@ -37,4 +44,26 @@
#define __maybe_unused __attribute__((unused))
#endif
+#ifndef __must_check
+#define __must_check __attribute__((warn_unused_result))
+#endif
+
+#ifndef noinline
+#define noinline __attribute__((noinline))
+#endif
+
+#ifndef likely
+#define likely(x) __builtin_expect((x), 1)
+#endif
+
+#ifndef unlikely
+#define unlikely(x) __builtin_expect((x), 0)
+#endif
+
+/*
+ * Kernel modules
+ */
+#define __init
+#define __exit
+
#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/dkio.h b/sys/contrib/openzfs/lib/libspl/include/sys/dkio.h
index f3c641f669b7..4ae1026d4d5f 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/dkio.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/dkio.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/dklabel.h b/sys/contrib/openzfs/lib/libspl/include/sys/dklabel.h
index 8c2ca06c0cbc..409d337e9adf 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/dklabel.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/dklabel.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/dktp/fdisk.h b/sys/contrib/openzfs/lib/libspl/include/sys/dktp/fdisk.h
index e90135f362e6..5e5db04cccfc 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/dktp/fdisk.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/dktp/fdisk.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h b/sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h
index 877e0a15a89e..be7d4ebf9210 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h b/sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h
index d7d063985316..66cf97ac8b5c 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h b/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h
index 3922445db31c..99dbc70e4617 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -227,9 +228,13 @@ extern "C" {
* RISC-V arch specific defines
* only RV64G (including atomic) LP64 is supported yet
*/
-#elif defined(__riscv) && defined(_LP64) && _LP64 && \
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64 && \
defined(__riscv_atomic) && __riscv_atomic
+#if !defined(_LP64)
+#define _LP64 1
+#endif
+
#ifndef __riscv__
#define __riscv__
#endif
@@ -242,10 +247,26 @@ extern "C" {
#define _SUNOS_VTOC_16
+/*
+ * LoongArch arch specific defines
+ * only LoongArch64 is supported yet
+ */
+#elif defined(__loongarch__) && defined(__loongarch_lp64)
+
+#if !defined(_LP64)
+#define _LP64
+#endif
+
+#define _ZFS_LITTLE_ENDIAN
+#define _SUNOS_VTOC_16
+
+/* not all LoongArch cores support unaligned accesses in hardware */
+#define _ALIGNMENT_REQUIRED 1
+
#else
/*
* Currently supported:
- * x86_64, x32, i386, arm, powerpc, s390, sparc, mips, and RV64G
+ * x86_64, x32, i386, arm, powerpc, s390, sparc, mips, RV64G, and LoongArch64
*/
#error "Unsupported ISA type"
#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h b/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h
index 06c614e51d1c..33e618f46bb0 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -19,26 +20,76 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_KMEM_H
#define _SYS_KMEM_H
-#include <stdlib.h>
+#include <umem.h>
+#include <sys/types.h>
-#ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
-#define KM_SLEEP 0x00000000 /* same as KM_SLEEP */
-#define KM_NOSLEEP 0x00000001 /* same as KM_NOSLEEP */
+/*
+ * Kernel memory
+ */
+#define KM_SLEEP UMEM_NOFAIL
+#define KM_PUSHPAGE KM_SLEEP
+#define KM_NOSLEEP UMEM_DEFAULT
+#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */
+#define KMC_NODEBUG UMC_NODEBUG
+#define KMC_KVMEM 0x0
+#define KMC_RECLAIMABLE 0x0
+#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
+#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f)
+#define kmem_free(_b, _s) umem_free(_b, _s)
+#define vmem_alloc(_s, _f) kmem_alloc(_s, _f)
+#define vmem_zalloc(_s, _f) kmem_zalloc(_s, _f)
+#define vmem_free(_b, _s) kmem_free(_b, _s)
+#define kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \
+ umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i)
+#define kmem_cache_destroy(_c) umem_cache_destroy(_c)
+#define kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f)
+#define kmem_cache_free(_c, _b) umem_cache_free(_c, _b)
+#define kmem_debugging() 0
+#define kmem_cache_reap_now(_c) umem_cache_reap_now(_c);
+extern int kmem_cache_reap_active(void);
+#define kmem_cache_set_move(_c, _cb) /* nothing */
+#define POINTER_INVALIDATE(_pp) /* nothing */
+#define POINTER_IS_VALID(_p) 0
+
+extern char *kmem_vasprintf(const char *fmt, va_list adx);
+extern char *kmem_asprintf(const char *fmt, ...);
+#define kmem_strfree(str) kmem_free((str), strlen(str) + 1)
+#define kmem_strdup(s) strdup(s)
+
+#ifndef __cplusplus
+extern int kmem_scnprintf(char *restrict str, size_t size,
+ const char *restrict fmt, ...);
+#endif
+
+typedef umem_cache_t kmem_cache_t;
+
+typedef enum kmem_cbrc {
+ KMEM_CBRC_YES,
+ KMEM_CBRC_NO,
+ KMEM_CBRC_LATER,
+ KMEM_CBRC_DONT_NEED,
+ KMEM_CBRC_DONT_KNOW
+} kmem_cbrc_t;
+
+typedef int fstrans_cookie_t;
-#define kmem_alloc(size, flags) ((void) sizeof (flags), malloc(size))
-#define kmem_free(ptr, size) ((void) sizeof (size), free(ptr))
+extern fstrans_cookie_t spl_fstrans_mark(void);
+extern void spl_fstrans_unmark(fstrans_cookie_t);
-#ifdef __cplusplus
+#ifdef __cplusplus
}
#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h b/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h
index c2de0778485c..361f24df3f58 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -26,758 +27,65 @@
#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 */
+ uchar_t ks_flags;
+ void *ks_data;
+ uint_t ks_ndata;
+ size_t ks_data_size;
+ int (*ks_update)(struct kstat *, int);
+ void *ks_private;
+ void *ks_lock;
} kstat_t;
-/*
- * 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_TYPE_RAW 0
+#define KSTAT_TYPE_NAMED 1
#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)
- * memcpy(ksp->ks_data, buf, ksp->ks_data_size);
- * else
- * memcpy(buf, ksp->ks_data, 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) {
- * memcpy(buf, foo, 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 ...
- * memcpy(buf, ksp->ks_data, 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) {
- * memcpy(end, KSTAT_NAMED_STR_PTR(knp),
- * 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 */
+ char name[KSTAT_STRLEN];
+ uchar_t 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 */
+ char *ptr;
+ char __pad[8];
} addr;
- uint32_t len; /* # bytes for strlen + '\0' */
+ uint32_t len;
} 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/inttypes.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 */
+ } value;
} 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)
+#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data)
+#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr)
+#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.
+ * kstat creation, installation and deletion
*/
-
-#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 kstat_t *kstat_create(const char *, int,
+ const char *, const char *, uchar_t, ulong_t, uchar_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_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
+extern void kstat_set_raw_ops(kstat_t *ksp,
+ int (*headers)(char *buf, size_t size),
+ int (*data)(char *buf, size_t size, void *data),
+ void *(*addr)(kstat_t *ksp, loff_t index));
#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
index 6db92ed42955..cbbda85dabb5 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/list.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/list.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/list_impl.h b/sys/contrib/openzfs/lib/libspl/include/sys/list_impl.h
index b5655b972c11..10683adab325 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/list_impl.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/list_impl.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -39,7 +40,6 @@ struct list_node {
};
struct list {
- size_t list_size;
size_t list_offset;
struct list_node list_head;
};
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/mhd.h b/sys/contrib/openzfs/lib/libspl/include/sys/mhd.h
index fcc062d51c84..82ec436750ef 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/mhd.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/mhd.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/misc.h b/sys/contrib/openzfs/lib/libspl/include/sys/misc.h
new file mode 100644
index 000000000000..171bbc1de798
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/misc.h
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _LIBSPL_SYS_MISC_H
+#define _LIBSPL_SYS_MISC_H
+
+#include <sys/utsname.h>
+
+/*
+ * Hostname information
+ */
+typedef struct utsname utsname_t;
+extern utsname_t *utsname(void);
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/mkdev.h b/sys/contrib/openzfs/lib/libspl/include/sys/mkdev.h
index 5978de65de50..f02823c68db0 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/mkdev.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/mkdev.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/mod.h b/sys/contrib/openzfs/lib/libspl/include/sys/mod.h
new file mode 100644
index 000000000000..ad19b6607a42
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/mod.h
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
+ */
+
+#ifndef _SYS_MOD_H
+#define _SYS_MOD_H
+
+#include <sys/tunables.h>
+
+#define ZFS_MODULE_PARAM(scope, prefix, name, type, perm, desc) \
+ static const zfs_tunable_t _zfs_tunable_##prefix##name = { \
+ .zt_name = #prefix#name, \
+ .zt_varp = &prefix##name, \
+ .zt_varsz = sizeof (prefix##name), \
+ .zt_type = ZFS_TUNABLE_TYPE_##type, \
+ .zt_perm = ZFS_TUNABLE_PERM_##perm, \
+ .zt_desc = desc \
+ }; \
+ static const zfs_tunable_t * \
+ __zfs_tunable_##prefix##name \
+ __attribute__((__section__("zfs_tunables"))) \
+ __attribute__((__used__)) \
+ = &_zfs_tunable_##prefix##name;
+
+#define ZFS_MODULE_PARAM_ARGS void
+#define ZFS_MODULE_PARAM_CALL(scope_prefix, name_prefix, name, setfunc, \
+ getfunc, perm, desc)
+
+#define EXPORT_SYMBOL(x)
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/mutex.h b/sys/contrib/openzfs/lib/libspl/include/sys/mutex.h
new file mode 100644
index 000000000000..1da0e632d60f
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/mutex.h
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_MUTEX_H
+#define _SYS_MUTEX_H
+
+#include <pthread.h>
+
+/*
+ * Mutexes
+ */
+typedef struct kmutex {
+ pthread_mutex_t m_lock;
+ pthread_t m_owner;
+} kmutex_t;
+
+#define MUTEX_DEFAULT 0
+#define MUTEX_NOLOCKDEP MUTEX_DEFAULT
+#define MUTEX_HELD(mp) pthread_equal((mp)->m_owner, pthread_self())
+#define MUTEX_NOT_HELD(mp) !MUTEX_HELD(mp)
+
+extern void mutex_init(kmutex_t *mp, char *name, int type, void *cookie);
+extern void mutex_destroy(kmutex_t *mp);
+extern void mutex_enter(kmutex_t *mp);
+extern int mutex_enter_check_return(kmutex_t *mp);
+extern void mutex_exit(kmutex_t *mp);
+extern int mutex_tryenter(kmutex_t *mp);
+
+#define NESTED_SINGLE 1
+#define mutex_enter_nested(mp, class) mutex_enter(mp)
+#define mutex_enter_interruptible(mp) mutex_enter_check_return(mp)
+
+#endif /* _SYS_MUTEX_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/policy.h b/sys/contrib/openzfs/lib/libspl/include/sys/policy.h
index 2f695b35cd0b..0d6016c1dd17 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/policy.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/policy.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/poll.h b/sys/contrib/openzfs/lib/libspl/include/sys/poll.h
index 6ab0bddc0be5..3e99db0bdbee 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/poll.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/poll.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/priv.h b/sys/contrib/openzfs/lib/libspl/include/sys/priv.h
index 76c76d1830c2..30b88a6c47fc 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/priv.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/priv.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/processor.h b/sys/contrib/openzfs/lib/libspl/include/sys/processor.h
index 78e95d01f1b5..9e1bd90992bd 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/processor.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/processor.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/procfs_list.h b/sys/contrib/openzfs/lib/libspl/include/sys/procfs_list.h
new file mode 100644
index 000000000000..144a8a22b9b5
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/procfs_list.h
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_PROCFS_LIST_H
+#define _SYS_PROCFS_LIST_H
+
+#include <sys/types.h>
+#include <sys/mutex.h>
+#include <sys/list.h>
+
+/*
+ * procfs list manipulation
+ */
+
+typedef struct procfs_list {
+ void *pl_private;
+ kmutex_t pl_lock;
+ list_t pl_list;
+ uint64_t pl_next_id;
+ size_t pl_node_offset;
+} procfs_list_t;
+
+#ifndef __cplusplus
+struct seq_file { };
+void seq_printf(struct seq_file *m, const char *fmt, ...);
+
+typedef struct procfs_list_node {
+ list_node_t pln_link;
+ uint64_t pln_id;
+} procfs_list_node_t;
+
+void procfs_list_install(const char *module,
+ const char *submodule,
+ const char *name,
+ mode_t mode,
+ procfs_list_t *procfs_list,
+ int (*show)(struct seq_file *f, void *p),
+ int (*show_header)(struct seq_file *f),
+ int (*clear)(procfs_list_t *procfs_list),
+ size_t procfs_list_node_off);
+void procfs_list_uninstall(procfs_list_t *procfs_list);
+void procfs_list_destroy(procfs_list_t *procfs_list);
+void procfs_list_add(procfs_list_t *procfs_list, void *p);
+#endif
+
+#endif /* _SYS_PROCFS_LIST_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/random.h b/sys/contrib/openzfs/lib/libspl/include/sys/random.h
new file mode 100644
index 000000000000..09ca0662d1a3
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/random.h
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_RANDOM_H
+#define _SYS_RANDOM_H
+
+extern int random_get_bytes(uint8_t *ptr, size_t len);
+extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
+
+extern void random_force_pseudo(boolean_t onoff);
+
+static __inline__ uint32_t
+random_in_range(uint32_t range)
+{
+ uint32_t r;
+
+#if !defined(__APPLE__) || !defined(IN_BASE)
+ ASSERT(range != 0);
+#endif
+
+ if (range == 1)
+ return (0);
+
+ (void) random_get_pseudo_bytes((uint8_t *)&r, sizeof (r));
+
+ return (r % range);
+}
+
+#endif /* _SYS_RANDOM_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/rwlock.h b/sys/contrib/openzfs/lib/libspl/include/sys/rwlock.h
new file mode 100644
index 000000000000..9f82f270d939
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/rwlock.h
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_RWLOCK_H
+#define _SYS_RWLOCK_H
+
+#include <pthread.h>
+
+/*
+ * RW locks
+ */
+typedef struct krwlock {
+ pthread_rwlock_t rw_lock;
+ pthread_t rw_owner;
+ uint_t rw_readers;
+} krwlock_t;
+
+typedef int krw_t;
+
+#define RW_READER 0
+#define RW_WRITER 1
+#define RW_DEFAULT RW_READER
+#define RW_NOLOCKDEP RW_READER
+
+#define RW_READ_HELD(rw) ((rw)->rw_readers > 0)
+#define RW_WRITE_HELD(rw) pthread_equal((rw)->rw_owner, pthread_self())
+#define RW_LOCK_HELD(rw) (RW_READ_HELD(rw) || RW_WRITE_HELD(rw))
+
+extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
+extern void rw_destroy(krwlock_t *rwlp);
+extern void rw_enter(krwlock_t *rwlp, krw_t rw);
+extern int rw_tryenter(krwlock_t *rwlp, krw_t rw);
+extern int rw_tryupgrade(krwlock_t *rwlp);
+extern void rw_exit(krwlock_t *rwlp);
+#define rw_downgrade(rwlp) do { } while (0)
+
+#endif /* _SYS_RWLOCK_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/sha2.h b/sys/contrib/openzfs/lib/libspl/include/sys/sha2.h
deleted file mode 100644
index 8bdc23a5f61e..000000000000
--- a/sys/contrib/openzfs/lib/libspl/include/sys/sha2.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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 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/sid.h b/sys/contrib/openzfs/lib/libspl/include/sys/sid.h
new file mode 100644
index 000000000000..74789c5d9a62
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/sid.h
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_SID_H
+#define _SYS_SID_H
+
+#include <sys/types.h>
+
+/* SID stuff */
+typedef struct ksiddomain {
+ uint_t kd_ref;
+ uint_t kd_len;
+ char *kd_name;
+} ksiddomain_t;
+
+ksiddomain_t *ksid_lookupdomain(const char *);
+void ksiddomain_rele(ksiddomain_t *);
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/simd.h b/sys/contrib/openzfs/lib/libspl/include/sys/simd.h
index 6a6d8b7c6191..4772a5416b2e 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/simd.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/simd.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -20,8 +21,8 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2022 Tino Reichardt <milky-zfs@mcmilk.de>
*/
#ifndef _LIBSPL_SYS_SIMD_H
@@ -30,6 +31,28 @@
#include <sys/isa_defs.h>
#include <sys/types.h>
+/* including <sys/auxv.h> clashes with AT_UID and others */
+#if defined(__arm__) || defined(__aarch64__) || defined(__powerpc__)
+#if defined(__FreeBSD__)
+#define AT_HWCAP 25
+#define AT_HWCAP2 26
+extern int elf_aux_info(int aux, void *buf, int buflen);
+static inline unsigned long getauxval(unsigned long key)
+{
+ unsigned long val = 0UL;
+
+ if (elf_aux_info((int)key, &val, sizeof (val)) != 0)
+ return (0UL);
+
+ return (val);
+}
+#elif defined(__linux__)
+#define AT_HWCAP 16
+#define AT_HWCAP2 26
+extern unsigned long getauxval(unsigned long type);
+#endif /* __linux__ */
+#endif /* arm || aarch64 || powerpc */
+
#if defined(__x86)
#include <cpuid.h>
@@ -78,7 +101,10 @@ typedef enum cpuid_inst_sets {
AVX512VL,
AES,
PCLMULQDQ,
- MOVBE
+ MOVBE,
+ SHA_NI,
+ VAES,
+ VPCLMULQDQ
} cpuid_inst_sets_t;
/*
@@ -103,6 +129,9 @@ typedef struct cpuid_feature_desc {
#define _AES_BIT (1U << 25)
#define _PCLMULQDQ_BIT (1U << 1)
#define _MOVBE_BIT (1U << 22)
+#define _VAES_BIT (1U << 9)
+#define _VPCLMULQDQ_BIT (1U << 10)
+#define _SHA_NI_BIT (1U << 29)
/*
* Descriptions of supported instruction sets
@@ -131,6 +160,9 @@ static const cpuid_feature_desc_t cpuid_features[] = {
[AES] = {1U, 0U, _AES_BIT, ECX },
[PCLMULQDQ] = {1U, 0U, _PCLMULQDQ_BIT, ECX },
[MOVBE] = {1U, 0U, _MOVBE_BIT, ECX },
+ [SHA_NI] = {7U, 0U, _SHA_NI_BIT, EBX },
+ [VAES] = {7U, 0U, _VAES_BIT, ECX },
+ [VPCLMULQDQ] = {7U, 0U, _VPCLMULQDQ_BIT, ECX },
};
/*
@@ -204,6 +236,9 @@ CPUID_FEATURE_CHECK(avx512vl, AVX512VL);
CPUID_FEATURE_CHECK(aes, AES);
CPUID_FEATURE_CHECK(pclmulqdq, PCLMULQDQ);
CPUID_FEATURE_CHECK(movbe, MOVBE);
+CPUID_FEATURE_CHECK(shani, SHA_NI);
+CPUID_FEATURE_CHECK(vaes, VAES);
+CPUID_FEATURE_CHECK(vpclmulqdq, VPCLMULQDQ);
/*
* Detect register set support
@@ -346,6 +381,33 @@ zfs_movbe_available(void)
}
/*
+ * Check if SHA_NI instruction is available
+ */
+static inline boolean_t
+zfs_shani_available(void)
+{
+ return (__cpuid_has_shani());
+}
+
+/*
+ * Check if VAES instruction is available
+ */
+static inline boolean_t
+zfs_vaes_available(void)
+{
+ return (__cpuid_has_vaes());
+}
+
+/*
+ * Check if VPCLMULQDQ instruction is available
+ */
+static inline boolean_t
+zfs_vpclmulqdq_available(void)
+{
+ return (__cpuid_has_vpclmulqdq());
+}
+
+/*
* AVX-512 family of instruction sets:
*
* AVX512F Foundation
@@ -443,72 +505,111 @@ zfs_avx512vbmi_available(void)
__zmm_enabled());
}
-#elif defined(__aarch64__)
+#elif defined(__arm__)
#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 HWCAP_NEON 0x00001000
+#define HWCAP2_SHA2 0x00000008
+
+/*
+ * Check if NEON is available
+ */
+static inline boolean_t
+zfs_neon_available(void)
+{
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ return (hwcap & HWCAP_NEON);
+}
+
+/*
+ * Check if SHA2 is available
+ */
+static inline boolean_t
+zfs_sha256_available(void)
+{
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ return (hwcap & HWCAP2_SHA2);
+}
+
+#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)
+#define HWCAP_FP 0x00000001
+#define HWCAP_SHA2 0x00000040
+#define HWCAP_SHA512 0x00200000
+
+/*
+ * Check if NEON is available
+ */
+static inline boolean_t
+zfs_neon_available(void)
+{
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ return (hwcap & HWCAP_FP);
+}
+
/*
- * Check if AltiVec instruction set is available
- * No easy way beyond 'altivec works' :-(
+ * Check if SHA2 is available
*/
-#include <signal.h>
-#include <setjmp.h>
+static inline boolean_t
+zfs_sha256_available(void)
+{
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ return (hwcap & HWCAP_SHA2);
+}
-#if defined(__ALTIVEC__) && !defined(__FreeBSD__)
-static jmp_buf env;
-static void sigillhandler(int x)
+/*
+ * Check if SHA512 is available
+ */
+static inline boolean_t
+zfs_sha512_available(void)
{
- (void) x;
- longjmp(env, 1);
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ return (hwcap & HWCAP_SHA512);
}
-#endif
+
+#elif defined(__powerpc__)
+
+#define kfpu_allowed() 0
+#define kfpu_initialize(tsk) do {} while (0)
+#define kfpu_begin() do {} while (0)
+#define kfpu_end() do {} while (0)
+
+#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
+#define PPC_FEATURE_HAS_VSX 0x00000080
+#define PPC_FEATURE2_ARCH_2_07 0x80000000
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);
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ return (hwcap & PPC_FEATURE_HAS_ALTIVEC);
}
+
static inline boolean_t
zfs_vsx_available(void)
{
- boolean_t has_vsx = B_FALSE;
-#if defined(__ALTIVEC__) && !defined(__FreeBSD__)
- sighandler_t savesig;
- savesig = signal(SIGILL, sigillhandler);
- if (setjmp(env)) {
- signal(SIGILL, savesig);
- has_vsx = B_FALSE;
- } else {
- __asm__ __volatile__("xssubsp 0,0,0\n");
- signal(SIGILL, savesig);
- has_vsx = B_TRUE;
- }
-#endif
- return (has_vsx);
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ return (hwcap & PPC_FEATURE_HAS_VSX);
}
+
+static inline boolean_t
+zfs_isa207_available(void)
+{
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ unsigned long hwcap2 = getauxval(AT_HWCAP2);
+ return ((hwcap & PPC_FEATURE_HAS_VSX) &&
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07));
+}
+
#else
#define kfpu_allowed() 0
@@ -518,4 +619,7 @@ zfs_vsx_available(void)
#endif
+extern void simd_stat_init(void);
+extern void simd_stat_fini(void);
+
#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
index 59807e97b6a0..80984086a145 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/stack.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/stack.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h b/sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h
index c26e2dc96c4e..db5876e5bc2b 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/string.h b/sys/contrib/openzfs/lib/libspl/include/sys/string.h
index 3b2f5900276f..55ccbd09041a 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/string.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/string.h
@@ -1 +1,4 @@
+#ifndef _LIBSPL_SYS_STRING_H
+#define _LIBSPL_SYS_STRING_H
#include <string.h>
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h b/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h
index ccd2b29b9b09..48e0b15a4542 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -20,10 +21,16 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 2008 by Sun Microsystems, Inc.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_SUNDDI_H
#define _SYS_SUNDDI_H
+extern int ddi_strtoull(const char *str, char **nptr, int base,
+ u_longlong_t *result);
+
#endif /* _SYS_SUNDDI_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/sysmacros.h b/sys/contrib/openzfs/lib/libspl/include/sys/sysmacros.h
index 31f347c6fd5a..f67b081c42fa 100644
--- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/sysmacros.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/sysmacros.h
@@ -1,13 +1,13 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* 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.
+ * 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -20,14 +20,32 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBSPL_SYS_SYSMACROS_H
#define _LIBSPL_SYS_SYSMACROS_H
+#include <stdint.h>
+
+#ifdef __linux__
+/*
+ * On Linux, we need the system-provided sysmacros.h to get the makedev(),
+ * major() and minor() definitions for makedevice() below. FreeBSD does not
+ * have this header, so include_next won't find it and will abort. So, we
+ * protect it with a platform check.
+ */
+#ifndef IN_BASE
#include_next <sys/sysmacros.h>
+#endif
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#endif
/* common macros */
#ifndef MIN
@@ -52,7 +70,8 @@
/*
* Compatibility macros/typedefs needed for Solaris -> Linux port
*/
-#define P2ALIGN(x, align) ((x) & -(align))
+// Deprecated. Use P2ALIGN_TYPED instead.
+// #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) \
@@ -92,10 +111,22 @@
#define P2SAMEHIGHBIT_TYPED(x, y, type) \
(((type)(x) ^ (type)(y)) < ((type)(x) & (type)(y)))
+#define max_ncpus 64
+#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN))
-/* 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
+/*
+ * Process priorities as defined by setpriority(2) and getpriority(2).
+ */
+#define minclsyspri 19
+#define defclsyspri 0
+/* Write issue taskq priority. */
+#define wtqclsyspri -19
+#define maxclsyspri -20
+
+#define CPU_SEQID ((uintptr_t)pthread_self() & (max_ncpus - 1))
+#define CPU_SEQID_UNSTABLE CPU_SEQID
+
+extern int lowbit64(uint64_t i);
+extern int highbit64(uint64_t i);
-#endif /* _LIBSPL_SYS_SYSMACROS_H */
+#endif /* _SYS_SYSMACROS_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/systeminfo.h b/sys/contrib/openzfs/lib/libspl/include/sys/systeminfo.h
index cc6c1793c00e..3ca1fa884994 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/systeminfo.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/systeminfo.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/systm.h b/sys/contrib/openzfs/lib/libspl/include/sys/systm.h
new file mode 100644
index 000000000000..f984125c3315
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/systm.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _LIBSPL_SYS_SYSTM_H
+#define _LIBSPL_SYS_SYSTM_H
+
+uint64_t libspl_physmem(void);
+
+#define physmem libspl_physmem()
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/taskq.h b/sys/contrib/openzfs/lib/libspl/include/sys/taskq.h
new file mode 100644
index 000000000000..fbe3f388c05f
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/taskq.h
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_TASKQ_H
+#define _SYS_TASKQ_H
+
+#include <pthread.h>
+#include <stdint.h>
+#include <sys/mutex.h>
+#include <sys/rwlock.h>
+#include <sys/condvar.h>
+
+/*
+ * Task queues
+ */
+
+#define TASKQ_NAMELEN 31
+
+typedef uintptr_t taskqid_t;
+typedef void (task_func_t)(void *);
+
+typedef struct taskq_ent {
+ struct taskq_ent *tqent_next;
+ struct taskq_ent *tqent_prev;
+ task_func_t *tqent_func;
+ void *tqent_arg;
+ uintptr_t tqent_flags;
+} taskq_ent_t;
+
+typedef struct taskq {
+ char tq_name[TASKQ_NAMELEN + 1];
+ kmutex_t tq_lock;
+ krwlock_t tq_threadlock;
+ kcondvar_t tq_dispatch_cv;
+ kcondvar_t tq_wait_cv;
+ kthread_t **tq_threadlist;
+ int tq_flags;
+ int tq_active;
+ int tq_nthreads;
+ int tq_nalloc;
+ int tq_minalloc;
+ int tq_maxalloc;
+ kcondvar_t tq_maxalloc_cv;
+ int tq_maxalloc_wait;
+ taskq_ent_t *tq_freelist;
+ taskq_ent_t tq_task;
+} taskq_t;
+
+#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */
+
+#define TASKQ_PREPOPULATE 0x0001
+#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
+#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
+#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */
+#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */
+
+#define TQ_SLEEP KM_SLEEP /* Can block for memory */
+#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */
+#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
+#define TQ_FRONT 0x08 /* Queue in front */
+
+#define TASKQID_INVALID ((taskqid_t)0)
+
+extern taskq_t *_system_taskq(void);
+extern taskq_t *_system_delay_taskq(void);
+
+#define system_taskq _system_taskq()
+#define system_delay_taskq _system_delay_taskq()
+
+extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
+extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t,
+ kthread_t ***);
+#define taskq_create_proc(a, b, c, d, e, p, f) \
+ (taskq_create(a, b, c, d, e, f))
+#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
+ ((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f))
+extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
+extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t,
+ clock_t);
+extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
+ taskq_ent_t *);
+extern int taskq_empty_ent(taskq_ent_t *);
+extern void taskq_init_ent(taskq_ent_t *);
+extern void taskq_destroy(taskq_t *);
+extern void taskq_wait(taskq_t *);
+extern void taskq_wait_id(taskq_t *, taskqid_t);
+extern void taskq_wait_outstanding(taskq_t *, taskqid_t);
+extern int taskq_member(taskq_t *, kthread_t *);
+extern taskq_t *taskq_of_curthread(void);
+extern int taskq_cancel_id(taskq_t *, taskqid_t);
+extern void system_taskq_init(void);
+extern void system_taskq_fini(void);
+
+#endif /* _SYS_TASKQ_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/thread.h b/sys/contrib/openzfs/lib/libspl/include/sys/thread.h
new file mode 100644
index 000000000000..6390c5bfd863
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/thread.h
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_THREAD_H
+#define _SYS_THREAD_H
+
+#include <pthread.h>
+
+/*
+ * Threads.
+ */
+typedef pthread_t kthread_t;
+
+#define TS_RUN 0x00000002
+#define TS_JOINABLE 0x00000004
+
+#define curthread ((void *)(uintptr_t)pthread_self())
+#define getcomm() "unknown"
+
+#define thread_create_named(name, stk, stksize, func, arg, len, \
+ pp, state, pri) \
+ zk_thread_create(name, func, arg, stksize, state)
+#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
+ zk_thread_create(#func, func, arg, stksize, state)
+#define thread_exit() pthread_exit(NULL)
+#define thread_join(t) pthread_join((pthread_t)(t), NULL)
+
+#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS)
+/*
+ * Check if the current thread is a memory reclaim thread.
+ * Always returns false in userspace (no memory reclaim thread).
+ */
+#define current_is_reclaim_thread() (0)
+
+/* in libzpool, p0 exists only to have its address taken */
+typedef void (proc_t)(void);
+extern void p0(void);
+
+#define curproc (&p0)
+
+#define PS_NONE -1
+
+extern kthread_t *zk_thread_create(const char *name, void (*func)(void *),
+ void *arg, size_t stksize, int state);
+
+#define issig() (FALSE)
+
+#define KPREEMPT_SYNC (-1)
+
+#define kpreempt(x) sched_yield()
+#define kpreempt_disable() ((void)0)
+#define kpreempt_enable() ((void)0)
+
+#endif /* _SYS_THREAD_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/time.h b/sys/contrib/openzfs/lib/libspl/include/sys/time.h
index c9f6165047d2..062c6ec979fc 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/time.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/time.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -97,11 +98,20 @@ gethrestime_sec(void)
}
static inline hrtime_t
+getlrtime(void)
+{
+ struct timeval tv;
+ (void) gettimeofday(&tv, NULL);
+ return ((((uint64_t)tv.tv_sec) * NANOSEC) +
+ ((uint64_t)tv.tv_usec * NSEC_PER_USEC));
+}
+
+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);
+ return ((((uint64_t)ts.tv_sec) * NANOSEC) + ts.tv_nsec);
}
#endif /* _LIBSPL_SYS_TIME_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/timer.h b/sys/contrib/openzfs/lib/libspl/include/sys/timer.h
new file mode 100644
index 000000000000..850d11f063c3
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/timer.h
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SPL_TIMER_H
+#define _SPL_TIMER_H
+
+#include <sys/time.h>
+
+#define ddi_get_lbolt() (gethrtime() >> 23)
+#define ddi_get_lbolt64() (gethrtime() >> 23)
+#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */
+
+#define ddi_time_before(a, b) (a < b)
+#define ddi_time_after(a, b) ddi_time_before(b, a)
+#define ddi_time_before_eq(a, b) (!ddi_time_after(a, b))
+#define ddi_time_after_eq(a, b) ddi_time_before_eq(b, a)
+
+#define ddi_time_before64(a, b) (a < b)
+#define ddi_time_after64(a, b) ddi_time_before64(b, a)
+#define ddi_time_before_eq64(a, b) (!ddi_time_after64(a, b))
+#define ddi_time_after_eq64(a, b) ddi_time_before_eq64(b, a)
+
+extern void delay(clock_t ticks);
+
+#define SEC_TO_TICK(sec) ((sec) * hz)
+#define MSEC_TO_TICK(msec) (howmany((hrtime_t)(msec) * hz, MILLISEC))
+#define USEC_TO_TICK(usec) (howmany((hrtime_t)(usec) * hz, MICROSEC))
+#define NSEC_TO_TICK(nsec) (howmany((hrtime_t)(nsec) * hz, NANOSEC))
+
+#define usleep_range(min, max) \
+ do { \
+ struct timespec ts; \
+ ts.tv_sec = min / MICROSEC; \
+ ts.tv_nsec = USEC2NSEC(min); \
+ (void) nanosleep(&ts, NULL); \
+ } while (0)
+
+#endif /* _SPL_TIMER_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/trace.h b/sys/contrib/openzfs/lib/libspl/include/sys/trace.h
new file mode 100644
index 000000000000..17b812faed20
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/trace.h
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_TRACE_H
+#define _SYS_TRACE_H
+
+/*
+ * DTrace SDT probes have different signatures in userland than they do in
+ * the kernel. If they're being used in kernel code, re-define them out of
+ * existence for their counterparts in libzpool.
+ *
+ * Here's an example of how to use the set-error probes in userland:
+ * zfs$target:::set-error /arg0 == EBUSY/ {stack();}
+ *
+ * Here's an example of how to use DTRACE_PROBE probes in userland:
+ * If there is a probe declared as follows:
+ * DTRACE_PROBE2(zfs__probe_name, uint64_t, blkid, dnode_t *, dn);
+ * Then you can use it as follows:
+ * zfs$target:::probe2 /copyinstr(arg0) == "zfs__probe_name"/
+ * {printf("%u %p\n", arg1, arg2);}
+ */
+
+#ifdef DTRACE_PROBE
+#undef DTRACE_PROBE
+#endif /* DTRACE_PROBE */
+#define DTRACE_PROBE(a)
+
+#ifdef DTRACE_PROBE1
+#undef DTRACE_PROBE1
+#endif /* DTRACE_PROBE1 */
+#define DTRACE_PROBE1(a, b, c)
+
+#ifdef DTRACE_PROBE2
+#undef DTRACE_PROBE2
+#endif /* DTRACE_PROBE2 */
+#define DTRACE_PROBE2(a, b, c, d, e)
+
+#ifdef DTRACE_PROBE3
+#undef DTRACE_PROBE3
+#endif /* DTRACE_PROBE3 */
+#define DTRACE_PROBE3(a, b, c, d, e, f, g)
+
+#ifdef DTRACE_PROBE4
+#undef DTRACE_PROBE4
+#endif /* DTRACE_PROBE4 */
+#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i)
+
+#endif /* _SYS_TRACE_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
deleted file mode 100644
index b80d288f7332..000000000000
--- a/sys/contrib/openzfs/lib/libspl/include/sys/trace_spl.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 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
deleted file mode 100644
index 87ed5ad3c3be..000000000000
--- a/sys/contrib/openzfs/lib/libspl/include/sys/trace_zfs.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 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/tsd.h b/sys/contrib/openzfs/lib/libspl/include/sys/tsd.h
new file mode 100644
index 000000000000..fa91519b3de5
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/tsd.h
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_TSD_H
+#define _SYS_TSD_H
+
+#include <pthread.h>
+
+/*
+ * Thread-specific data
+ */
+#define tsd_get(k) pthread_getspecific(k)
+#define tsd_set(k, v) pthread_setspecific(k, v)
+#define tsd_create(kp, d) pthread_key_create((pthread_key_t *)kp, d)
+#define tsd_destroy(kp) /* nothing */
+
+#endif /* _SYS_MUTEX_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h b/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h
new file mode 100644
index 000000000000..d93425733709
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2025, Rob Norris <robn@despairlabs.com>
+ */
+
+#ifndef _SYS_TUNABLES_H
+//#define _SYS_TUNABLES_H extern __attribute__((visibility("hidden")))
+#define _SYS_TUNABLES_H extern
+
+typedef enum {
+ ZFS_TUNABLE_TYPE_INT,
+ ZFS_TUNABLE_TYPE_UINT,
+ ZFS_TUNABLE_TYPE_ULONG,
+ ZFS_TUNABLE_TYPE_U64,
+ ZFS_TUNABLE_TYPE_STRING,
+} zfs_tunable_type_t;
+
+typedef enum {
+ ZFS_TUNABLE_PERM_ZMOD_RW,
+ ZFS_TUNABLE_PERM_ZMOD_RD,
+} zfs_tunable_perm_t;
+
+typedef struct zfs_tunable {
+ const char *zt_name;
+ void *zt_varp;
+ size_t zt_varsz;
+ zfs_tunable_type_t zt_type;
+ zfs_tunable_perm_t zt_perm;
+ const char *zt_desc;
+} zfs_tunable_t;
+
+_SYS_TUNABLES_H int zfs_tunable_set(const zfs_tunable_t *tunable,
+ const char *val);
+_SYS_TUNABLES_H int zfs_tunable_get(const zfs_tunable_t *tunable, char *val,
+ size_t valsz);
+
+_SYS_TUNABLES_H const zfs_tunable_t *zfs_tunable_lookup(const char *name);
+
+typedef int (*zfs_tunable_iter_t)(const zfs_tunable_t *tunable, void *arg);
+_SYS_TUNABLES_H void zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg);
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/types.h b/sys/contrib/openzfs/lib/libspl/include/sys/types.h
index 8dc38ae3394f..9af20d781674 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/types.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/types.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -47,31 +48,10 @@
typedef uint_t 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
+#include <sys/param.h> /* for NBBY */
-#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;
+#ifdef __FreeBSD__
+typedef off_t loff_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
index bb41aa34bee0..1bcae20187ad 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/types32.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/types32.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -65,11 +66,6 @@ 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 */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/uio.h b/sys/contrib/openzfs/lib/libspl/include/sys/uio.h
index 81ade54b5409..9ada482be000 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/uio.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/uio.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -40,6 +41,7 @@
#ifndef _LIBSPL_SYS_UIO_H
#define _LIBSPL_SYS_UIO_H
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include_next <sys/uio.h>
@@ -57,8 +59,7 @@ typedef enum zfs_uio_rw {
} zfs_uio_rw_t;
typedef enum zfs_uio_seg {
- UIO_USERSPACE = 0,
- UIO_SYSSPACE = 1,
+ UIO_SYSSPACE = 0,
} zfs_uio_seg_t;
#elif defined(__FreeBSD__)
@@ -82,6 +83,32 @@ typedef struct zfs_uio {
#define zfs_uio_iovlen(uio, idx) (uio)->uio_iov[(idx)].iov_len
#define zfs_uio_iovbase(uio, idx) (uio)->uio_iov[(idx)].iov_base
+static inline boolean_t
+zfs_dio_page_aligned(void *buf)
+{
+ return ((((unsigned long)(buf) & (PAGESIZE - 1)) == 0) ?
+ B_TRUE : B_FALSE);
+}
+
+static inline boolean_t
+zfs_dio_offset_aligned(uint64_t offset, uint64_t blksz)
+{
+ return ((IS_P2ALIGNED(offset, blksz)) ? B_TRUE : B_FALSE);
+}
+
+static inline boolean_t
+zfs_dio_size_aligned(uint64_t size, uint64_t blksz)
+{
+ return (((size % blksz) == 0) ? B_TRUE : B_FALSE);
+}
+
+static inline boolean_t
+zfs_dio_aligned(uint64_t offset, uint64_t size, uint64_t blksz)
+{
+ return ((zfs_dio_offset_aligned(offset, blksz) &&
+ zfs_dio_size_aligned(size, blksz)) ? B_TRUE : B_FALSE);
+}
+
static inline void
zfs_uio_iov_at_index(zfs_uio_t *uio, uint_t idx, void **base, uint64_t *len)
{
@@ -90,7 +117,7 @@ zfs_uio_iov_at_index(zfs_uio_t *uio, uint_t idx, void **base, uint64_t *len)
}
static inline void
-zfs_uio_advance(zfs_uio_t *uio, size_t size)
+zfs_uio_advance(zfs_uio_t *uio, ssize_t size)
{
uio->uio_resid -= size;
uio->uio_loffset += size;
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h b/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h
index efcdd2c5a5ae..ed9901eede22 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -24,7 +25,36 @@
* Use is subject to license terms.
*/
-#ifndef _LIBSPL_SYS_VNODE_H
-#define _LIBSPL_SYS_VNODE_H
+#ifndef _SYS_VNODE_H
+#define _SYS_VNODE_H
-#endif /* _LIBSPL_SYS_VNODE_H */
+typedef struct vattr {
+ uint_t va_mask; /* bit-mask of attributes */
+ u_offset_t va_size; /* file size in bytes */
+} vattr_t;
+
+#define AT_MODE 0x00002
+#define AT_UID 0x00004
+#define AT_GID 0x00008
+#define AT_FSID 0x00010
+#define AT_NODEID 0x00020
+#define AT_NLINK 0x00040
+#define AT_SIZE 0x00080
+#define AT_ATIME 0x00100
+#define AT_MTIME 0x00200
+#define AT_CTIME 0x00400
+#define AT_RDEV 0x00800
+#define AT_BLKSIZE 0x01000
+#define AT_NBLOCKS 0x02000
+#define AT_SEQ 0x08000
+#define AT_XVATTR 0x10000
+
+#define ATTR_XVATTR AT_XVATTR
+
+#define CRCREAT 0
+
+#define F_FREESP 11
+#define FIGNORECASE 0x80000 /* request case-insensitive lookups */
+
+
+#endif /* _SYS_VNODE_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/wmsum.h b/sys/contrib/openzfs/lib/libspl/include/sys/wmsum.h
index 0679af73ce91..36e37f9e17d4 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/wmsum.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/wmsum.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/zone.h b/sys/contrib/openzfs/lib/libspl/include/sys/zone.h
index bbb964dcef22..179cc004fdb8 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/zone.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/zone.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -20,11 +21,19 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
-#ifndef _LIBSPL_SYS_ZONE_H
-#define _LIBSPL_SYS_ZONE_H
+#ifndef _SYS_ZONE_H
+#define _SYS_ZONE_H
-#endif
+#define zone_dataset_visible(x, y) (1)
+
+#define INGLOBALZONE(z) (1)
+
+extern uint32_t zone_get_hostid(void *zonep);
+
+#endif /* _SYS_ZONE_H */
diff --git a/sys/contrib/openzfs/lib/libspl/include/umem.h b/sys/contrib/openzfs/lib/libspl/include/umem.h
index 288aaf3ecc36..1b79fee56d23 100644
--- a/sys/contrib/openzfs/lib/libspl/include/umem.h
+++ b/sys/contrib/openzfs/lib/libspl/include/umem.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -41,6 +42,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <errno.h>
#ifdef __cplusplus
extern "C" {
@@ -83,6 +85,7 @@ const char *_umem_debug_init(void);
const char *_umem_options_init(void);
const char *_umem_logging_init(void);
+__attribute__((malloc, alloc_size(1)))
static inline void *
umem_alloc(size_t size, int flags)
{
@@ -95,11 +98,12 @@ umem_alloc(size_t size, int flags)
return (ptr);
}
+__attribute__((malloc, alloc_size(1)))
static inline void *
umem_alloc_aligned(size_t size, size_t align, int flags)
{
void *ptr = NULL;
- int rc = EINVAL;
+ int rc;
do {
rc = posix_memalign(&ptr, align, size);
@@ -116,6 +120,7 @@ umem_alloc_aligned(size_t size, size_t align, int flags)
return (ptr);
}
+__attribute__((malloc, alloc_size(1)))
static inline void *
umem_zalloc(size_t size, int flags)
{
@@ -134,6 +139,21 @@ umem_free(const void *ptr, size_t size __maybe_unused)
free((void *)ptr);
}
+/*
+ * umem_free_aligned was added for supporting portability
+ * with non-POSIX platforms that require a different free
+ * to be used with aligned allocations.
+ */
+static inline void
+umem_free_aligned(void *ptr, size_t size __maybe_unused)
+{
+#ifndef _WIN32
+ free((void *)ptr);
+#else
+ _aligned_free(ptr);
+#endif
+}
+
static inline void
umem_nofail_callback(umem_nofail_callback_t *cb __maybe_unused)
{}
@@ -170,6 +190,7 @@ umem_cache_destroy(umem_cache_t *cp)
umem_free(cp, sizeof (umem_cache_t));
}
+__attribute__((malloc))
static inline void *
umem_cache_alloc(umem_cache_t *cp, int flags)
{
@@ -193,7 +214,10 @@ 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);
+ if (cp->cache_align != 0)
+ umem_free_aligned(ptr, cp->cache_bufsize);
+ else
+ umem_free(ptr, cp->cache_bufsize);
}
static inline void
diff --git a/sys/contrib/openzfs/lib/libspl/include/unistd.h b/sys/contrib/openzfs/lib/libspl/include/unistd.h
index 0246991b4b61..6d755eb8ad91 100644
--- a/sys/contrib/openzfs/lib/libspl/include/unistd.h
+++ b/sys/contrib/openzfs/lib/libspl/include/unistd.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/include/zone.h b/sys/contrib/openzfs/lib/libspl/include/zone.h
index 0af4e7a2fa49..f946c0f13f77 100644
--- a/sys/contrib/openzfs/lib/libspl/include/zone.h
+++ b/sys/contrib/openzfs/lib/libspl/include/zone.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/kmem.c b/sys/contrib/openzfs/lib/libspl/kmem.c
new file mode 100644
index 000000000000..c64e94597cf4
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/kmem.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <sys/kmem.h>
+
+char *
+kmem_vasprintf(const char *fmt, va_list adx)
+{
+ char *buf = NULL;
+ va_list adx_copy;
+
+ va_copy(adx_copy, adx);
+ VERIFY(vasprintf(&buf, fmt, adx_copy) != -1);
+ va_end(adx_copy);
+
+ return (buf);
+}
+
+char *
+kmem_asprintf(const char *fmt, ...)
+{
+ char *buf = NULL;
+ va_list adx;
+
+ va_start(adx, fmt);
+ VERIFY(vasprintf(&buf, fmt, adx) != -1);
+ va_end(adx);
+
+ return (buf);
+}
+
+/*
+ * kmem_scnprintf() will return the number of characters that it would have
+ * printed whenever it is limited by value of the size variable, rather than
+ * the number of characters that it did print. This can cause misbehavior on
+ * subsequent uses of the return value, so we define a safe version that will
+ * return the number of characters actually printed, minus the NULL format
+ * character. Subsequent use of this by the safe string functions is safe
+ * whether it is snprintf(), strlcat() or strlcpy().
+ */
+int
+kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...)
+{
+ int n;
+ va_list ap;
+
+ /* Make the 0 case a no-op so that we do not return -1 */
+ if (size == 0)
+ return (0);
+
+ va_start(ap, fmt);
+ n = vsnprintf(str, size, fmt, ap);
+ va_end(ap);
+
+ if (n >= size)
+ n = size - 1;
+
+ return (n);
+}
+
+fstrans_cookie_t
+spl_fstrans_mark(void)
+{
+ return ((fstrans_cookie_t)0);
+}
+
+void
+spl_fstrans_unmark(fstrans_cookie_t cookie)
+{
+ (void) cookie;
+}
+
+int
+kmem_cache_reap_active(void)
+{
+ return (0);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/kstat.c b/sys/contrib/openzfs/lib/libspl/kstat.c
new file mode 100644
index 000000000000..af4b870edadf
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/kstat.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <sys/kstat.h>
+
+/*
+ * =========================================================================
+ * kstats
+ * =========================================================================
+ */
+kstat_t *
+kstat_create(const char *module, int instance, const char *name,
+ const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag)
+{
+ (void) module, (void) instance, (void) name, (void) class, (void) type,
+ (void) ndata, (void) ks_flag;
+ return (NULL);
+}
+
+void
+kstat_install(kstat_t *ksp)
+{
+ (void) ksp;
+}
+
+void
+kstat_delete(kstat_t *ksp)
+{
+ (void) ksp;
+}
+
+void
+kstat_set_raw_ops(kstat_t *ksp,
+ int (*headers)(char *buf, size_t size),
+ int (*data)(char *buf, size_t size, void *data),
+ void *(*addr)(kstat_t *ksp, loff_t index))
+{
+ (void) ksp, (void) headers, (void) data, (void) addr;
+}
diff --git a/sys/contrib/openzfs/lib/libspl/libspl.c b/sys/contrib/openzfs/lib/libspl/libspl.c
new file mode 100644
index 000000000000..208b3e428536
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/libspl.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ * Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
+ */
+
+#include <libspl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/misc.h>
+#include <sys/systm.h>
+#include <sys/utsname.h>
+#include "libspl_impl.h"
+
+static uint64_t hw_physmem = 0;
+static struct utsname hw_utsname = {};
+
+uint64_t
+libspl_physmem(void)
+{
+ return (hw_physmem);
+}
+
+utsname_t *
+utsname(void)
+{
+ return (&hw_utsname);
+}
+
+void
+libspl_init(void)
+{
+ hw_physmem = sysconf(_SC_PHYS_PAGES);
+
+ VERIFY0(uname(&hw_utsname));
+
+ random_init();
+}
+
+void
+libspl_fini(void)
+{
+ random_fini();
+}
diff --git a/sys/contrib/openzfs/lib/libspl/libspl_impl.h b/sys/contrib/openzfs/lib/libspl/libspl_impl.h
index cda56e64c962..446801f2564b 100644
--- a/sys/contrib/openzfs/lib/libspl/libspl_impl.h
+++ b/sys/contrib/openzfs/lib/libspl/libspl_impl.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -20,5 +21,12 @@
* CDDL HEADER END
*/
+#ifndef _LIBSPL_IMPL_H
+#define _LIBSPL_IMPL_H
extern ssize_t getexecname_impl(char *execname);
+
+extern void random_init(void);
+extern void random_fini(void);
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/list.c b/sys/contrib/openzfs/lib/libspl/list.c
index 0f2f3731b235..f95b358153de 100644
--- a/sys/contrib/openzfs/lib/libspl/list.c
+++ b/sys/contrib/openzfs/lib/libspl/list.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -65,7 +66,8 @@ list_create(list_t *list, size_t size, size_t offset)
ASSERT(size > 0);
ASSERT(size >= offset + sizeof (list_node_t));
- list->list_size = size;
+ (void) size;
+
list->list_offset = offset;
list->list_head.next = list->list_head.prev = &list->list_head;
}
@@ -194,7 +196,6 @@ 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))
diff --git a/sys/contrib/openzfs/lib/libspl/mkdirp.c b/sys/contrib/openzfs/lib/libspl/mkdirp.c
index fce2c1c82eb7..80198dfbecba 100644
--- a/sys/contrib/openzfs/lib/libspl/mkdirp.c
+++ b/sys/contrib/openzfs/lib/libspl/mkdirp.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/mutex.c b/sys/contrib/openzfs/lib/libspl/mutex.c
new file mode 100644
index 000000000000..36e5bec396ed
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/mutex.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <assert.h>
+#include <pthread.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/mutex.h>
+
+/*
+ * =========================================================================
+ * mutexes
+ * =========================================================================
+ */
+
+void
+mutex_init(kmutex_t *mp, char *name, int type, void *cookie)
+{
+ (void) name, (void) type, (void) cookie;
+ VERIFY0(pthread_mutex_init(&mp->m_lock, NULL));
+ memset(&mp->m_owner, 0, sizeof (pthread_t));
+}
+
+void
+mutex_destroy(kmutex_t *mp)
+{
+ VERIFY0(pthread_mutex_destroy(&mp->m_lock));
+}
+
+void
+mutex_enter(kmutex_t *mp)
+{
+ VERIFY0(pthread_mutex_lock(&mp->m_lock));
+ mp->m_owner = pthread_self();
+}
+
+int
+mutex_enter_check_return(kmutex_t *mp)
+{
+ int error = pthread_mutex_lock(&mp->m_lock);
+ if (error == 0)
+ mp->m_owner = pthread_self();
+ return (error);
+}
+
+int
+mutex_tryenter(kmutex_t *mp)
+{
+ int error = pthread_mutex_trylock(&mp->m_lock);
+ if (error == 0) {
+ mp->m_owner = pthread_self();
+ return (1);
+ } else {
+ VERIFY3S(error, ==, EBUSY);
+ return (0);
+ }
+}
+
+void
+mutex_exit(kmutex_t *mp)
+{
+ memset(&mp->m_owner, 0, sizeof (pthread_t));
+ VERIFY0(pthread_mutex_unlock(&mp->m_lock));
+}
diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c
index 256b28c1b70e..49c0ce3a2432 100644
--- a/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c
+++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/gethostid.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/gethostid.c
index 7bd567fe61b5..bd0f3ee5a075 100644
--- a/sys/contrib/openzfs/lib/libspl/os/freebsd/gethostid.c
+++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/gethostid.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/getmntany.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/getmntany.c
index 0ef24059e84f..baff124b4a40 100644
--- a/sys/contrib/openzfs/lib/libspl/os/freebsd/getmntany.c
+++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/getmntany.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -36,6 +37,7 @@
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <libzutil.h>
int
getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
@@ -49,13 +51,13 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
if (stat64(path, statbuf) != 0) {
(void) fprintf(stderr, "cannot open '%s': %s\n",
- path, strerror(errno));
+ path, zfs_strerror(errno));
return (-1);
}
if (statfs(path, &sfs) != 0) {
(void) fprintf(stderr, "%s: %s\n", path,
- strerror(errno));
+ zfs_strerror(errno));
return (-1);
}
statfs2mnttab(&sfs, (struct mnttab *)entry);
diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c
index f0cc04d89ded..5287da132966 100644
--- a/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c
+++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* All rights reserved.
@@ -29,9 +30,6 @@
* functions.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/mntent.h>
@@ -74,7 +72,7 @@ hasmntopt(struct mnttab *mnt, const char *opt)
if (mnt->mnt_mntopts == NULL)
return (NULL);
- (void) strcpy(opts, mnt->mnt_mntopts);
+ (void) strlcpy(opts, mnt->mnt_mntopts, MNT_LINE_MAX);
f = mntopt(&opts);
for (; *f; f = mntopt(&opts)) {
if (strncmp(opt, f, strlen(opt)) == 0)
diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/zone.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/zone.c
index c07cb0532e16..d6f698207cd1 100644
--- a/sys/contrib/openzfs/lib/libspl/os/freebsd/zone.c
+++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/zone.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* All rights reserved.
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c b/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c
index a640556bcbec..dc4fe26ca550 100644
--- a/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c b/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c
index c04b7fd3eef3..d39f3dda3b8d 100644
--- a/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -59,6 +60,7 @@ unsigned long
get_system_hostid(void)
{
unsigned long hostid = get_spl_hostid();
+ uint32_t system_hostid;
/*
* We do not use gethostid(3) because it can return a bogus ID,
@@ -69,8 +71,11 @@ get_system_hostid(void)
if (hostid == 0) {
int fd = open("/etc/hostid", O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
- if (read(fd, &hostid, 4) < 0)
+ if (read(fd, &system_hostid, sizeof (system_hostid))
+ != sizeof (system_hostid))
hostid = 0;
+ else
+ hostid = system_hostid;
(void) close(fd);
}
}
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c b/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c
index 3713ff38e17f..ee1cdf59b9e5 100644
--- a/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -38,6 +39,7 @@
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <libzutil.h>
#define BUFSIZE (MNT_LINE_MAX + 2)
@@ -83,13 +85,21 @@ _sol_getmntent(FILE *fp, struct mnttab *mgetp)
}
static int
-getextmntent_impl(FILE *fp, struct extmnttab *mp)
+getextmntent_impl(FILE *fp, struct extmnttab *mp, uint64_t *mnt_id)
{
int ret;
struct stat64 st;
+ *mnt_id = 0;
ret = _sol_getmntent(fp, (struct mnttab *)mp);
if (ret == 0) {
+#ifdef HAVE_STATX_MNT_ID
+ struct statx stx;
+ if (statx(AT_FDCWD, mp->mnt_mountp,
+ AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW,
+ STATX_MNT_ID, &stx) == 0 && (stx.stx_mask & STATX_MNT_ID))
+ *mnt_id = stx.stx_mnt_id;
+#endif
if (stat64(mp->mnt_mountp, &st) != 0) {
mp->mnt_major = 0;
mp->mnt_minor = 0;
@@ -108,6 +118,12 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
struct stat64 st;
FILE *fp;
int match;
+ boolean_t have_mnt_id = B_FALSE;
+ uint64_t target_mnt_id = 0;
+ uint64_t entry_mnt_id;
+#ifdef HAVE_STATX_MNT_ID
+ struct statx stx;
+#endif
if (strlen(path) >= MAXPATHLEN) {
(void) fprintf(stderr, "invalid object; pathname too long\n");
@@ -122,10 +138,17 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
*/
if (stat64(path, statbuf) != 0) {
(void) fprintf(stderr, "cannot open '%s': %s\n",
- path, strerror(errno));
+ path, zfs_strerror(errno));
return (-1);
}
+#ifdef HAVE_STATX_MNT_ID
+ if (statx(AT_FDCWD, path, AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW,
+ STATX_MNT_ID, &stx) == 0 && (stx.stx_mask & STATX_MNT_ID)) {
+ have_mnt_id = B_TRUE;
+ target_mnt_id = stx.stx_mnt_id;
+ }
+#endif
if ((fp = fopen(MNTTAB, "re")) == NULL) {
(void) fprintf(stderr, "cannot open %s\n", MNTTAB);
@@ -137,12 +160,15 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
*/
match = 0;
- while (getextmntent_impl(fp, entry) == 0) {
- if (makedev(entry->mnt_major, entry->mnt_minor) ==
- statbuf->st_dev) {
- match = 1;
- break;
+ while (getextmntent_impl(fp, entry, &entry_mnt_id) == 0) {
+ if (have_mnt_id) {
+ match = (entry_mnt_id == target_mnt_id);
+ } else {
+ match = makedev(entry->mnt_major, entry->mnt_minor) ==
+ statbuf->st_dev;
}
+ if (match)
+ break;
}
(void) fclose(fp);
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/zone.c b/sys/contrib/openzfs/lib/libspl/os/linux/zone.c
index 65c02dfe7aab..f1520676753e 100644
--- a/sys/contrib/openzfs/lib/libspl/os/linux/zone.c
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/zone.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -41,21 +42,21 @@ getzoneid(void)
int c = snprintf(path, sizeof (path), "/proc/self/ns/user");
/* This API doesn't have any error checking... */
- if (c < 0)
- return (0);
+ if (c < 0 || c >= sizeof (path))
+ return (GLOBAL_ZONEID);
ssize_t r = readlink(path, buf, sizeof (buf) - 1);
if (r < 0)
- return (0);
+ return (GLOBAL_ZONEID);
cp = strchr(buf, '[');
if (cp == NULL)
- return (0);
+ return (GLOBAL_ZONEID);
cp++;
unsigned long n = strtoul(cp, NULL, 10);
if (n == ULONG_MAX && errno == ERANGE)
- return (0);
+ return (GLOBAL_ZONEID);
zoneid_t z = (zoneid_t)n;
return (z);
diff --git a/sys/contrib/openzfs/lib/libspl/page.c b/sys/contrib/openzfs/lib/libspl/page.c
index 5b0d3f2e5786..6160a1de10cd 100644
--- a/sys/contrib/openzfs/lib/libspl/page.c
+++ b/sys/contrib/openzfs/lib/libspl/page.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -7,7 +8,7 @@
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/procfs_list.c b/sys/contrib/openzfs/lib/libspl/procfs_list.c
new file mode 100644
index 000000000000..0ce327db6343
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/procfs_list.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <assert.h>
+#include <pthread.h>
+#include <stddef.h>
+#include <sys/procfs_list.h>
+#include <sys/mutex.h>
+#include <sys/list.h>
+
+/*
+ * =========================================================================
+ * procfs list
+ * =========================================================================
+ */
+
+void
+seq_printf(struct seq_file *m, const char *fmt, ...)
+{
+ (void) m, (void) fmt;
+}
+
+void
+procfs_list_install(const char *module,
+ const char *submodule,
+ const char *name,
+ mode_t mode,
+ procfs_list_t *procfs_list,
+ int (*show)(struct seq_file *f, void *p),
+ int (*show_header)(struct seq_file *f),
+ int (*clear)(procfs_list_t *procfs_list),
+ size_t procfs_list_node_off)
+{
+ (void) module, (void) submodule, (void) name, (void) mode, (void) show,
+ (void) show_header, (void) clear;
+ mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL);
+ list_create(&procfs_list->pl_list,
+ procfs_list_node_off + sizeof (procfs_list_node_t),
+ procfs_list_node_off + offsetof(procfs_list_node_t, pln_link));
+ procfs_list->pl_next_id = 1;
+ procfs_list->pl_node_offset = procfs_list_node_off;
+}
+
+void
+procfs_list_uninstall(procfs_list_t *procfs_list)
+{
+ (void) procfs_list;
+}
+
+void
+procfs_list_destroy(procfs_list_t *procfs_list)
+{
+ ASSERT(list_is_empty(&procfs_list->pl_list));
+ list_destroy(&procfs_list->pl_list);
+ mutex_destroy(&procfs_list->pl_lock);
+}
+
+#define NODE_ID(procfs_list, obj) \
+ (((procfs_list_node_t *)(((char *)obj) + \
+ (procfs_list)->pl_node_offset))->pln_id)
+
+void
+procfs_list_add(procfs_list_t *procfs_list, void *p)
+{
+ ASSERT(MUTEX_HELD(&procfs_list->pl_lock));
+ NODE_ID(procfs_list, p) = procfs_list->pl_next_id++;
+ list_insert_tail(&procfs_list->pl_list, p);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/random.c b/sys/contrib/openzfs/lib/libspl/random.c
new file mode 100644
index 000000000000..c6f0ee7ae0f7
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/random.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <sys/random.h>
+#include "libspl_impl.h"
+
+#define RANDOM_PATH "/dev/random"
+#define URANDOM_PATH "/dev/urandom"
+
+static int random_fd = -1, urandom_fd = -1;
+
+static boolean_t force_pseudo = B_FALSE;
+
+void
+random_init(void)
+{
+ /* Handle multiple calls. */
+ if (random_fd != -1) {
+ ASSERT3U(urandom_fd, !=, -1);
+ return;
+ }
+
+ VERIFY((random_fd = open(RANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1);
+ VERIFY((urandom_fd = open(URANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1);
+}
+
+void
+random_fini(void)
+{
+ close(random_fd);
+ close(urandom_fd);
+
+ random_fd = -1;
+ urandom_fd = -1;
+}
+
+void
+random_force_pseudo(boolean_t onoff)
+{
+ force_pseudo = onoff;
+}
+
+static int
+random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
+{
+ size_t resid = len;
+ ssize_t bytes;
+
+ ASSERT(fd != -1);
+
+ while (resid != 0) {
+ bytes = read(fd, ptr, resid);
+ ASSERT3S(bytes, >=, 0);
+ ptr += bytes;
+ resid -= bytes;
+ }
+
+ return (0);
+}
+
+int
+random_get_bytes(uint8_t *ptr, size_t len)
+{
+ if (force_pseudo)
+ return (random_get_pseudo_bytes(ptr, len));
+ return (random_get_bytes_common(ptr, len, random_fd));
+}
+
+int
+random_get_pseudo_bytes(uint8_t *ptr, size_t len)
+{
+ return (random_get_bytes_common(ptr, len, urandom_fd));
+}
diff --git a/sys/contrib/openzfs/lib/libspl/rwlock.c b/sys/contrib/openzfs/lib/libspl/rwlock.c
new file mode 100644
index 000000000000..3712829ef594
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/rwlock.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <assert.h>
+#include <pthread.h>
+#include <errno.h>
+#include <atomic.h>
+#include <sys/rwlock.h>
+
+/*
+ * =========================================================================
+ * rwlocks
+ * =========================================================================
+ */
+
+void
+rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
+{
+ (void) name, (void) type, (void) arg;
+ VERIFY0(pthread_rwlock_init(&rwlp->rw_lock, NULL));
+ rwlp->rw_readers = 0;
+ rwlp->rw_owner = 0;
+}
+
+void
+rw_destroy(krwlock_t *rwlp)
+{
+ VERIFY0(pthread_rwlock_destroy(&rwlp->rw_lock));
+}
+
+void
+rw_enter(krwlock_t *rwlp, krw_t rw)
+{
+ if (rw == RW_READER) {
+ VERIFY0(pthread_rwlock_rdlock(&rwlp->rw_lock));
+ atomic_inc_uint(&rwlp->rw_readers);
+ } else {
+ VERIFY0(pthread_rwlock_wrlock(&rwlp->rw_lock));
+ rwlp->rw_owner = pthread_self();
+ }
+}
+
+void
+rw_exit(krwlock_t *rwlp)
+{
+ if (RW_READ_HELD(rwlp))
+ atomic_dec_uint(&rwlp->rw_readers);
+ else
+ rwlp->rw_owner = 0;
+
+ VERIFY0(pthread_rwlock_unlock(&rwlp->rw_lock));
+}
+
+int
+rw_tryenter(krwlock_t *rwlp, krw_t rw)
+{
+ int error;
+
+ if (rw == RW_READER)
+ error = pthread_rwlock_tryrdlock(&rwlp->rw_lock);
+ else
+ error = pthread_rwlock_trywrlock(&rwlp->rw_lock);
+
+ if (error == 0) {
+ if (rw == RW_READER)
+ atomic_inc_uint(&rwlp->rw_readers);
+ else
+ rwlp->rw_owner = pthread_self();
+
+ return (1);
+ }
+
+ VERIFY3S(error, ==, EBUSY);
+
+ return (0);
+}
+
+int
+rw_tryupgrade(krwlock_t *rwlp)
+{
+ (void) rwlp;
+ return (0);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/sid.c b/sys/contrib/openzfs/lib/libspl/sid.c
new file mode 100644
index 000000000000..b7d5b5f2e778
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/sid.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <sys/sid.h>
+#include <umem.h>
+
+ksiddomain_t *
+ksid_lookupdomain(const char *dom)
+{
+ ksiddomain_t *kd;
+
+ kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
+ kd->kd_name = strdup(dom);
+ return (kd);
+}
+
+void
+ksiddomain_rele(ksiddomain_t *ksid)
+{
+ free(ksid->kd_name);
+ umem_free(ksid, sizeof (ksiddomain_t));
+}
diff --git a/sys/contrib/openzfs/lib/libspl/strlcat.c b/sys/contrib/openzfs/lib/libspl/strlcat.c
index 4528d875ed5e..6e4c3280a83a 100644
--- a/sys/contrib/openzfs/lib/libspl/strlcat.c
+++ b/sys/contrib/openzfs/lib/libspl/strlcat.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/strlcpy.c b/sys/contrib/openzfs/lib/libspl/strlcpy.c
index d483b91f6121..49ffa2db67c5 100644
--- a/sys/contrib/openzfs/lib/libspl/strlcpy.c
+++ b/sys/contrib/openzfs/lib/libspl/strlcpy.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
diff --git a/sys/contrib/openzfs/lib/libspl/taskq.c b/sys/contrib/openzfs/lib/libspl/taskq.c
new file mode 100644
index 000000000000..043f70225551
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/taskq.c
@@ -0,0 +1,425 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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.
+ */
+/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
+ * Copyright (c) 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/sysmacros.h>
+#include <sys/timer.h>
+#include <sys/types.h>
+#include <sys/thread.h>
+#include <sys/taskq.h>
+#include <sys/kmem.h>
+
+static taskq_t *__system_taskq = NULL;
+static taskq_t *__system_delay_taskq = NULL;
+
+taskq_t
+*_system_taskq(void)
+{
+ return (__system_taskq);
+}
+
+taskq_t
+*_system_delay_taskq(void)
+{
+ return (__system_delay_taskq);
+}
+
+static pthread_key_t taskq_tsd;
+
+#define TASKQ_ACTIVE 0x00010000
+
+static taskq_ent_t *
+task_alloc(taskq_t *tq, int tqflags)
+{
+ taskq_ent_t *t;
+ int rv;
+
+again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
+ ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC));
+ tq->tq_freelist = t->tqent_next;
+ } else {
+ if (tq->tq_nalloc >= tq->tq_maxalloc) {
+ if (!(tqflags & KM_SLEEP))
+ return (NULL);
+
+ /*
+ * We don't want to exceed tq_maxalloc, but we can't
+ * wait for other tasks to complete (and thus free up
+ * task structures) without risking deadlock with
+ * the caller. So, we just delay for one second
+ * to throttle the allocation rate. If we have tasks
+ * complete before one second timeout expires then
+ * taskq_ent_free will signal us and we will
+ * immediately retry the allocation.
+ */
+ tq->tq_maxalloc_wait++;
+ rv = cv_timedwait(&tq->tq_maxalloc_cv,
+ &tq->tq_lock, ddi_get_lbolt() + hz);
+ tq->tq_maxalloc_wait--;
+ if (rv > 0)
+ goto again; /* signaled */
+ }
+ mutex_exit(&tq->tq_lock);
+
+ t = kmem_alloc(sizeof (taskq_ent_t), tqflags);
+
+ mutex_enter(&tq->tq_lock);
+ if (t != NULL) {
+ /* Make sure we start without any flags */
+ t->tqent_flags = 0;
+ tq->tq_nalloc++;
+ }
+ }
+ return (t);
+}
+
+static void
+task_free(taskq_t *tq, taskq_ent_t *t)
+{
+ if (tq->tq_nalloc <= tq->tq_minalloc) {
+ t->tqent_next = tq->tq_freelist;
+ tq->tq_freelist = t;
+ } else {
+ tq->tq_nalloc--;
+ mutex_exit(&tq->tq_lock);
+ kmem_free(t, sizeof (taskq_ent_t));
+ mutex_enter(&tq->tq_lock);
+ }
+
+ if (tq->tq_maxalloc_wait)
+ cv_signal(&tq->tq_maxalloc_cv);
+}
+
+taskqid_t
+taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
+{
+ taskq_ent_t *t;
+
+ mutex_enter(&tq->tq_lock);
+ ASSERT(tq->tq_flags & TASKQ_ACTIVE);
+ if ((t = task_alloc(tq, tqflags)) == NULL) {
+ mutex_exit(&tq->tq_lock);
+ return (0);
+ }
+ if (tqflags & TQ_FRONT) {
+ t->tqent_next = tq->tq_task.tqent_next;
+ t->tqent_prev = &tq->tq_task;
+ } else {
+ t->tqent_next = &tq->tq_task;
+ t->tqent_prev = tq->tq_task.tqent_prev;
+ }
+ t->tqent_next->tqent_prev = t;
+ t->tqent_prev->tqent_next = t;
+ t->tqent_func = func;
+ t->tqent_arg = arg;
+ t->tqent_flags = 0;
+ cv_signal(&tq->tq_dispatch_cv);
+ mutex_exit(&tq->tq_lock);
+ return (1);
+}
+
+taskqid_t
+taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags,
+ clock_t expire_time)
+{
+ (void) tq, (void) func, (void) arg, (void) tqflags, (void) expire_time;
+ return (0);
+}
+
+int
+taskq_empty_ent(taskq_ent_t *t)
+{
+ return (t->tqent_next == NULL);
+}
+
+void
+taskq_init_ent(taskq_ent_t *t)
+{
+ t->tqent_next = NULL;
+ t->tqent_prev = NULL;
+ t->tqent_func = NULL;
+ t->tqent_arg = NULL;
+ t->tqent_flags = 0;
+}
+
+void
+taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
+ taskq_ent_t *t)
+{
+ ASSERT(func != NULL);
+
+ /*
+ * Mark it as a prealloc'd task. This is important
+ * to ensure that we don't free it later.
+ */
+ t->tqent_flags |= TQENT_FLAG_PREALLOC;
+ /*
+ * Enqueue the task to the underlying queue.
+ */
+ mutex_enter(&tq->tq_lock);
+
+ if (flags & TQ_FRONT) {
+ t->tqent_next = tq->tq_task.tqent_next;
+ t->tqent_prev = &tq->tq_task;
+ } else {
+ t->tqent_next = &tq->tq_task;
+ t->tqent_prev = tq->tq_task.tqent_prev;
+ }
+ t->tqent_next->tqent_prev = t;
+ t->tqent_prev->tqent_next = t;
+ t->tqent_func = func;
+ t->tqent_arg = arg;
+ cv_signal(&tq->tq_dispatch_cv);
+ mutex_exit(&tq->tq_lock);
+}
+
+void
+taskq_wait(taskq_t *tq)
+{
+ mutex_enter(&tq->tq_lock);
+ while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0)
+ cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
+ mutex_exit(&tq->tq_lock);
+}
+
+void
+taskq_wait_id(taskq_t *tq, taskqid_t id)
+{
+ (void) id;
+ taskq_wait(tq);
+}
+
+void
+taskq_wait_outstanding(taskq_t *tq, taskqid_t id)
+{
+ (void) id;
+ taskq_wait(tq);
+}
+
+static __attribute__((noreturn)) void
+taskq_thread(void *arg)
+{
+ taskq_t *tq = arg;
+ taskq_ent_t *t;
+ boolean_t prealloc;
+
+ VERIFY0(pthread_setspecific(taskq_tsd, tq));
+
+ mutex_enter(&tq->tq_lock);
+ while (tq->tq_flags & TASKQ_ACTIVE) {
+ if ((t = tq->tq_task.tqent_next) == &tq->tq_task) {
+ if (--tq->tq_active == 0)
+ cv_broadcast(&tq->tq_wait_cv);
+ cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock);
+ tq->tq_active++;
+ continue;
+ }
+ t->tqent_prev->tqent_next = t->tqent_next;
+ t->tqent_next->tqent_prev = t->tqent_prev;
+ t->tqent_next = NULL;
+ t->tqent_prev = NULL;
+ prealloc = t->tqent_flags & TQENT_FLAG_PREALLOC;
+ mutex_exit(&tq->tq_lock);
+
+ rw_enter(&tq->tq_threadlock, RW_READER);
+ t->tqent_func(t->tqent_arg);
+ rw_exit(&tq->tq_threadlock);
+
+ mutex_enter(&tq->tq_lock);
+ if (!prealloc)
+ task_free(tq, t);
+ }
+ tq->tq_nthreads--;
+ cv_broadcast(&tq->tq_wait_cv);
+ mutex_exit(&tq->tq_lock);
+ thread_exit();
+}
+
+taskq_t *
+taskq_create(const char *name, int nthreads, pri_t pri,
+ int minalloc, int maxalloc, uint_t flags)
+{
+ (void) pri;
+ taskq_t *tq = kmem_zalloc(sizeof (taskq_t), KM_SLEEP);
+ int t;
+
+ if (flags & TASKQ_THREADS_CPU_PCT) {
+ int pct;
+ ASSERT3S(nthreads, >=, 0);
+ ASSERT3S(nthreads, <=, 100);
+ pct = MIN(nthreads, 100);
+ pct = MAX(pct, 0);
+
+ nthreads = (sysconf(_SC_NPROCESSORS_ONLN) * pct) / 100;
+ nthreads = MAX(nthreads, 1); /* need at least 1 thread */
+ } else {
+ ASSERT3S(nthreads, >=, 1);
+ }
+
+ rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL);
+ mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL);
+ cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL);
+ cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL);
+ cv_init(&tq->tq_maxalloc_cv, NULL, CV_DEFAULT, NULL);
+ (void) strlcpy(tq->tq_name, name, sizeof (tq->tq_name));
+ tq->tq_flags = flags | TASKQ_ACTIVE;
+ tq->tq_active = nthreads;
+ tq->tq_nthreads = nthreads;
+ tq->tq_minalloc = minalloc;
+ tq->tq_maxalloc = maxalloc;
+ tq->tq_task.tqent_next = &tq->tq_task;
+ tq->tq_task.tqent_prev = &tq->tq_task;
+ tq->tq_threadlist = kmem_alloc(nthreads * sizeof (kthread_t *),
+ KM_SLEEP);
+
+ if (flags & TASKQ_PREPOPULATE) {
+ mutex_enter(&tq->tq_lock);
+ while (minalloc-- > 0)
+ task_free(tq, task_alloc(tq, KM_SLEEP));
+ mutex_exit(&tq->tq_lock);
+ }
+
+ for (t = 0; t < nthreads; t++)
+ VERIFY((tq->tq_threadlist[t] = thread_create_named(tq->tq_name,
+ NULL, 0, taskq_thread, tq, 0, &p0, TS_RUN, pri)) != NULL);
+
+ return (tq);
+}
+
+void
+taskq_destroy(taskq_t *tq)
+{
+ int nthreads = tq->tq_nthreads;
+
+ taskq_wait(tq);
+
+ mutex_enter(&tq->tq_lock);
+
+ tq->tq_flags &= ~TASKQ_ACTIVE;
+ cv_broadcast(&tq->tq_dispatch_cv);
+
+ while (tq->tq_nthreads != 0)
+ cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
+
+ tq->tq_minalloc = 0;
+ while (tq->tq_nalloc != 0) {
+ ASSERT(tq->tq_freelist != NULL);
+ taskq_ent_t *tqent_nexttq = tq->tq_freelist->tqent_next;
+ task_free(tq, tq->tq_freelist);
+ tq->tq_freelist = tqent_nexttq;
+ }
+
+ mutex_exit(&tq->tq_lock);
+
+ kmem_free(tq->tq_threadlist, nthreads * sizeof (kthread_t *));
+
+ rw_destroy(&tq->tq_threadlock);
+ mutex_destroy(&tq->tq_lock);
+ cv_destroy(&tq->tq_dispatch_cv);
+ cv_destroy(&tq->tq_wait_cv);
+ cv_destroy(&tq->tq_maxalloc_cv);
+
+ kmem_free(tq, sizeof (taskq_t));
+}
+
+/*
+ * Create a taskq with a specified number of pool threads. Allocate
+ * and return an array of nthreads kthread_t pointers, one for each
+ * thread in the pool. The array is not ordered and must be freed
+ * by the caller.
+ */
+taskq_t *
+taskq_create_synced(const char *name, int nthreads, pri_t pri,
+ int minalloc, int maxalloc, uint_t flags, kthread_t ***ktpp)
+{
+ taskq_t *tq;
+ kthread_t **kthreads = kmem_zalloc(sizeof (*kthreads) * nthreads,
+ KM_SLEEP);
+
+ (void) pri; (void) minalloc; (void) maxalloc;
+
+ flags &= ~(TASKQ_DYNAMIC | TASKQ_THREADS_CPU_PCT | TASKQ_DC_BATCH);
+
+ tq = taskq_create(name, nthreads, minclsyspri, nthreads, INT_MAX,
+ flags | TASKQ_PREPOPULATE);
+ VERIFY(tq != NULL);
+ VERIFY(tq->tq_nthreads == nthreads);
+
+ for (int i = 0; i < nthreads; i++) {
+ kthreads[i] = tq->tq_threadlist[i];
+ }
+ *ktpp = kthreads;
+ return (tq);
+}
+
+int
+taskq_member(taskq_t *tq, kthread_t *t)
+{
+ int i;
+
+ for (i = 0; i < tq->tq_nthreads; i++)
+ if (tq->tq_threadlist[i] == t)
+ return (1);
+
+ return (0);
+}
+
+taskq_t *
+taskq_of_curthread(void)
+{
+ return (pthread_getspecific(taskq_tsd));
+}
+
+int
+taskq_cancel_id(taskq_t *tq, taskqid_t id)
+{
+ (void) tq, (void) id;
+ return (ENOENT);
+}
+
+void
+system_taskq_init(void)
+{
+ VERIFY0(pthread_key_create(&taskq_tsd, NULL));
+ __system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512,
+ TASKQ_DYNAMIC | TASKQ_PREPOPULATE);
+ __system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4,
+ 512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE);
+}
+
+void
+system_taskq_fini(void)
+{
+ taskq_destroy(__system_taskq);
+ __system_taskq = NULL; /* defensive */
+ taskq_destroy(__system_delay_taskq);
+ __system_delay_taskq = NULL;
+ VERIFY0(pthread_key_delete(taskq_tsd));
+}
diff --git a/sys/contrib/openzfs/lib/libspl/thread.c b/sys/contrib/openzfs/lib/libspl/thread.c
new file mode 100644
index 000000000000..f00e0a01a06b
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/thread.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <assert.h>
+#include <pthread.h>
+#include <string.h>
+#include <sys/thread.h>
+
+/* this only exists to have its address taken */
+void p0(void) {}
+
+/*
+ * =========================================================================
+ * threads
+ * =========================================================================
+ *
+ * TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While
+ * TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for
+ * the expected stack depth while small enough to avoid exhausting address
+ * space with high thread counts.
+ */
+#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768)
+#define TS_STACK_MAX (256 * 1024)
+
+struct zk_thread_wrapper {
+ void (*func)(void *);
+ void *arg;
+};
+
+static void *
+zk_thread_wrapper(void *arg)
+{
+ struct zk_thread_wrapper ztw;
+ memcpy(&ztw, arg, sizeof (ztw));
+ free(arg);
+ ztw.func(ztw.arg);
+ return (NULL);
+}
+
+kthread_t *
+zk_thread_create(const char *name, void (*func)(void *), void *arg,
+ size_t stksize, int state)
+{
+ pthread_attr_t attr;
+ pthread_t tid;
+ char *stkstr;
+ struct zk_thread_wrapper *ztw;
+ int detachstate = PTHREAD_CREATE_DETACHED;
+
+ VERIFY0(pthread_attr_init(&attr));
+
+ if (state & TS_JOINABLE)
+ detachstate = PTHREAD_CREATE_JOINABLE;
+
+ VERIFY0(pthread_attr_setdetachstate(&attr, detachstate));
+
+ /*
+ * We allow the default stack size in user space to be specified by
+ * setting the ZFS_STACK_SIZE environment variable. This allows us
+ * the convenience of observing and debugging stack overruns in
+ * user space. Explicitly specified stack sizes will be honored.
+ * The usage of ZFS_STACK_SIZE is discussed further in the
+ * ENVIRONMENT VARIABLES sections of the ztest(1) man page.
+ */
+ if (stksize == 0) {
+ stkstr = getenv("ZFS_STACK_SIZE");
+
+ if (stkstr == NULL)
+ stksize = TS_STACK_MAX;
+ else
+ stksize = MAX(atoi(stkstr), TS_STACK_MIN);
+ }
+
+ VERIFY3S(stksize, >, 0);
+ stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);
+
+ /*
+ * If this ever fails, it may be because the stack size is not a
+ * multiple of system page size.
+ */
+ VERIFY0(pthread_attr_setstacksize(&attr, stksize));
+ VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));
+
+ VERIFY(ztw = malloc(sizeof (*ztw)));
+ ztw->func = func;
+ ztw->arg = arg;
+ VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw));
+ VERIFY0(pthread_attr_destroy(&attr));
+
+ pthread_setname_np(tid, name);
+
+ return ((void *)(uintptr_t)tid);
+}
diff --git a/sys/contrib/openzfs/lib/libspl/timestamp.c b/sys/contrib/openzfs/lib/libspl/timestamp.c
index 8d14ae645734..0b0838f4b442 100644
--- a/sys/contrib/openzfs/lib/libspl/timestamp.c
+++ b/sys/contrib/openzfs/lib/libspl/timestamp.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
@@ -6,7 +7,7 @@
* 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.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -62,3 +63,45 @@ print_timestamp(uint_t timestamp_fmt)
(void) printf("%s\n", dstr);
}
}
+
+/*
+ * Return timestamp as decimal reprentation (in string) of time_t
+ * value (-T u was specified) or in date(1) format (-T d was specified).
+ */
+void
+get_timestamp(uint_t timestamp_fmt, char *buf, int len)
+{
+ time_t t = time(NULL);
+ static const 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) snprintf(buf, len, "%lld", (longlong_t)t);
+ } else if (timestamp_fmt == DDATE) {
+ struct tm tm;
+ strftime(buf, len, fmt, localtime_r(&t, &tm));
+ }
+}
+
+/*
+ * Format the provided time stamp to human readable format
+ */
+void
+format_timestamp(time_t t, char *buf, int len)
+{
+ struct tm tm;
+ static const char *fmt = NULL;
+
+ if (t == 0) {
+ snprintf(buf, len, "-");
+ return;
+ }
+
+ /* We only need to retrieve this once per invocation */
+ if (fmt == NULL)
+ fmt = nl_langinfo(_DATE_FMT);
+ strftime(buf, len, fmt, localtime_r(&t, &tm));
+}
diff --git a/sys/contrib/openzfs/lib/libspl/tunables.c b/sys/contrib/openzfs/lib/libspl/tunables.c
new file mode 100644
index 000000000000..67dc9710dee8
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/tunables.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * 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 https://opensource.org/licenses/CDDL-1.0.
+ * 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) 2025, Rob Norris <robn@despairlabs.com>
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <sys/tunables.h>
+
+/*
+ * Userspace tunables.
+ *
+ * Tunables are external pointers to global variables that are wired up to the
+ * host environment in some way that allows the operator to directly change
+ * their values "under the hood".
+ *
+ * In userspace, the "host environment" is the program using libzpool.so. So
+ * that it can manipulate tunables if it wants, we provide an API to access
+ * them.
+ *
+ * Tunables are declared through the ZFS_MODULE_PARAM* macros, which associate
+ * a global variable with some metadata we can use to describe and access the
+ * tunable. This is done by creating a uniquely-named zfs_tunable_t.
+ *
+ * At runtime, we need a way to discover these zfs_tunable_t items. Since they
+ * are declared globally, all over the codebase, there's no central place to
+ * record or list them. So, we take advantage of the compiler's "linker set"
+ * feature.
+ *
+ * In the ZFS_MODULE_PARAM macro, after we create the zfs_tunable_t, we also
+ * create a zfs_tunable_t* pointing to it. That pointer is forced into the
+ * "zfs_tunables" ELF section in compiled object. At link time, the linker will
+ * collect all these pointers into one single big "zfs_tunable" section, and
+ * will generate two new symbols in the final object: __start_zfs_tunable and
+ * __stop_zfs_tunable. These point to the first and last item in that section,
+ * which allows us to access the pointers in that section like an array, and
+ * through those pointers access the tunable metadata, and from there the
+ * actual C variable that the tunable describes.
+ */
+
+extern const zfs_tunable_t *__start_zfs_tunables;
+extern const zfs_tunable_t *__stop_zfs_tunables;
+
+/*
+ * Because there are no tunables in libspl itself, the above symbols will not
+ * be generated, which will stop libspl being linked at all. To work around
+ * that, we force a symbol into that section, and then when iterating, skip
+ * any NULL pointers.
+ */
+static void *__zfs_tunable__placeholder
+ __attribute__((__section__("zfs_tunables")))
+ __attribute__((__used__)) = NULL;
+
+/*
+ * Find the name tunable by walking through the linker set and comparing names,
+ * as described above. This is not particularly efficient but it's a fairly
+ * rare task, so it shouldn't be a big deal.
+ */
+const zfs_tunable_t *
+zfs_tunable_lookup(const char *name)
+{
+ for (const zfs_tunable_t **ztp = &__start_zfs_tunables;
+ ztp != &__stop_zfs_tunables; ztp++) {
+ const zfs_tunable_t *zt = *ztp;
+ if (zt == NULL)
+ continue;
+ if (strcmp(name, zt->zt_name) == 0)
+ return (zt);
+ }
+
+ return (NULL);
+}
+
+/*
+ * Like zfs_tunable_lookup, but call the provided callback for each tunable.
+ */
+void
+zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg)
+{
+ for (const zfs_tunable_t **ztp = &__start_zfs_tunables;
+ ztp != &__stop_zfs_tunables; ztp++) {
+ const zfs_tunable_t *zt = *ztp;
+ if (zt == NULL)
+ continue;
+ if (cb(zt, arg))
+ return;
+ }
+}
+
+/*
+ * Parse a string into an int or uint. It's easier to have a pair of "generic"
+ * functions that clamp to a given min and max rather than have multiple
+ * functions for each width of type.
+ */
+static int
+zfs_tunable_parse_int(const char *val, intmax_t *np,
+ intmax_t min, intmax_t max)
+{
+ intmax_t n;
+ char *end;
+ errno = 0;
+ n = strtoimax(val, &end, 0);
+ if (errno != 0)
+ return (errno);
+ if (*end != '\0')
+ return (EINVAL);
+ if (n < min || n > max)
+ return (ERANGE);
+ *np = n;
+ return (0);
+}
+
+static int
+zfs_tunable_parse_uint(const char *val, uintmax_t *np,
+ uintmax_t min, uintmax_t max)
+{
+ uintmax_t n;
+ char *end;
+ errno = 0;
+ n = strtoumax(val, &end, 0);
+ if (errno != 0)
+ return (errno);
+ if (*end != '\0')
+ return (EINVAL);
+ if (strchr(val, '-'))
+ return (ERANGE);
+ if (n < min || n > max)
+ return (ERANGE);
+ *np = n;
+ return (0);
+}
+
+/*
+ * Set helpers for each tunable type. Parses the string, and if produces a
+ * valid value for the tunable, sets it. No effort is made to make sure the
+ * tunable is of the right type; that's done in zfs_tunable_set() below.
+ */
+static int
+zfs_tunable_set_int(const zfs_tunable_t *zt, const char *val)
+{
+ intmax_t n;
+ int err = zfs_tunable_parse_int(val, &n, INT_MIN, INT_MAX);
+ if (err != 0)
+ return (err);
+ *(int *)zt->zt_varp = n;
+ return (0);
+}
+
+static int
+zfs_tunable_set_uint(const zfs_tunable_t *zt, const char *val)
+{
+ uintmax_t n;
+ int err = zfs_tunable_parse_uint(val, &n, 0, UINT_MAX);
+ if (err != 0)
+ return (err);
+ *(unsigned int *)zt->zt_varp = n;
+ return (0);
+}
+
+static int
+zfs_tunable_set_ulong(const zfs_tunable_t *zt, const char *val)
+{
+ uintmax_t n;
+ int err = zfs_tunable_parse_uint(val, &n, 0, ULONG_MAX);
+ if (err != 0)
+ return (err);
+ *(unsigned long *)zt->zt_varp = n;
+ return (0);
+}
+
+static int
+zfs_tunable_set_u64(const zfs_tunable_t *zt, const char *val)
+{
+ uintmax_t n;
+ int err = zfs_tunable_parse_uint(val, &n, 0, UINT64_MAX);
+ if (err != 0)
+ return (err);
+ *(uint64_t *)zt->zt_varp = n;
+ return (0);
+}
+
+static int
+zfs_tunable_set_string(const zfs_tunable_t *zt, const char *val)
+{
+ (void) zt, (void) val;
+ /*
+ * We can't currently handle strings. String tunables are pointers
+ * into read-only memory, so we can update the pointer, but not the
+ * contents. That would mean taking an allocation, but we don't have
+ * an obvious place to free it.
+ *
+ * For now, it's no big deal as there's only a couple of string
+ * tunables anyway.
+ */
+ return (ENOTSUP);
+}
+
+/*
+ * Get helpers for each tunable type. Converts the value to a string if
+ * necessary and writes it into the provided buffer. The type is assumed to
+ * be correct; zfs_tunable_get() below will call the correct function for the
+ * type.
+ */
+static int
+zfs_tunable_get_int(const zfs_tunable_t *zt, char *val, size_t valsz)
+{
+ snprintf(val, valsz, "%d", *(int *)zt->zt_varp);
+ return (0);
+}
+
+static int
+zfs_tunable_get_uint(const zfs_tunable_t *zt, char *val, size_t valsz)
+{
+ snprintf(val, valsz, "%u", *(unsigned int *)zt->zt_varp);
+ return (0);
+}
+
+static int
+zfs_tunable_get_ulong(const zfs_tunable_t *zt, char *val, size_t valsz)
+{
+ snprintf(val, valsz, "%lu", *(unsigned long *)zt->zt_varp);
+ return (0);
+}
+
+static int
+zfs_tunable_get_u64(const zfs_tunable_t *zt, char *val, size_t valsz)
+{
+ snprintf(val, valsz, "%"PRIu64, *(uint64_t *)zt->zt_varp);
+ return (0);
+}
+
+static int
+zfs_tunable_get_string(const zfs_tunable_t *zt, char *val, size_t valsz)
+{
+ strlcpy(val, *(char **)zt->zt_varp, valsz);
+ return (0);
+}
+
+/* The public set function. Delegates to the type-specific version. */
+int
+zfs_tunable_set(const zfs_tunable_t *zt, const char *val)
+{
+ int err;
+ switch (zt->zt_type) {
+ case ZFS_TUNABLE_TYPE_INT:
+ err = zfs_tunable_set_int(zt, val);
+ break;
+ case ZFS_TUNABLE_TYPE_UINT:
+ err = zfs_tunable_set_uint(zt, val);
+ break;
+ case ZFS_TUNABLE_TYPE_ULONG:
+ err = zfs_tunable_set_ulong(zt, val);
+ break;
+ case ZFS_TUNABLE_TYPE_U64:
+ err = zfs_tunable_set_u64(zt, val);
+ break;
+ case ZFS_TUNABLE_TYPE_STRING:
+ err = zfs_tunable_set_string(zt, val);
+ break;
+ default:
+ err = EOPNOTSUPP;
+ break;
+ }
+ return (err);
+}
+
+/* The public get function. Delegates to the type-specific version. */
+int
+zfs_tunable_get(const zfs_tunable_t *zt, char *val, size_t valsz)
+{
+ int err;
+ switch (zt->zt_type) {
+ case ZFS_TUNABLE_TYPE_INT:
+ err = zfs_tunable_get_int(zt, val, valsz);
+ break;
+ case ZFS_TUNABLE_TYPE_UINT:
+ err = zfs_tunable_get_uint(zt, val, valsz);
+ break;
+ case ZFS_TUNABLE_TYPE_ULONG:
+ err = zfs_tunable_get_ulong(zt, val, valsz);
+ break;
+ case ZFS_TUNABLE_TYPE_U64:
+ err = zfs_tunable_get_u64(zt, val, valsz);
+ break;
+ case ZFS_TUNABLE_TYPE_STRING:
+ err = zfs_tunable_get_string(zt, val, valsz);
+ break;
+ default:
+ err = EOPNOTSUPP;
+ break;
+ }
+ return (err);
+}