diff --git a/cmd/raidz_test/raidz_test.c b/cmd/raidz_test/raidz_test.c index cf3e123c6090..4839e909e4f7 100644 --- a/cmd/raidz_test/raidz_test.c +++ b/cmd/raidz_test/raidz_test.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "raidz_test.h" static int *rand_data; diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 2560ad045db3..9c1fc543b419 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -89,6 +89,7 @@ #include #include +#include #include #include #include diff --git a/cmd/zhack.c b/cmd/zhack.c index 8ffbf91ffb30..536e3880718c 100644 --- a/cmd/zhack.c +++ b/cmd/zhack.c @@ -55,6 +55,7 @@ #include #include #include +#include static importargs_t g_importargs; static char *g_pool; diff --git a/cmd/ztest.c b/cmd/ztest.c index 7d590e5e06da..0cb83ee279d6 100644 --- a/cmd/ztest.c +++ b/cmd/ztest.c @@ -139,6 +139,7 @@ #include #include #include +#include static int ztest_fd_data = -1; static int ztest_fd_rand = -1; diff --git a/config/Rules.am b/config/Rules.am index deffa352ea24..ecc7ab23cd75 100644 --- a/config/Rules.am +++ b/config/Rules.am @@ -8,9 +8,9 @@ AM_CPPFLAGS = \ -include $(top_builddir)/zfs_config.h \ -I$(top_builddir)/include \ -I$(top_srcdir)/include \ - -I$(top_srcdir)/module/icp/include \ -I$(top_srcdir)/lib/libspl/include \ - -I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@ + -I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@ \ + -I$(top_srcdir)/lib/libzpool/include AM_LIBTOOLFLAGS = --silent diff --git a/include/Makefile.am b/include/Makefile.am index 7588cd0aedc9..42457519e746 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -191,6 +191,7 @@ USER_H = \ libzfs.h \ libzfs_core.h \ libzfsbootenv.h \ + libzpool.h \ libzutil.h \ thread_pool.h diff --git a/include/libzpool.h b/include/libzpool.h new file mode 100644 index 000000000000..95991e68116e --- /dev/null +++ b/include/libzpool.h @@ -0,0 +1,51 @@ +// 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 _LIBZPOOL_H +#define _LIBZPOOL_H extern __attribute__((visibility("default"))) + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern char *vn_dumpdir; + +_LIBZPOOL_H void kernel_init(int mode); +_LIBZPOOL_H void kernel_fini(void); + +struct spa; +_LIBZPOOL_H void show_pool_stats(struct spa *); +_LIBZPOOL_H int handle_tunable_option(const char *, boolean_t); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libzutil.h b/include/libzutil.h index 001ece2280f6..59599b0f63f4 100644 --- a/include/libzutil.h +++ b/include/libzutil.h @@ -165,6 +165,7 @@ _LIBZUTIL_H void zfs_nicetime(uint64_t, char *, size_t); _LIBZUTIL_H void zfs_niceraw(uint64_t, char *, size_t); #define nicenum(num, buf, size) zfs_nicenum(num, buf, size) +#define NN_NUMBUF_SZ (6) _LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *); _LIBZUTIL_H int zpool_history_unpack(char *, uint64_t, uint64_t *, nvlist_t ***, diff --git a/include/os/freebsd/Makefile.am b/include/os/freebsd/Makefile.am index d6b6923d033f..47cf6756ab7d 100644 --- a/include/os/freebsd/Makefile.am +++ b/include/os/freebsd/Makefile.am @@ -44,7 +44,6 @@ noinst_HEADERS = \ %D%/spl/sys/procfs_list.h \ %D%/spl/sys/random.h \ %D%/spl/sys/rwlock.h \ - %D%/spl/sys/sdt.h \ %D%/spl/sys/sid.h \ %D%/spl/sys/sig.h \ %D%/spl/sys/simd.h \ @@ -63,7 +62,6 @@ noinst_HEADERS = \ %D%/spl/sys/time.h \ %D%/spl/sys/timer.h \ %D%/spl/sys/trace.h \ - %D%/spl/sys/trace_zfs.h \ %D%/spl/sys/types.h \ %D%/spl/sys/types32.h \ %D%/spl/sys/uio.h \ @@ -82,10 +80,12 @@ noinst_HEADERS = \ %D%/zfs/sys/arc_os.h \ %D%/zfs/sys/freebsd_crypto.h \ %D%/zfs/sys/freebsd_event.h \ + %D%/zfs/sys/trace_zfs.h \ %D%/zfs/sys/vdev_os.h \ %D%/zfs/sys/zfs_bootenv_os.h \ %D%/zfs/sys/zfs_context_os.h \ %D%/zfs/sys/zfs_ctldir.h \ + %D%/zfs/sys/zfs_debug_os.h \ %D%/zfs/sys/zfs_dir.h \ %D%/zfs/sys/zfs_ioctl_compat.h \ %D%/zfs/sys/zfs_vfsops_os.h \ diff --git a/include/os/freebsd/spl/sys/trace_zfs.h b/include/os/freebsd/zfs/sys/trace_zfs.h similarity index 100% rename from include/os/freebsd/spl/sys/trace_zfs.h rename to include/os/freebsd/zfs/sys/trace_zfs.h diff --git a/include/os/freebsd/spl/sys/sdt.h b/include/os/freebsd/zfs/sys/zfs_debug_os.h similarity index 92% rename from include/os/freebsd/spl/sys/sdt.h rename to include/os/freebsd/zfs/sys/zfs_debug_os.h index ef1dad6c14c9..cc7540c4f83c 100644 --- a/include/os/freebsd/spl/sys/sdt.h +++ b/include/os/freebsd/zfs/sys/zfs_debug_os.h @@ -27,10 +27,11 @@ * $FreeBSD$ */ -#ifndef _OPENSOLARIS_SYS_SDT_H_ -#define _OPENSOLARIS_SYS_SDT_H_ +#ifndef _SYS_ZFS_DEBUG_OS_H +#define _SYS_ZFS_DEBUG_OS_H + +#include -#include_next #ifdef KDTRACE_HOOKS SDT_PROBE_DECLARE(sdt, , , set__error); @@ -44,4 +45,4 @@ SDT_PROBE_DECLARE(sdt, , , set__error); #define SET_ERROR(err) (err) #endif -#endif /* _OPENSOLARIS_SYS_SDT_H_ */ +#endif /* _SYS_ZFS_DEBUG_OS_H */ diff --git a/include/os/linux/Makefile.am b/include/os/linux/Makefile.am index e156ca183dbd..9188a974cc22 100644 --- a/include/os/linux/Makefile.am +++ b/include/os/linux/Makefile.am @@ -41,6 +41,7 @@ kernel_sys_HEADERS = \ %D%/zfs/sys/zfs_bootenv_os.h \ %D%/zfs/sys/zfs_context_os.h \ %D%/zfs/sys/zfs_ctldir.h \ + %D%/zfs/sys/zfs_debug_os.h \ %D%/zfs/sys/zfs_dir.h \ %D%/zfs/sys/zfs_vfsops_os.h \ %D%/zfs/sys/zfs_vnops_os.h \ @@ -97,7 +98,6 @@ kernel_spl_sys_HEADERS = \ %D%/spl/sys/time.h \ %D%/spl/sys/timer.h \ %D%/spl/sys/trace.h \ - %D%/spl/sys/trace_spl.h \ %D%/spl/sys/trace_taskq.h \ %D%/spl/sys/tsd.h \ %D%/spl/sys/types.h \ diff --git a/include/os/linux/spl/sys/sysmacros.h b/include/os/linux/spl/sys/sysmacros.h index db48222b712a..dc9e9e492ae4 100644 --- a/include/os/linux/spl/sys/sysmacros.h +++ b/include/os/linux/spl/sys/sysmacros.h @@ -34,11 +34,6 @@ #include #include - -#ifndef _KERNEL -#define _KERNEL __KERNEL__ -#endif - #define FALSE 0 #define TRUE 1 @@ -202,9 +197,6 @@ makedev(unsigned int major, unsigned int minor) #define P2SAMEHIGHBIT_TYPED(x, y, type) \ (((type)(x) ^ (type)(y)) < ((type)(x) & (type)(y))) -#define SET_ERROR(err) \ - (__set_error(__FILE__, __func__, __LINE__, err), err) - #include #define qsort(base, num, size, cmp) \ sort(base, num, size, cmp, NULL) diff --git a/include/os/linux/zfs/sys/zfs_debug_os.h b/include/os/linux/zfs/sys/zfs_debug_os.h new file mode 100644 index 000000000000..2841809528b6 --- /dev/null +++ b/include/os/linux/zfs/sys/zfs_debug_os.h @@ -0,0 +1,29 @@ +// 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 + */ + +#ifndef _SYS_ZFS_DEBUG_OS_H +#define _SYS_ZFS_DEBUG_OS_H + +#define SET_ERROR(err) \ + (__set_error(__FILE__, __func__, __LINE__, err), err) + +#endif /* _SYS_ZFS_DEBUG_OS_H */ diff --git a/include/sys/crypto/common.h b/include/sys/crypto/common.h index 4a9b4f0e1f76..2428fb2737a0 100644 --- a/include/sys/crypto/common.h +++ b/include/sys/crypto/common.h @@ -38,6 +38,8 @@ extern "C" { #endif #include +#include +#include /* Cryptographic Mechanisms */ diff --git a/include/sys/zfs_acl.h b/include/sys/zfs_acl.h index 753a128873d5..f9afee372c94 100644 --- a/include/sys/zfs_acl.h +++ b/include/sys/zfs_acl.h @@ -29,8 +29,8 @@ #ifdef _KERNEL #include #include -#include #endif +#include #include #include #include diff --git a/include/sys/zfs_bootenv.h b/include/sys/zfs_bootenv.h index 074e7e759576..4c4b2ab1ab1b 100644 --- a/include/sys/zfs_bootenv.h +++ b/include/sys/zfs_bootenv.h @@ -31,6 +31,7 @@ extern "C" { #define BE_FREEBSD_VENDOR "freebsd" #define BE_GRUB_VENDOR "grub" #define BE_LINUX_VENDOR "linux" +#define BE_POSIX_VENDOR "posix" #include diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 7112d3ef5c99..5e571d497642 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -77,14 +77,6 @@ extern "C" { #include #else /* _KERNEL || _STANDALONE */ -#define _SYS_MUTEX_H -#define _SYS_RWLOCK_H -#define _SYS_CONDVAR_H -#define _SYS_VNODE_H -#define _SYS_VFS_H -#define _SYS_SUNDDI_H -#define _SYS_CALLB_H - #include #include #include @@ -93,10 +85,8 @@ extern "C" { #include #include #include -#include #include #include -#include #include #include #include @@ -119,666 +109,26 @@ extern "C" { #include #include #include -#include -#include - -#include - -/* - * Stack - */ - -#define noinline __attribute__((noinline)) -#define likely(x) __builtin_expect((x), 1) -#define unlikely(x) __builtin_expect((x), 0) - -/* - * Debugging - */ - -/* - * 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 - -/* - * 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) - -/* - * 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 struct proc { - uintptr_t this_is_never_used_dont_dereference_it; -} proc_t; - -extern struct proc p0; -#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) - -/* - * 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) -/* - * 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) - -/* - * Credentials - */ -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); - -/* - * 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) - -/* - * 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 */ -#ifdef __FreeBSD__ -typedef off_t loff_t; -#endif - -/* - * kstat creation, installation and deletion - */ -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_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)); - -/* - * 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 - -/* - * 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); -#define kmem_cache_set_move(_c, _cb) /* nothing */ -#define POINTER_INVALIDATE(_pp) /* nothing */ -#define POINTER_IS_VALID(_p) 0 - -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; - -/* - * 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; -extern taskq_t *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); - -#define XVA_MAPSIZE 3 -#define XVA_MAGIC 0x78766174 - -extern char *vn_dumpdir; -#define AV_SCANSTAMP_SZ 32 /* length of anti-virus scanstamp */ - -typedef struct xoptattr { - inode_timespec_t xoa_createtime; /* Create time of file */ - uint8_t xoa_archive; - uint8_t xoa_system; - uint8_t xoa_readonly; - uint8_t xoa_hidden; - uint8_t xoa_nounlink; - uint8_t xoa_immutable; - uint8_t xoa_appendonly; - uint8_t xoa_nodump; - uint8_t xoa_settable; - uint8_t xoa_opaque; - uint8_t xoa_av_quarantined; - uint8_t xoa_av_modified; - uint8_t xoa_av_scanstamp[AV_SCANSTAMP_SZ]; - uint8_t xoa_reparse; - uint8_t xoa_offline; - uint8_t xoa_sparse; -} xoptattr_t; - -typedef struct vattr { - uint_t va_mask; /* bit-mask of attributes */ - u_offset_t va_size; /* file size in bytes */ -} vattr_t; - - -typedef struct xvattr { - vattr_t xva_vattr; /* Embedded vattr structure */ - uint32_t xva_magic; /* Magic Number */ - uint32_t xva_mapsize; /* Size of attr bitmap (32-bit words) */ - uint32_t *xva_rtnattrmapp; /* Ptr to xva_rtnattrmap[] */ - uint32_t xva_reqattrmap[XVA_MAPSIZE]; /* Requested attrs */ - uint32_t xva_rtnattrmap[XVA_MAPSIZE]; /* Returned attrs */ - xoptattr_t xva_xoptattrs; /* Optional attributes */ -} xvattr_t; - -typedef struct vsecattr { - uint_t vsa_mask; /* See below */ - int vsa_aclcnt; /* ACL entry count */ - void *vsa_aclentp; /* pointer to ACL entries */ - int vsa_dfaclcnt; /* default ACL entry count */ - void *vsa_dfaclentp; /* pointer to default ACL entries */ - size_t vsa_aclentsz; /* ACE size in bytes of vsa_aclentp */ -} vsecattr_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 CRCREAT 0 - -#define F_FREESP 11 -#define FIGNORECASE 0x80000 /* request case-insensitive lookups */ - -/* - * Random stuff - */ -#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 max_ncpus 64 -#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN)) - -/* - * 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 - -#define kcred NULL -#define CRED() NULL - -#define crhold(cr) ((void)cr) -#define crfree(cr) ((void)cr) - -#define ptob(x) ((x) * PAGESIZE) - -#define NN_DIVISOR_1000 (1U << 0) -#define NN_NUMBUF_SZ (6) - -extern uint64_t physmem; -extern const char *random_path; -extern const char *urandom_path; - -extern int highbit64(uint64_t i); -extern int lowbit64(uint64_t i); -extern int random_get_bytes(uint8_t *ptr, size_t len); -extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len); - -static __inline__ uint32_t -random_in_range(uint32_t range) -{ - uint32_t r; - - ASSERT(range != 0); - - if (range == 1) - return (0); - - (void) random_get_pseudo_bytes((uint8_t *)&r, sizeof (r)); - - return (r % range); -} - -extern void kernel_init(int mode); -extern void kernel_fini(void); -extern void random_init(void); -extern void random_fini(void); - -struct spa; -extern void show_pool_stats(struct spa *); -extern int handle_tunable_option(const char *, boolean_t); - -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); \ -} - -#define zone_dataset_visible(x, y) (1) -#define INGLOBALZONE(z) (1) -extern uint32_t zone_get_hostid(void *zonep); - -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 - -/* - * Hostname information - */ -extern int ddi_strtoull(const char *str, char **nptr, int base, - u_longlong_t *result); - -typedef struct utsname utsname_t; -extern utsname_t *utsname(void); - -/* ZFS Boot Related stuff. */ - -struct _buf { - intptr_t _fd; -}; - -struct bootstat { - uint64_t st_size; -}; - -typedef struct ace_object { - uid_t a_who; - uint32_t a_access_mask; - uint16_t a_flags; - uint16_t a_type; - uint8_t a_obj_type[16]; - uint8_t a_inherit_obj_type[16]; -} ace_object_t; - - -#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05 -#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06 -#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07 -#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08 - -extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr); -extern int zfs_secpolicy_rename_perms(const char *from, const char *to, - cred_t *cr); -extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr); -extern int secpolicy_zfs(const cred_t *cr); -extern zoneid_t getzoneid(void); - -/* 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 *); - -#define DDI_SLEEP KM_SLEEP -#define ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g) \ - sysevent_post_event(_c, _d, _b, "libzpool", _e, _f) - -#define zfs_sleep_until(wakeup) \ - do { \ - hrtime_t delta = wakeup - gethrtime(); \ - struct timespec ts; \ - ts.tv_sec = delta / NANOSEC; \ - ts.tv_nsec = delta % NANOSEC; \ - (void) nanosleep(&ts, NULL); \ - } while (0) - -typedef int fstrans_cookie_t; - -extern fstrans_cookie_t spl_fstrans_mark(void); -extern void spl_fstrans_unmark(fstrans_cookie_t); -extern int kmem_cache_reap_active(void); +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -/* - * Kernel modules - */ -#define __init -#define __exit +#include #endif /* _KERNEL || _STANDALONE */ diff --git a/include/sys/zfs_debug.h b/include/sys/zfs_debug.h index 4d4cd4c39e97..0f021d15157b 100644 --- a/include/sys/zfs_debug.h +++ b/include/sys/zfs_debug.h @@ -40,6 +40,7 @@ extern "C" { #endif #include +#include extern int zfs_flags; extern int zfs_recover; diff --git a/lib/libicp/Makefile.am b/lib/libicp/Makefile.am index 23adba10bc44..a8937e60b770 100644 --- a/lib/libicp/Makefile.am +++ b/lib/libicp/Makefile.am @@ -1,6 +1,9 @@ libicp_la_CCASFLAGS = $(AM_CCASFLAGS) libicp_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) $(LIBRARY_CFLAGS) +libicp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS) +libicp_la_CPPFLAGS += -I$(top_srcdir)/module/icp/include + noinst_LTLIBRARIES += libicp.la nodist_libicp_la_SOURCES = \ @@ -35,8 +38,7 @@ nodist_libicp_la_SOURCES = \ module/icp/core/kcf_prov_lib.c \ module/icp/core/kcf_callprov.c \ module/icp/core/kcf_mech_tabs.c \ - module/icp/core/kcf_prov_tabs.c \ - module/zfs/zfs_impl.c + module/icp/core/kcf_prov_tabs.c if TARGET_CPU_AARCH64 nodist_libicp_la_SOURCES += \ diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index 0fd907d3011e..27f004634487 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -16,12 +16,24 @@ libspl_assert_la_SOURCES = \ 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 \ diff --git a/lib/libspl/condvar.c b/lib/libspl/condvar.c new file mode 100644 index 000000000000..3d70fe152089 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +/* + * ========================================================================= + * 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/lib/libspl/cred.c b/lib/libspl/cred.c new file mode 100644 index 000000000000..130323ea91a7 --- /dev/null +++ b/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 + +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/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 746cb12bf637..e68742409839 100644 --- a/lib/libspl/include/Makefile.am +++ b/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 \ @@ -24,14 +25,13 @@ libspl_rpc_HEADERS = \ libspl_sysdir = $(libspldir)/sys libspl_sys_HEADERS = \ - %D%/sys/abd_os.h \ - %D%/sys/abd_impl_os.h \ %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 \ @@ -43,22 +43,33 @@ 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/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 \ @@ -77,9 +88,7 @@ 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/vfs.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 @@ -94,9 +103,7 @@ 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 diff --git a/lib/libspl/include/libspl.h b/lib/libspl/include/libspl.h new file mode 100644 index 000000000000..68756bb9597b --- /dev/null +++ b/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 + */ + +#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/lib/libspl/include/os/freebsd/sys/param.h b/lib/libspl/include/os/freebsd/sys/param.h index 55fa1de0e8ff..a693149115db 100644 --- a/lib/libspl/include/os/freebsd/sys/param.h +++ b/lib/libspl/include/os/freebsd/sys/param.h @@ -58,6 +58,8 @@ 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 diff --git a/lib/libspl/include/os/freebsd/sys/zfs_context_os.h b/lib/libspl/include/os/freebsd/sys/zfs_context_os.h deleted file mode 100644 index 1dd036d02ac6..000000000000 --- a/lib/libspl/include/os/freebsd/sys/zfs_context_os.h +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * 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/lib/libspl/include/os/linux/sys/param.h b/lib/libspl/include/os/linux/sys/param.h index 814f8feaf37f..169d5875fcf0 100644 --- a/lib/libspl/include/os/linux/sys/param.h +++ b/lib/libspl/include/os/linux/sys/param.h @@ -65,4 +65,6 @@ extern size_t spl_pagesize(void); #define PAGESIZE (spl_pagesize()) +#define ptob(x) ((x) * PAGESIZE) + #endif diff --git a/lib/libspl/include/sys/acl.h b/lib/libspl/include/sys/acl.h index 602043bbb196..3e79040c5307 100644 --- a/lib/libspl/include/sys/acl.h +++ b/lib/libspl/include/sys/acl.h @@ -141,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,... */ @@ -152,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/lib/libspl/include/sys/callb.h b/lib/libspl/include/sys/callb.h index 46ed166e52f8..6e8e22338b8b 100644 --- a/lib/libspl/include/sys/callb.h +++ b/lib/libspl/include/sys/callb.h @@ -21,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 + +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/lib/libspl/include/sys/cmn_err.h b/lib/libspl/include/sys/cmn_err.h index 32930adaeffa..5e7136f7fdc2 100644 --- a/lib/libspl/include/sys/cmn_err.h +++ b/lib/libspl/include/sys/cmn_err.h @@ -62,4 +62,31 @@ do { \ } \ } 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/lib/libspl/include/sys/condvar.h b/lib/libspl/include/sys/condvar.h new file mode 100644 index 000000000000..9a05c41d1510 --- /dev/null +++ b/lib/libspl/include/sys/condvar.h @@ -0,0 +1,65 @@ +// 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 + +#include +#include +#include + +/* + * 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 /* _SYS_CONDVAR_H */ diff --git a/lib/libspl/include/sys/cred.h b/lib/libspl/include/sys/cred.h index 4f6183762a0a..deceecee0f19 100644 --- a/lib/libspl/include/sys/cred.h +++ b/lib/libspl/include/sys/cred.h @@ -28,6 +28,24 @@ #ifndef _LIBSPL_SYS_CRED_H #define _LIBSPL_SYS_CRED_H +#include + +/* + * 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/lib/libspl/include/sys/debug.h b/lib/libspl/include/sys/debug.h index 02f33a68b75b..2bd077686f1c 100644 --- a/lib/libspl/include/sys/debug.h +++ b/lib/libspl/include/sys/debug.h @@ -24,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 @@ -42,4 +48,22 @@ #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/lib/libspl/include/sys/kmem.h b/lib/libspl/include/sys/kmem.h index 279461f8d4c1..0321f6a0d5ba 100644 --- a/lib/libspl/include/sys/kmem.h +++ b/lib/libspl/include/sys/kmem.h @@ -20,27 +20,67 @@ * 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 +#include +#include -#ifdef __cplusplus -extern "C" { -#endif +/* + * 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) + +extern int kmem_scnprintf(char *restrict str, size_t size, + const char *restrict fmt, ...); + +typedef umem_cache_t kmem_cache_t; -#define KM_SLEEP 0x00000000 /* same as KM_SLEEP */ -#define KM_NOSLEEP 0x00000001 /* same as KM_NOSLEEP */ +typedef enum kmem_cbrc { + KMEM_CBRC_YES, + KMEM_CBRC_NO, + KMEM_CBRC_LATER, + KMEM_CBRC_DONT_NEED, + KMEM_CBRC_DONT_KNOW +} kmem_cbrc_t; -#define kmem_alloc(size, flags) ((void) sizeof (flags), malloc(size)) -#define kmem_free(ptr, size) ((void) sizeof (size), free(ptr)) +typedef int fstrans_cookie_t; -#ifdef __cplusplus -} -#endif +extern fstrans_cookie_t spl_fstrans_mark(void); +extern void spl_fstrans_unmark(fstrans_cookie_t); #endif /* _SYS_KMEM_H */ diff --git a/lib/libspl/include/sys/kstat.h b/lib/libspl/include/sys/kstat.h index 7777888c31eb..361f24df3f58 100644 --- a/lib/libspl/include/sys/kstat.h +++ b/lib/libspl/include/sys/kstat.h @@ -27,758 +27,65 @@ #ifndef _SYS_KSTAT_H #define _SYS_KSTAT_H - - -/* - * Definition of general kernel statistics structures and /dev/kstat ioctls - */ - #include #include -#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 - -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/lib/libspl/include/sys/misc.h b/lib/libspl/include/sys/misc.h new file mode 100644 index 000000000000..8f2f5f9332e7 --- /dev/null +++ b/lib/libspl/include/sys/misc.h @@ -0,0 +1,43 @@ +// 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 + +extern const char *random_path; +extern const char *urandom_path; + +/* + * Hostname information + */ +typedef struct utsname utsname_t; +extern utsname_t *utsname(void); + +#endif diff --git a/lib/libspl/include/sys/mutex.h b/lib/libspl/include/sys/mutex.h new file mode 100644 index 000000000000..1da0e632d60f --- /dev/null +++ b/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 + +/* + * 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/lib/libspl/include/sys/procfs_list.h b/lib/libspl/include/sys/procfs_list.h new file mode 100644 index 000000000000..93b80a4bfdb6 --- /dev/null +++ b/lib/libspl/include/sys/procfs_list.h @@ -0,0 +1,69 @@ +// 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 +#include +#include + +/* + * 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; + +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 /* _SYS_PROCFS_LIST_H */ diff --git a/lib/libspl/include/sys/random.h b/lib/libspl/include/sys/random.h new file mode 100644 index 000000000000..27f2d4e3a684 --- /dev/null +++ b/lib/libspl/include/sys/random.h @@ -0,0 +1,50 @@ +// 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); + +static __inline__ uint32_t +random_in_range(uint32_t range) +{ + uint32_t r; + + ASSERT(range != 0); + + 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/lib/libspl/include/sys/rwlock.h b/lib/libspl/include/sys/rwlock.h new file mode 100644 index 000000000000..9f82f270d939 --- /dev/null +++ b/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 + +/* + * 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/lib/libspl/include/sys/sid.h b/lib/libspl/include/sys/sid.h new file mode 100644 index 000000000000..74789c5d9a62 --- /dev/null +++ b/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 + +/* 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/lib/libspl/include/sys/string.h b/lib/libspl/include/sys/string.h index 3b2f5900276f..55ccbd09041a 100644 --- a/lib/libspl/include/sys/string.h +++ b/lib/libspl/include/sys/string.h @@ -1 +1,4 @@ +#ifndef _LIBSPL_SYS_STRING_H +#define _LIBSPL_SYS_STRING_H #include +#endif diff --git a/lib/libspl/include/sys/sunddi.h b/lib/libspl/include/sys/sunddi.h index 8489c7139bad..48e0b15a4542 100644 --- a/lib/libspl/include/sys/sunddi.h +++ b/lib/libspl/include/sys/sunddi.h @@ -21,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/lib/libspl/include/os/linux/sys/sysmacros.h b/lib/libspl/include/sys/sysmacros.h similarity index 72% rename from lib/libspl/include/os/linux/sys/sysmacros.h rename to lib/libspl/include/sys/sysmacros.h index 66e0da6b5afe..e33915c8d96b 100644 --- a/lib/libspl/include/os/linux/sys/sysmacros.h +++ b/lib/libspl/include/sys/sysmacros.h @@ -3,9 +3,8 @@ * 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 https://opensource.org/licenses/CDDL-1.0. @@ -21,14 +20,26 @@ * 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 + +#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. + */ #include_next +#endif /* common macros */ #ifndef MIN @@ -94,10 +105,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 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/lib/libspl/include/sys/systm.h b/lib/libspl/include/sys/systm.h new file mode 100644 index 000000000000..94fcfdd2a303 --- /dev/null +++ b/lib/libspl/include/sys/systm.h @@ -0,0 +1,34 @@ +// 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 + +extern uint64_t physmem; + +#endif diff --git a/lib/libspl/include/sys/taskq.h b/lib/libspl/include/sys/taskq.h new file mode 100644 index 000000000000..63238734b4fd --- /dev/null +++ b/lib/libspl/include/sys/taskq.h @@ -0,0 +1,116 @@ +// 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 +#include +#include +#include +#include + +/* + * 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; +extern taskq_t *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/lib/libspl/include/sys/thread.h b/lib/libspl/include/sys/thread.h new file mode 100644 index 000000000000..a5108a03d45f --- /dev/null +++ b/lib/libspl/include/sys/thread.h @@ -0,0 +1,81 @@ +// 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 + +/* + * 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 struct proc { + uintptr_t this_is_never_used_dont_dereference_it; +} proc_t; + +extern struct proc p0; +#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/lib/libspl/include/sys/timer.h b/lib/libspl/include/sys/timer.h new file mode 100644 index 000000000000..850d11f063c3 --- /dev/null +++ b/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 + +#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/lib/libspl/include/sys/trace.h b/lib/libspl/include/sys/trace.h new file mode 100644 index 000000000000..17b812faed20 --- /dev/null +++ b/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/lib/libspl/include/sys/trace_spl.h b/lib/libspl/include/sys/trace_spl.h deleted file mode 100644 index b80d288f7332..000000000000 --- a/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/lib/libspl/include/sys/trace_zfs.h b/lib/libspl/include/sys/trace_zfs.h deleted file mode 100644 index 87ed5ad3c3be..000000000000 --- a/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/lib/libspl/include/sys/tsd.h b/lib/libspl/include/sys/tsd.h new file mode 100644 index 000000000000..fa91519b3de5 --- /dev/null +++ b/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 + +/* + * 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/lib/libspl/include/sys/types.h b/lib/libspl/include/sys/types.h index f4bb85c7942e..9af20d781674 100644 --- a/lib/libspl/include/sys/types.h +++ b/lib/libspl/include/sys/types.h @@ -50,4 +50,8 @@ typedef int projid_t; #include /* for NBBY */ +#ifdef __FreeBSD__ +typedef off_t loff_t; +#endif + #endif diff --git a/lib/libspl/include/sys/vnode.h b/lib/libspl/include/sys/vnode.h index 49afe12c52b1..ed9901eede22 100644 --- a/lib/libspl/include/sys/vnode.h +++ b/lib/libspl/include/sys/vnode.h @@ -25,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/lib/libspl/include/sys/zone.h b/lib/libspl/include/sys/zone.h index f4037b4875a9..179cc004fdb8 100644 --- a/lib/libspl/include/sys/zone.h +++ b/lib/libspl/include/sys/zone.h @@ -21,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/lib/libspl/include/umem.h b/lib/libspl/include/umem.h index 3e44610e4e21..1b79fee56d23 100644 --- a/lib/libspl/include/umem.h +++ b/lib/libspl/include/umem.h @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/lib/libspl/kmem.c b/lib/libspl/kmem.c new file mode 100644 index 000000000000..c64e94597cf4 --- /dev/null +++ b/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 + +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/lib/libspl/kstat.c b/lib/libspl/kstat.c new file mode 100644 index 000000000000..af4b870edadf --- /dev/null +++ b/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 + +/* + * ========================================================================= + * 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/lib/libspl/libspl.c b/lib/libspl/libspl.c new file mode 100644 index 000000000000..63e948bc2829 --- /dev/null +++ b/lib/libspl/libspl.c @@ -0,0 +1,60 @@ +// 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 + */ + +#include +#include +#include +#include +#include +#include "libspl_impl.h" + +uint64_t physmem; +struct utsname hw_utsname; + +utsname_t * +utsname(void) +{ + return (&hw_utsname); +} + +void +libspl_init(void) +{ + physmem = sysconf(_SC_PHYS_PAGES); + + VERIFY0(uname(&hw_utsname)); + + random_init(); +} + +void +libspl_fini(void) +{ + random_fini(); +} diff --git a/lib/libspl/libspl_impl.h b/lib/libspl/libspl_impl.h index 39392da09ef5..446801f2564b 100644 --- a/lib/libspl/libspl_impl.h +++ b/lib/libspl/libspl_impl.h @@ -21,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/lib/libspl/mutex.c b/lib/libspl/mutex.c new file mode 100644 index 000000000000..36e5bec396ed --- /dev/null +++ b/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 +#include +#include +#include +#include + +/* + * ========================================================================= + * 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/lib/libspl/procfs_list.c b/lib/libspl/procfs_list.c new file mode 100644 index 000000000000..0ce327db6343 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +/* + * ========================================================================= + * 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/lib/libspl/random.c b/lib/libspl/random.c new file mode 100644 index 000000000000..0392737908fe --- /dev/null +++ b/lib/libspl/random.c @@ -0,0 +1,84 @@ +// 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 +#include +#include +#include +#include "libspl_impl.h" + +const char *random_path = "/dev/random"; +const char *urandom_path = "/dev/urandom"; +static int random_fd = -1, urandom_fd = -1; + +void +random_init(void) +{ + 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; +} + +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) +{ + 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/lib/libspl/rwlock.c b/lib/libspl/rwlock.c new file mode 100644 index 000000000000..3712829ef594 --- /dev/null +++ b/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 +#include +#include +#include +#include + +/* + * ========================================================================= + * 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/lib/libspl/sid.c b/lib/libspl/sid.c new file mode 100644 index 000000000000..b7d5b5f2e778 --- /dev/null +++ b/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 +#include + +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/lib/libzpool/taskq.c b/lib/libspl/taskq.c similarity index 98% rename from lib/libzpool/taskq.c rename to lib/libspl/taskq.c index 0457de21fa18..075d188930c1 100644 --- a/lib/libzpool/taskq.c +++ b/lib/libspl/taskq.c @@ -29,7 +29,12 @@ * Copyright (c) 2014 by Delphix. All rights reserved. */ -#include +#include +#include +#include +#include +#include +#include int taskq_now; taskq_t *system_taskq; diff --git a/lib/libspl/thread.c b/lib/libspl/thread.c new file mode 100644 index 000000000000..17c36c754621 --- /dev/null +++ b/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 +#include +#include +#include + +/* this only exists to have its address taken */ +struct proc p0; + +/* + * ========================================================================= + * 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/lib/libuutil/libuutil.abi b/lib/libuutil/libuutil.abi index 2a740afa07ca..f690b20fc898 100644 --- a/lib/libuutil/libuutil.abi +++ b/lib/libuutil/libuutil.abi @@ -144,6 +144,19 @@ + + + + + + + + + + + + + @@ -151,8 +164,20 @@ + + + + + + + + + + + + @@ -178,10 +203,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -248,7 +313,18 @@ + + + + + + + + + + + @@ -616,7 +692,6 @@ - @@ -635,8 +710,6 @@ - - @@ -800,6 +873,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -809,6 +1106,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -921,7 +1387,6 @@ - @@ -971,6 +1436,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -981,246 +1479,757 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + - - - + + + - + + + - + + - - - - - - + + + + - - + + + - - - - - + + - - - - + - - + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - - - - + - + + - - - - - - - - - - + - - - - - - - - - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - + + - - - + + + - - - - + + + - - - + + + - - - - + + + - - - - + - + - - + + + - - - + - - - - - - - - - - - + + + + - @@ -1351,8 +2360,6 @@ - - @@ -2334,10 +3341,6 @@ - - - - diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi index f988d27a286a..021839b28761 100644 --- a/lib/libzfs/libzfs.abi +++ b/lib/libzfs/libzfs.abi @@ -160,6 +160,19 @@ + + + + + + + + + + + + + @@ -195,9 +208,21 @@ + + + + + + + + + + + + @@ -243,10 +268,30 @@ + + + + + + + + + + + + + + + + + + + + @@ -254,10 +299,29 @@ + + + + + + + + + + + + + + + + + + + @@ -270,6 +334,7 @@ + @@ -477,6 +542,7 @@ + @@ -638,9 +704,17 @@ + + + + + + + + @@ -1319,6 +1393,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1328,6 +1502,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1458,6 +1785,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1473,6 +1833,484 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1915,10 +2753,6 @@ - - - - @@ -1952,6 +2786,7 @@ + @@ -2472,6 +3307,9 @@ + + + @@ -2639,8 +3477,13 @@ - - + + + + + + + @@ -2658,6 +3501,16 @@ + + + + + + + + + + @@ -2728,7 +3581,6 @@ - @@ -3100,14 +3952,6 @@ - - - - - - - - @@ -3286,7 +4130,6 @@ - @@ -3588,6 +4431,7 @@ + @@ -6494,6 +7338,10 @@ + + + + @@ -8348,10 +9196,6 @@ - - - - diff --git a/lib/libzfs/libzfs_crypto.c b/lib/libzfs/libzfs_crypto.c index f7cc1e84f804..f461ad41405b 100644 --- a/lib/libzfs/libzfs_crypto.c +++ b/lib/libzfs/libzfs_crypto.c @@ -19,7 +19,6 @@ * Copyright 2020 Joyent, Inc. */ -#include #include #include #include diff --git a/lib/libzfs_core/libzfs_core.abi b/lib/libzfs_core/libzfs_core.abi index 263cad045f7a..1ed3342d2b70 100644 --- a/lib/libzfs_core/libzfs_core.abi +++ b/lib/libzfs_core/libzfs_core.abi @@ -127,6 +127,19 @@ + + + + + + + + + + + + + @@ -134,8 +147,20 @@ + + + + + + + + + + + + @@ -218,32 +243,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - @@ -617,7 +678,6 @@ - @@ -798,6 +858,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -807,6 +1084,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -918,7 +1376,6 @@ - @@ -967,6 +1424,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -977,7 +1487,6 @@ - @@ -1149,14 +1658,271 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1165,6 +1931,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1297,8 +2318,6 @@ - - @@ -2342,10 +3361,10 @@ - + - + diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index aeacc595b363..592a1a781e9c 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -2,7 +2,6 @@ libzpool_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) $(LIBRARY_CFLAGS) libzpool_la_CFLAGS += $(ZLIB_CFLAGS) libzpool_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS) -libzpool_la_CPPFLAGS += -I$(srcdir)/include/os/@ac_system_l@/zfs libzpool_la_CPPFLAGS += -DLIB_ZPOOL_BUILD lib_LTLIBRARIES += libzpool.la @@ -12,7 +11,6 @@ dist_libzpool_la_SOURCES = \ %D%/abd_os.c \ %D%/arc_os.c \ %D%/kernel.c \ - %D%/taskq.c \ %D%/util.c \ %D%/vdev_label_os.c \ %D%/zfs_racct.c \ @@ -180,6 +178,7 @@ nodist_libzpool_la_SOURCES = \ module/zfs/zfs_crrd.c \ module/zfs/zfs_fm.c \ module/zfs/zfs_fuid.c \ + module/zfs/zfs_impl.c \ module/zfs/zfs_ratelimit.c \ module/zfs/zfs_rlock.c \ module/zfs/zfs_sa.c \ diff --git a/lib/libzpool/include/Makefile.am b/lib/libzpool/include/Makefile.am new file mode 100644 index 000000000000..7b9f0c2b99e6 --- /dev/null +++ b/lib/libzpool/include/Makefile.am @@ -0,0 +1,7 @@ +libzpool_sys_HEADERS = \ + %D%/sys/abd_os.h \ + %D%/sys/abd_impl_os.h \ + %D%/sys/trace_zfs.h \ + %D%/sys/zfs_bootenv_os.h \ + %D%/sys/zfs_context_os.h \ + %D%/sys/zfs_debug_os.h diff --git a/lib/libspl/include/sys/abd_impl_os.h b/lib/libzpool/include/sys/abd_impl_os.h similarity index 100% rename from lib/libspl/include/sys/abd_impl_os.h rename to lib/libzpool/include/sys/abd_impl_os.h diff --git a/lib/libspl/include/sys/abd_os.h b/lib/libzpool/include/sys/abd_os.h similarity index 100% rename from lib/libspl/include/sys/abd_os.h rename to lib/libzpool/include/sys/abd_os.h diff --git a/lib/libspl/include/os/freebsd/sys/sysmacros.h b/lib/libzpool/include/sys/trace_zfs.h similarity index 100% rename from lib/libspl/include/os/freebsd/sys/sysmacros.h rename to lib/libzpool/include/sys/trace_zfs.h diff --git a/lib/libzpool/include/sys/zfs_bootenv_os.h b/lib/libzpool/include/sys/zfs_bootenv_os.h new file mode 100644 index 000000000000..44afbb6f5b6b --- /dev/null +++ b/lib/libzpool/include/sys/zfs_bootenv_os.h @@ -0,0 +1,39 @@ +// 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 + */ + +#ifndef _ZFS_BOOTENV_OS_H +#define _ZFS_BOOTENV_OS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOOTENV_OS BE_POSIX_VENDOR + +#ifdef __cplusplus +} +#endif + +#endif /* _ZFS_BOOTENV_OS_H */ diff --git a/lib/libzpool/include/sys/zfs_context_os.h b/lib/libzpool/include/sys/zfs_context_os.h new file mode 100644 index 000000000000..4dcf386e3351 --- /dev/null +++ b/lib/libzpool/include/sys/zfs_context_os.h @@ -0,0 +1,34 @@ +// 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 ZFS_CONTEXT_OS_H_ +#define ZFS_CONTEXT_OS_H_ + +#define HAVE_LARGE_STACKS 1 + +#endif diff --git a/lib/libspl/include/os/linux/sys/zfs_context_os.h b/lib/libzpool/include/sys/zfs_debug_os.h similarity index 73% rename from lib/libspl/include/os/linux/sys/zfs_context_os.h rename to lib/libzpool/include/sys/zfs_debug_os.h index bbfb4d17e06d..b59165a6c903 100644 --- a/lib/libspl/include/os/linux/sys/zfs_context_os.h +++ b/lib/libzpool/include/sys/zfs_debug_os.h @@ -3,9 +3,8 @@ * 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 https://opensource.org/licenses/CDDL-1.0. @@ -21,9 +20,10 @@ * CDDL HEADER END */ -#ifndef ZFS_CONTEXT_OS_H -#define ZFS_CONTEXT_OS_H +#ifndef _SYS_ZFS_DEBUG_OS_H +#define _SYS_ZFS_DEBUG_OS_H -#define HAVE_LARGE_STACKS 1 +#define SET_ERROR(err) \ + (__set_error(__FILE__, __func__, __LINE__, err), err) #endif diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index 70eba5099119..18d93266d6b2 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -40,10 +40,14 @@ #include #include #include +#include #include #include #include -#include +#include + +#include +#include #include #include #include @@ -56,258 +60,11 @@ * Emulation of kernel services in userland. */ -uint64_t physmem; uint32_t hostid; -struct utsname hw_utsname; /* If set, all blocks read will be copied to the specified directory. */ char *vn_dumpdir = NULL; -/* this only exists to have its address taken */ -struct proc p0; - -/* - * ========================================================================= - * 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); -} - -/* - * ========================================================================= - * 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; -} - -/* - * ========================================================================= - * 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)); -} - -/* - * ========================================================================= - * 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); -} - uint32_t zone_get_hostid(void *zonep) { @@ -318,191 +75,6 @@ zone_get_hostid(void *zonep) return (hostid); } -int -rw_tryupgrade(krwlock_t *rwlp) -{ - (void) rwlp; - return (0); -} - -/* - * ========================================================================= - * 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)); -} - -/* - * ========================================================================= - * 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); -} - /* * ========================================================================= * vnode operations @@ -771,57 +343,6 @@ lowbit64(uint64_t i) return (__builtin_ffsll(i)); } -const char *random_path = "/dev/random"; -const char *urandom_path = "/dev/urandom"; -static int random_fd = -1, urandom_fd = -1; - -void -random_init(void) -{ - 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; -} - -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) -{ - 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)); -} - int ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result) { @@ -832,12 +353,6 @@ ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result) return (0); } -utsname_t * -utsname(void) -{ - return (&hw_utsname); -} - /* * ========================================================================= * kernel emulation setup & teardown @@ -931,19 +446,15 @@ kernel_init(int mode) { extern uint_t rrw_tsd_key; - umem_nofail_callback(umem_out_of_memory); + libspl_init(); - physmem = sysconf(_SC_PHYS_PAGES); + umem_nofail_callback(umem_out_of_memory); dprintf("physmem = %llu pages (%.2f GB)\n", (u_longlong_t)physmem, (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); hostid = (mode & SPA_MODE_WRITE) ? get_system_hostid() : 0; - random_init(); - - VERIFY0(uname(&hw_utsname)); - system_taskq_init(); icp_init(); @@ -968,142 +479,7 @@ kernel_fini(void) icp_fini(); system_taskq_fini(); - random_fini(); -} - -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); -} - -int -zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr) -{ - (void) name, (void) cr; - return (0); -} - -int -zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr) -{ - (void) from, (void) to, (void) cr; - return (0); -} - -int -zfs_secpolicy_destroy_perms(const char *name, cred_t *cr) -{ - (void) name, (void) cr; - return (0); -} - -int -secpolicy_zfs(const cred_t *cr) -{ - (void) cr; - return (0); -} - -ksiddomain_t * -ksid_lookupdomain(const char *dom) -{ - ksiddomain_t *kd; - - kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL); - kd->kd_name = spa_strdup(dom); - return (kd); -} - -void -ksiddomain_rele(ksiddomain_t *ksid) -{ - spa_strfree(ksid->kd_name); - umem_free(ksid, sizeof (ksiddomain_t)); -} - -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); + libspl_fini(); } zfs_file_t * @@ -1128,24 +504,6 @@ zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data, return (0); } -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); -} - void zvol_create_minors(const char *name) { diff --git a/lib/libzpool/util.c b/lib/libzpool/util.c index 66d6f43967d5..a0b4480c4bcf 100644 --- a/lib/libzpool/util.c +++ b/lib/libzpool/util.c @@ -38,6 +38,7 @@ #include #include #include +#include /* * Routines needed by more than one client of libzpool. diff --git a/module/icp/spi/kcf_spi.c b/module/icp/spi/kcf_spi.c index 806c0b028017..35fe55b2595d 100644 --- a/module/icp/spi/kcf_spi.c +++ b/module/icp/spi/kcf_spi.c @@ -31,7 +31,6 @@ */ -#include #include #include #include diff --git a/module/os/freebsd/spl/spl_uio.c b/module/os/freebsd/spl/spl_uio.c index 54d4029c5e6f..b92be3710f3c 100644 --- a/module/os/freebsd/spl/spl_uio.c +++ b/module/os/freebsd/spl/spl_uio.c @@ -238,7 +238,7 @@ zfs_uio_iov_step(struct iovec v, zfs_uio_t *uio, int *numpages) zfs_uio_rw(uio), &uio->uio_dio.pages[uio->uio_dio.npages]); if (res != n) - return (SET_ERROR(EFAULT)); + return (EFAULT); ASSERT3U(len, ==, res * PAGE_SIZE); *numpages = res; diff --git a/module/os/linux/spl/spl-taskq.c b/module/os/linux/spl/spl-taskq.c index 092f090d934b..00ff789265c6 100644 --- a/module/os/linux/spl/spl-taskq.c +++ b/module/os/linux/spl/spl-taskq.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -325,7 +324,6 @@ task_expire_impl(taskq_ent_t *t) } t->tqent_birth = jiffies; - DTRACE_PROBE1(taskq_ent__birth, taskq_ent_t *, t); /* * The priority list must be maintained in strict task id order @@ -713,9 +711,7 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags) t->tqent_taskq = tq; t->tqent_timer.function = NULL; t->tqent_timer.expires = 0; - t->tqent_birth = jiffies; - DTRACE_PROBE1(taskq_ent__birth, taskq_ent_t *, t); ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC)); @@ -840,9 +836,7 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags, t->tqent_func = func; t->tqent_arg = arg; t->tqent_taskq = tq; - t->tqent_birth = jiffies; - DTRACE_PROBE1(taskq_ent__birth, taskq_ent_t *, t); spin_unlock(&t->tqent_lock); @@ -1054,11 +1048,6 @@ taskq_thread(void *args) * A TQENT_FLAG_PREALLOC task may be reused or freed * during the task function call. Store tqent_id and * tqent_flags here. - * - * Also use an on stack taskq_ent_t for tqt_task - * assignment in this case; we want to make sure - * to duplicate all fields, so the values are - * correct when it's accessed via DTRACE_PROBE*. */ tqt->tqt_id = t->tqent_id; tqt->tqt_flags = t->tqent_flags; @@ -1074,13 +1063,10 @@ taskq_thread(void *args) spin_unlock_irqrestore(&tq->tq_lock, flags); TQSTAT_INC(tq, threads_active); - DTRACE_PROBE1(taskq_ent__start, taskq_ent_t *, t); /* Perform the requested task */ t->tqent_func(t->tqent_arg); - DTRACE_PROBE1(taskq_ent__finish, taskq_ent_t *, t); - TQSTAT_DEC(tq, threads_active); if ((t->tqent_flags & TQENT_LIST_MASK) == TQENT_LIST_PENDING) diff --git a/module/zfs/zfs_fuid.c b/module/zfs/zfs_fuid.c index 7f786c00b93a..aa10741ba870 100644 --- a/module/zfs/zfs_fuid.c +++ b/module/zfs/zfs_fuid.c @@ -28,8 +28,8 @@ #include #include #include -#ifdef _KERNEL #include +#ifdef _KERNEL #include #include #endif diff --git a/scripts/spdxcheck.pl b/scripts/spdxcheck.pl index 4d4e14368beb..e1af3150bccd 100755 --- a/scripts/spdxcheck.pl +++ b/scripts/spdxcheck.pl @@ -124,14 +124,12 @@ include/os/freebsd/spl/sys/inttypes.h include/os/freebsd/spl/sys/mode.h include/os/freebsd/spl/sys/trace.h - include/os/freebsd/spl/sys/trace_zfs.h + include/os/freebsd/zfs/sys/trace_zfs.h include/os/freebsd/zfs/sys/zpl.h include/os/linux/kernel/linux/page_compat.h - lib/libspl/include/os/freebsd/sys/sysmacros.h lib/libspl/include/sys/string.h - lib/libspl/include/sys/trace_spl.h - lib/libspl/include/sys/trace_zfs.h lib/libzdb/libzdb.c + lib/libzpool/include/sys/trace_zfs.h module/lua/setjmp/setjmp.S module/lua/setjmp/setjmp_ppc.S module/zstd/include/sparc_compat.h diff --git a/tests/zfs-tests/cmd/Makefile.am b/tests/zfs-tests/cmd/Makefile.am index 85c3cf3c35a8..b4efefdb7ab7 100644 --- a/tests/zfs-tests/cmd/Makefile.am +++ b/tests/zfs-tests/cmd/Makefile.am @@ -60,7 +60,6 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/file_append %D%/file_check %D%/file_trunc scripts_zfs_tests_bin_PROGRAMS += %D%/libzfs_input_check -%C%_libzfs_input_check_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/include/os/@ac_system_l@/zfs %C%_libzfs_input_check_LDADD = \ libzfs_core.la \ libnvpair.la @@ -117,9 +116,7 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/edonr_test %D%/skein_test \ %C%_edonr_test_SOURCES = %D%/checksum/edonr_test.c %C%_blake3_test_SOURCES = %D%/checksum/blake3_test.c %C%_skein_test_LDADD = \ - libicp.la \ - libspl.la \ - libspl_assert.la + libzpool.la %C%_sha2_test_LDADD = $(%C%_skein_test_LDADD) %C%_edonr_test_LDADD = $(%C%_skein_test_LDADD) %C%_blake3_test_LDADD = $(%C%_skein_test_LDADD) diff --git a/tests/zfs-tests/cmd/ereports.c b/tests/zfs-tests/cmd/ereports.c index f981d5b34438..a28495b762cd 100644 --- a/tests/zfs-tests/cmd/ereports.c +++ b/tests/zfs-tests/cmd/ereports.c @@ -22,11 +22,12 @@ #include #include #include -#include #include #include #include +#define ZEVENT_NONBLOCK 0x1 + /* * Command to output io and checksum ereport values, one per line. * Used by zpool_events_duplicates.ksh to check for duplicate events.