From e14ba622cbc80e178756cdb65be1b136c4c62fbd Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 6 Jul 2025 12:16:54 +1000 Subject: [PATCH 01/57] libspl: single zfs_context_os.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/include/Makefile.am | 5 ++- .../include/os/freebsd/sys/zfs_context_os.h | 35 ------------------- .../{os/linux => }/sys/zfs_context_os.h | 15 +++++--- 3 files changed, 12 insertions(+), 43 deletions(-) delete mode 100644 lib/libspl/include/os/freebsd/sys/zfs_context_os.h rename lib/libspl/include/{os/linux => }/sys/zfs_context_os.h (62%) diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 746cb12bf637..3a744def6dd7 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -65,6 +65,7 @@ libspl_sys_HEADERS = \ %D%/sys/uio.h \ %D%/sys/vnode.h \ %D%/sys/wmsum.h \ + %D%/sys/zfs_context_os.h \ %D%/sys/zone.h libspl_ia32dir = $(libspldir)/sys/ia32 @@ -79,7 +80,6 @@ libspl_sys_HEADERS += \ %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 libspl_ia32_HEADERS = \ %D%/os/linux/sys/ia32/asm_linkage.h @@ -95,8 +95,7 @@ libspl_sys_HEADERS += \ %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/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/zfs_context_os.h b/lib/libspl/include/sys/zfs_context_os.h similarity index 62% rename from lib/libspl/include/os/linux/sys/zfs_context_os.h rename to lib/libspl/include/sys/zfs_context_os.h index bbfb4d17e06d..4dcf386e3351 100644 --- a/lib/libspl/include/os/linux/sys/zfs_context_os.h +++ b/lib/libspl/include/sys/zfs_context_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. @@ -20,9 +19,15 @@ * * 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 +#ifndef ZFS_CONTEXT_OS_H_ +#define ZFS_CONTEXT_OS_H_ #define HAVE_LARGE_STACKS 1 From bf8410f9bcfdb69fd5b2fb92712c75f8bc02d02d Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 26 Oct 2025 14:47:11 +1100 Subject: [PATCH 02/57] libzpool: move zfs_context_os.h from libspl Keeping the spl/zfs module split, libzpool is the zfs module for userspace. Headers and functions specific to it belong there. --- config/Rules.am | 3 ++- lib/libspl/include/Makefile.am | 1 - lib/libzpool/Makefile.am | 2 ++ lib/libzpool/include/Makefile.am | 3 +++ lib/{libspl => libzpool}/include/sys/zfs_context_os.h | 0 5 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 lib/libzpool/include/Makefile.am rename lib/{libspl => libzpool}/include/sys/zfs_context_os.h (100%) diff --git a/config/Rules.am b/config/Rules.am index deffa352ea24..9c0714c82513 100644 --- a/config/Rules.am +++ b/config/Rules.am @@ -10,7 +10,8 @@ AM_CPPFLAGS = \ -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/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 3a744def6dd7..be65bdb2216e 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -65,7 +65,6 @@ libspl_sys_HEADERS = \ %D%/sys/uio.h \ %D%/sys/vnode.h \ %D%/sys/wmsum.h \ - %D%/sys/zfs_context_os.h \ %D%/sys/zone.h libspl_ia32dir = $(libspldir)/sys/ia32 diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index aeacc595b363..4a5f08fcfb5e 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -1,3 +1,5 @@ +include $(srcdir)/%D%/include/Makefile.am + libzpool_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) $(LIBRARY_CFLAGS) libzpool_la_CFLAGS += $(ZLIB_CFLAGS) diff --git a/lib/libzpool/include/Makefile.am b/lib/libzpool/include/Makefile.am new file mode 100644 index 000000000000..06fffdc75def --- /dev/null +++ b/lib/libzpool/include/Makefile.am @@ -0,0 +1,3 @@ +libzpool_sysdir = $(includedir)/libzpool/sys +libzpool_sys_HEADERS = \ + %D%/sys/zfs_context_os.h diff --git a/lib/libspl/include/sys/zfs_context_os.h b/lib/libzpool/include/sys/zfs_context_os.h similarity index 100% rename from lib/libspl/include/sys/zfs_context_os.h rename to lib/libzpool/include/sys/zfs_context_os.h From 4cea265c81f63bda5c8f2d1791797a0ea65193ca Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 26 Oct 2025 15:01:21 +1100 Subject: [PATCH 03/57] libzpool: move ZFS-specific headers from libspl --- lib/libspl/include/Makefile.am | 3 --- lib/libzpool/include/Makefile.am | 3 +++ lib/{libspl => libzpool}/include/sys/abd_impl_os.h | 0 lib/{libspl => libzpool}/include/sys/abd_os.h | 0 lib/{libspl => libzpool}/include/sys/trace_zfs.h | 0 scripts/spdxcheck.pl | 2 +- 6 files changed, 4 insertions(+), 4 deletions(-) rename lib/{libspl => libzpool}/include/sys/abd_impl_os.h (100%) rename lib/{libspl => libzpool}/include/sys/abd_os.h (100%) rename lib/{libspl => libzpool}/include/sys/trace_zfs.h (100%) diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index be65bdb2216e..4eb534d16ccc 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -24,8 +24,6 @@ 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 \ @@ -58,7 +56,6 @@ libspl_sys_HEADERS = \ %D%/sys/systeminfo.h \ %D%/sys/time.h \ %D%/sys/trace_spl.h \ - %D%/sys/trace_zfs.h \ %D%/sys/tunables.h \ %D%/sys/types.h \ %D%/sys/types32.h \ diff --git a/lib/libzpool/include/Makefile.am b/lib/libzpool/include/Makefile.am index 06fffdc75def..54d10e62358b 100644 --- a/lib/libzpool/include/Makefile.am +++ b/lib/libzpool/include/Makefile.am @@ -1,3 +1,6 @@ libzpool_sysdir = $(includedir)/libzpool/sys libzpool_sys_HEADERS = \ + %D%/sys/abd_os.h \ + %D%/sys/abd_impl_os.h \ + %D%/sys/trace_zfs.h \ %D%/sys/zfs_context_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/sys/trace_zfs.h b/lib/libzpool/include/sys/trace_zfs.h similarity index 100% rename from lib/libspl/include/sys/trace_zfs.h rename to lib/libzpool/include/sys/trace_zfs.h diff --git a/scripts/spdxcheck.pl b/scripts/spdxcheck.pl index 4d4e14368beb..e119f13518cc 100755 --- a/scripts/spdxcheck.pl +++ b/scripts/spdxcheck.pl @@ -130,8 +130,8 @@ 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 From a95e250fa58a7d76f2911e50762dac60daf9bcd3 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Thu, 16 Oct 2025 13:52:57 +1100 Subject: [PATCH 04/57] libspl: move time definitions from zfs_context_os.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 33 ++---------------- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/timer.h | 64 ++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 31 deletions(-) create mode 100644 lib/libspl/include/sys/timer.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 7112d3ef5c99..39dca9939321 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -122,6 +122,8 @@ extern "C" { #include #include +#include + #include /* @@ -588,27 +590,6 @@ typedef struct vsecattr { /* * 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)) @@ -758,22 +739,12 @@ void ksiddomain_rele(ksiddomain_t *); #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); - /* * Kernel modules */ diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 4eb534d16ccc..98184340e664 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -55,6 +55,7 @@ libspl_sys_HEADERS = \ %D%/sys/sunddi.h \ %D%/sys/systeminfo.h \ %D%/sys/time.h \ + %D%/sys/timer.h \ %D%/sys/trace_spl.h \ %D%/sys/tunables.h \ %D%/sys/types.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 */ From 30f436d90841be8b43b59d2c94140237b397e08c Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 9 Aug 2025 09:51:43 +1000 Subject: [PATCH 05/57] libspl: move mutex headers from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 25 +-------------- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/mutex.h | 58 ++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 lib/libspl/include/sys/mutex.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 39dca9939321..17d3ed20ce21 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -77,7 +77,6 @@ extern "C" { #include #else /* _KERNEL || _STANDALONE */ -#define _SYS_MUTEX_H #define _SYS_RWLOCK_H #define _SYS_CONDVAR_H #define _SYS_VNODE_H @@ -122,6 +121,7 @@ extern "C" { #include #include +#include #include #include @@ -253,29 +253,6 @@ extern kthread_t *zk_thread_create(const char *name, void (*func)(void *), #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 */ diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 98184340e664..d4649c2d5dd0 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -44,6 +44,7 @@ libspl_sys_HEADERS = \ %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 \ 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 */ From 16fb8833bcf3eee5640a91f6fdc838d7cf7ef7f0 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 09:41:59 +1100 Subject: [PATCH 06/57] libspl: move mutex implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/mutex.c | 89 ++++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 56 -------------------------- 3 files changed, 90 insertions(+), 56 deletions(-) create mode 100644 lib/libspl/mutex.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index 0fd907d3011e..d03c61306835 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -19,6 +19,7 @@ libspl_la_SOURCES = \ %D%/getexecname.c \ %D%/list.c \ %D%/mkdirp.c \ + %D%/mutex.c \ %D%/page.c \ %D%/strlcat.c \ %D%/strlcpy.c \ 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/libzpool/kernel.c b/lib/libzpool/kernel.c index 452462a1700b..3c7637304a51 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -184,62 +184,6 @@ kstat_set_raw_ops(kstat_t *ksp, (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 From 61edfcc8dc57f36f9cb77acbf5daa3d83b4c82fc Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 9 Aug 2025 09:51:43 +1000 Subject: [PATCH 07/57] libspl: move rwlock definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 30 +--------------- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/rwlock.h | 62 +++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 29 deletions(-) create mode 100644 lib/libspl/include/sys/rwlock.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 17d3ed20ce21..d96113f26458 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -77,7 +77,6 @@ extern "C" { #include #else /* _KERNEL || _STANDALONE */ -#define _SYS_RWLOCK_H #define _SYS_CONDVAR_H #define _SYS_VNODE_H #define _SYS_VFS_H @@ -122,6 +121,7 @@ extern "C" { #include #include +#include #include #include @@ -253,34 +253,6 @@ extern kthread_t *zk_thread_create(const char *name, void (*func)(void *), #define kpreempt_disable() ((void)0) #define kpreempt_enable() ((void)0) -/* - * 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 */ diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index d4649c2d5dd0..f490bb9f7e6d 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -49,6 +49,7 @@ libspl_sys_HEADERS = \ %D%/sys/poll.h \ %D%/sys/priv.h \ %D%/sys/processor.h \ + %D%/sys/rwlock.h \ %D%/sys/simd.h \ %D%/sys/stack.h \ %D%/sys/stdtypes.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 */ From c9c5ac308a99e26f836c8d7c1e9d5acd9a4f9e11 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 09:56:32 +1100 Subject: [PATCH 08/57] libspl: move rwlock implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/rwlock.c | 108 +++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 75 ---------------------------- 3 files changed, 109 insertions(+), 75 deletions(-) create mode 100644 lib/libspl/rwlock.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index d03c61306835..3611d03dfb65 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -21,6 +21,7 @@ libspl_la_SOURCES = \ %D%/mkdirp.c \ %D%/mutex.c \ %D%/page.c \ + %D%/rwlock.c \ %D%/strlcat.c \ %D%/strlcpy.c \ %D%/timestamp.c \ 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/libzpool/kernel.c b/lib/libzpool/kernel.c index 3c7637304a51..dc5d6e70d0ab 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -184,74 +184,6 @@ kstat_set_raw_ops(kstat_t *ksp, (void) ksp, (void) headers, (void) data, (void) addr; } -/* - * ========================================================================= - * 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) { @@ -262,13 +194,6 @@ zone_get_hostid(void *zonep) return (hostid); } -int -rw_tryupgrade(krwlock_t *rwlp) -{ - (void) rwlp; - return (0); -} - /* * ========================================================================= * condition variables From bb11dd5f65b020b226be711046c278c4421dc478 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 9 Aug 2025 09:51:43 +1000 Subject: [PATCH 09/57] libspl: move condvar definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 31 +-------------- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/condvar.h | 65 ++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 30 deletions(-) create mode 100644 lib/libspl/include/sys/condvar.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index d96113f26458..564a8c4894be 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -77,7 +77,6 @@ extern "C" { #include #else /* _KERNEL || _STANDALONE */ -#define _SYS_CONDVAR_H #define _SYS_VNODE_H #define _SYS_VFS_H #define _SYS_SUNDDI_H @@ -122,6 +121,7 @@ extern "C" { #include #include +#include #include #include @@ -262,35 +262,6 @@ 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 */ diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index f490bb9f7e6d..e2c5f89acf56 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -30,6 +30,7 @@ libspl_sys_HEADERS = \ %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 \ 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 */ From 03597111bbe40007b7174792c9ba337cf9c7bb9e Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 10:17:08 +1100 Subject: [PATCH 10/57] libspl: move condvar implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/condvar.c | 153 +++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 119 -------------------------------- 3 files changed, 154 insertions(+), 119 deletions(-) create mode 100644 lib/libspl/condvar.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index 3611d03dfb65..badc8ffcc568 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -16,6 +16,7 @@ libspl_assert_la_SOURCES = \ libspl_la_SOURCES = \ %D%/libspl_impl.h \ %D%/atomic.c \ + %D%/condvar.c \ %D%/getexecname.c \ %D%/list.c \ %D%/mkdirp.c \ 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/libzpool/kernel.c b/lib/libzpool/kernel.c index dc5d6e70d0ab..9ab704a28f58 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -194,125 +194,6 @@ zone_get_hostid(void *zonep) return (hostid); } -/* - * ========================================================================= - * 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 From 7243d6ec1e2b802ea810eadb1a0987b240cd2156 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 9 Aug 2025 10:44:05 +1000 Subject: [PATCH 11/57] libspl: move cmn_err definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 32 +------------------------------- lib/libspl/include/sys/cmn_err.h | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 564a8c4894be..25e00f502d0c 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -122,6 +122,7 @@ extern "C" { #include #include #include +#include #include #include @@ -134,37 +135,6 @@ extern "C" { #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 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 From a65d33381266412ff354bb5da83e0ea9af71d0d1 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 25 Aug 2025 21:45:35 +1000 Subject: [PATCH 12/57] libspl: move thread definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 49 +------------------- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/thread.h | 81 +++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 48 deletions(-) create mode 100644 lib/libspl/include/sys/thread.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 25e00f502d0c..62c3487c4df6 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -90,7 +90,6 @@ extern "C" { #include #include #include -#include #include #include #include @@ -123,6 +122,7 @@ extern "C" { #include #include #include +#include #include #include @@ -176,53 +176,6 @@ extern "C" { #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) - /* * Credentials */ diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index e2c5f89acf56..cc43493b1fa1 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -57,6 +57,7 @@ libspl_sys_HEADERS = \ %D%/sys/string.h \ %D%/sys/sunddi.h \ %D%/sys/systeminfo.h \ + %D%/sys/thread.h \ %D%/sys/time.h \ %D%/sys/timer.h \ %D%/sys/trace_spl.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 */ From 318a733944214f4a6337f8a01e6781399551389e Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 13:30:12 +1100 Subject: [PATCH 13/57] libspl: move thread implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/thread.c | 118 +++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 86 ------------------------------ 3 files changed, 119 insertions(+), 86 deletions(-) create mode 100644 lib/libspl/thread.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index badc8ffcc568..10920ae8c606 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -25,6 +25,7 @@ libspl_la_SOURCES = \ %D%/rwlock.c \ %D%/strlcat.c \ %D%/strlcpy.c \ + %D%/thread.c \ %D%/timestamp.c \ %D%/tunables.c \ %D%/include/sys/list.h \ 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/libzpool/kernel.c b/lib/libzpool/kernel.c index 9ab704a28f58..704c8faff8d5 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -63,92 +63,6 @@ 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 From 78c1f1ec10b7080ec9dabf678e2b29f9f6f4453d Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 16 Aug 2025 20:23:25 +1000 Subject: [PATCH 14/57] libspl: move taskq definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 79 +--------------------- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/taskq.h | 116 +++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 78 deletions(-) create mode 100644 lib/libspl/include/sys/taskq.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 62c3487c4df6..6f7ae6b069ef 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -123,6 +123,7 @@ extern "C" { #include #include #include +#include #include #include @@ -280,84 +281,6 @@ typedef enum kmem_cbrc { 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 diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index cc43493b1fa1..7d5e1b7b3f66 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -58,6 +58,7 @@ libspl_sys_HEADERS = \ %D%/sys/sunddi.h \ %D%/sys/systeminfo.h \ %D%/sys/thread.h \ + %D%/sys/taskq.h \ %D%/sys/time.h \ %D%/sys/timer.h \ %D%/sys/trace_spl.h \ 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 */ From 7ad5870d827d02d93ab59fcc66f84acd3516c642 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 09:08:01 +1100 Subject: [PATCH 15/57] libspl: move taskq implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/{libzpool => libspl}/taskq.c | 0 lib/libzpool/Makefile.am | 1 - 3 files changed, 1 insertion(+), 1 deletion(-) rename lib/{libzpool => libspl}/taskq.c (100%) diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index 10920ae8c606..cb70fb29614f 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -25,6 +25,7 @@ libspl_la_SOURCES = \ %D%/rwlock.c \ %D%/strlcat.c \ %D%/strlcpy.c \ + %D%/taskq.c \ %D%/thread.c \ %D%/timestamp.c \ %D%/tunables.c \ diff --git a/lib/libzpool/taskq.c b/lib/libspl/taskq.c similarity index 100% rename from lib/libzpool/taskq.c rename to lib/libspl/taskq.c diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 4a5f08fcfb5e..9921c595e0d7 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -14,7 +14,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 \ From 6cbe8f410c052387a648eac18e40b84f3f52fa86 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 25 Aug 2025 22:00:24 +1000 Subject: [PATCH 16/57] libspl: move cred definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 15 --------------- lib/libspl/include/sys/cred.h | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 6f7ae6b069ef..e7d164a176e0 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -177,15 +177,6 @@ extern "C" { #endif /* DTRACE_PROBE4 */ #define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) -/* - * 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); - /* * Thread-specific data */ @@ -371,12 +362,6 @@ typedef struct vsecattr { #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) 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 From 24ee5d80a680f6a2e95e5e8582e208cfd1887770 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 14:14:41 +1100 Subject: [PATCH 17/57] libspl: move cred implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/cred.c | 65 ++++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 35 ----------------------- 3 files changed, 66 insertions(+), 35 deletions(-) create mode 100644 lib/libspl/cred.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index cb70fb29614f..b13cb676633e 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -17,6 +17,7 @@ libspl_la_SOURCES = \ %D%/libspl_impl.h \ %D%/atomic.c \ %D%/condvar.c \ + %D%/cred.c \ %D%/getexecname.c \ %D%/list.c \ %D%/mkdirp.c \ diff --git a/lib/libspl/cred.c b/lib/libspl/cred.c new file mode 100644 index 000000000000..48527b1998f3 --- /dev/null +++ b/lib/libspl/cred.c @@ -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 (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/libzpool/kernel.c b/lib/libzpool/kernel.c index 704c8faff8d5..019f4e573fd3 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -635,41 +635,6 @@ kernel_fini(void) 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) { From 4989a45dad9286770e1cf376e6a76e8dc5ad6c4e Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Wed, 15 Oct 2025 17:31:31 +1100 Subject: [PATCH 18/57] libspl: move tsd definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 8 +------ lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/tsd.h | 42 ++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 1 + 4 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 lib/libspl/include/sys/tsd.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index e7d164a176e0..64aee9dc31eb 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -124,6 +124,7 @@ extern "C" { #include #include #include +#include #include #include @@ -177,13 +178,6 @@ extern "C" { #endif /* DTRACE_PROBE4 */ #define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) -/* - * 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 diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 7d5e1b7b3f66..c5e6111fabd6 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -62,6 +62,7 @@ libspl_sys_HEADERS = \ %D%/sys/time.h \ %D%/sys/timer.h \ %D%/sys/trace_spl.h \ + %D%/sys/tsd.h \ %D%/sys/tunables.h \ %D%/sys/types.h \ %D%/sys/types32.h \ 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/libzpool/kernel.c b/lib/libzpool/kernel.c index 019f4e573fd3..aed0a96bb58e 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include From e05cd5bb5cca4079870773217368b9a14947b9fa Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Thu, 16 Oct 2025 12:39:35 +1100 Subject: [PATCH 19/57] libspl: move kstat definitions from zfs_context.h, slim down to basics Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 12 - lib/libspl/include/sys/kstat.h | 743 ++------------------------------- 2 files changed, 25 insertions(+), 730 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 64aee9dc31eb..bb36d0baa93f 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -182,18 +182,6 @@ extern "C" { 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 */ 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 */ From 9e5e17521f2a886992e89af654c3dee04b233fa9 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 13:38:26 +1100 Subject: [PATCH 20/57] libspl: move kstat implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/kstat.c | 64 ++++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 35 ----------------------- 3 files changed, 65 insertions(+), 35 deletions(-) create mode 100644 lib/libspl/kstat.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index b13cb676633e..77e7461951ed 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -19,6 +19,7 @@ libspl_la_SOURCES = \ %D%/condvar.c \ %D%/cred.c \ %D%/getexecname.c \ + %D%/kstat.c \ %D%/list.c \ %D%/mkdirp.c \ %D%/mutex.c \ 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/libzpool/kernel.c b/lib/libzpool/kernel.c index aed0a96bb58e..f57c082351ff 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -64,41 +64,6 @@ struct utsname hw_utsname; /* If set, all blocks read will be copied to the specified directory. */ char *vn_dumpdir = NULL; -/* - * ========================================================================= - * 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; -} - uint32_t zone_get_hostid(void *zonep) { From 4775fb3ed44ef398f7ae4699d89625d14d653ee3 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Thu, 16 Oct 2025 13:12:30 +1100 Subject: [PATCH 21/57] libspl: move procfs_list definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 36 +-------------- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/procfs_list.h | 69 ++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 35 deletions(-) create mode 100644 lib/libspl/include/sys/procfs_list.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index bb36d0baa93f..1c636436ebc9 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -125,6 +125,7 @@ extern "C" { #include #include #include +#include #include #include @@ -182,41 +183,6 @@ extern "C" { typedef off_t loff_t; #endif -/* - * 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 */ diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index c5e6111fabd6..486cce3f161c 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -50,6 +50,7 @@ libspl_sys_HEADERS = \ %D%/sys/poll.h \ %D%/sys/priv.h \ %D%/sys/processor.h \ + %D%/sys/procfs_list.h \ %D%/sys/rwlock.h \ %D%/sys/simd.h \ %D%/sys/stack.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 */ From 8515bc30c0a4892543279222937ca2c30d1259fb Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 13:49:15 +1100 Subject: [PATCH 22/57] libspl: move procfs_list implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/procfs_list.c | 93 ++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 59 ------------------------- 3 files changed, 94 insertions(+), 59 deletions(-) create mode 100644 lib/libspl/procfs_list.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index 77e7461951ed..b7f519871f77 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -24,6 +24,7 @@ libspl_la_SOURCES = \ %D%/mkdirp.c \ %D%/mutex.c \ %D%/page.c \ + %D%/procfs_list.c \ %D%/rwlock.c \ %D%/strlcat.c \ %D%/strlcpy.c \ 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/libzpool/kernel.c b/lib/libzpool/kernel.c index f57c082351ff..836af6565696 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -74,65 +74,6 @@ zone_get_hostid(void *zonep) return (hostid); } -/* - * ========================================================================= - * 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 From 3545e748fe4316aa4fa66ca29aac12f48d63c59d Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Thu, 16 Oct 2025 13:27:43 +1100 Subject: [PATCH 23/57] libspl: move kmem definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 55 +---------------------------- lib/libspl/include/sys/kmem.h | 66 ++++++++++++++++++++++++++++------- lib/libspl/include/umem.h | 1 + 3 files changed, 55 insertions(+), 67 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 1c636436ebc9..f043249a289e 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -92,7 +92,6 @@ extern "C" { #include #include #include -#include #include #include #include @@ -126,6 +125,7 @@ extern "C" { #include #include #include +#include #include #include @@ -183,43 +183,6 @@ extern "C" { typedef off_t loff_t; #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; - #define XVA_MAPSIZE 3 #define XVA_MAGIC 0x78766174 @@ -373,16 +336,6 @@ typedef struct callb_cpr { #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 */ @@ -438,12 +391,6 @@ void ksiddomain_rele(ksiddomain_t *); #define ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g) \ sysevent_post_event(_c, _d, _b, "libzpool", _e, _f) -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); - /* * Kernel modules */ 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/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" { From 4f43476d65e0dc46b327d7e9ff7854a2ce44f872 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 14:12:20 +1100 Subject: [PATCH 24/57] libspl: move kmem implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/kmem.c | 102 +++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 73 ----------------------------- 3 files changed, 103 insertions(+), 73 deletions(-) create mode 100644 lib/libspl/kmem.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index b7f519871f77..a6afd17934e1 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -19,6 +19,7 @@ libspl_la_SOURCES = \ %D%/condvar.c \ %D%/cred.c \ %D%/getexecname.c \ + %D%/kmem.c \ %D%/kstat.c \ %D%/list.c \ %D%/mkdirp.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/libzpool/kernel.c b/lib/libzpool/kernel.c index 836af6565696..d73495203b12 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -587,61 +587,6 @@ ksiddomain_rele(ksiddomain_t *ksid) 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); -} - zfs_file_t * zfs_onexit_fd_hold(int fd, minor_t *minorp) { @@ -664,24 +609,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) { From b4051093e52f35c287c7bf724b24f9747f48d843 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Fri, 17 Oct 2025 22:25:23 +1100 Subject: [PATCH 25/57] libspl: move vattr and xvattr definitions from zfs_context.h; enable for userspace Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_acl.h | 2 +- include/sys/zfs_context.h | 72 +--------------------------------- lib/libspl/include/sys/vnode.h | 35 +++++++++++++++-- 3 files changed, 34 insertions(+), 75 deletions(-) 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_context.h b/include/sys/zfs_context.h index f043249a289e..dac1e4b6922e 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -77,7 +77,6 @@ extern "C" { #include #else /* _KERNEL || _STANDALONE */ -#define _SYS_VNODE_H #define _SYS_VFS_H #define _SYS_SUNDDI_H #define _SYS_CALLB_H @@ -127,6 +126,7 @@ extern "C" { #include #include #include +#include #include @@ -183,77 +183,7 @@ extern "C" { typedef off_t loff_t; #endif -#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 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 */ From 8f89d7b4be7b55a538336bea378871200a936f50 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Wed, 22 Oct 2025 13:52:22 +1100 Subject: [PATCH 26/57] libspl: add include guards for sys/string.h The extra inclusion via xvattr.h appears to upset the linter in CI. I'm not entirely sure what its complaint is, but removing sys/string.h entirely is not quite possible yet, and include guards are rarely a bad idea, so this will do. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/include/sys/string.h | 3 +++ 1 file changed, 3 insertions(+) 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 From 507c47de3b14f886020ed9f6c1751504f4c5964f Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 18 Oct 2025 22:24:06 +1100 Subject: [PATCH 27/57] libspl: move ptob() from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 2 -- lib/libspl/include/os/freebsd/sys/param.h | 2 ++ lib/libspl/include/os/linux/sys/param.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index dac1e4b6922e..770cb73f224b 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -203,8 +203,6 @@ extern char *vn_dumpdir; #define CPU_SEQID ((uintptr_t)pthread_self() & (max_ncpus - 1)) #define CPU_SEQID_UNSTABLE CPU_SEQID -#define ptob(x) ((x) * PAGESIZE) - #define NN_DIVISOR_1000 (1U << 0) #define NN_NUMBUF_SZ (6) 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/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 From 9fcf822d7e0a0690efebe1d7af613c47856e4224 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 18 Oct 2025 22:35:57 +1100 Subject: [PATCH 28/57] zfs_context: remove duplicated access control stuff; remove kernel gate Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 15 --------------- lib/libspl/include/sys/acl.h | 4 ---- 2 files changed, 19 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 770cb73f224b..49d3b207a31d 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -283,21 +283,6 @@ 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); 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| \ From bf3cb818c56224cb68a2e1841d7cf8054e48278e Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Fri, 24 Oct 2025 22:37:54 +1100 Subject: [PATCH 29/57] libzpool: separate driver-side include Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- cmd/raidz_test/raidz_test.c | 1 + cmd/zdb/zdb.c | 1 + cmd/zhack.c | 1 + cmd/ztest.c | 1 + include/Makefile.am | 1 + include/libzpool.h | 49 +++++++++++++++++++++++++++++++++++++ include/sys/zfs_context.h | 6 ----- lib/libzpool/kernel.c | 3 +++ lib/libzpool/util.c | 1 + 9 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 include/libzpool.h 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 fa8e7fa691db..09e144f66c68 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 89b1f68606ea..54b4fdb4c48a 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/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..3fd6c694d2f3 --- /dev/null +++ b/include/libzpool.h @@ -0,0 +1,49 @@ +// 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 + +_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/sys/zfs_context.h b/include/sys/zfs_context.h index 49d3b207a31d..ef5899b11972 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -230,15 +230,9 @@ random_in_range(uint32_t range) 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; diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index d73495203b12..d7ff74cba62a 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -45,6 +45,9 @@ #include #include #include + +#include +#include #include #include #include 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. From fb7c89afcc8bb0f24b201602101006fea6cff4bf Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Fri, 24 Oct 2025 22:32:31 +1100 Subject: [PATCH 30/57] libspl: init/fini Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/include/Makefile.am | 1 + lib/libspl/include/libspl.h | 40 ++++++++++++++++++++++++++++++++++ lib/libspl/libspl.c | 36 ++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 4 ++++ 5 files changed, 82 insertions(+) create mode 100644 lib/libspl/include/libspl.h create mode 100644 lib/libspl/libspl.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index a6afd17934e1..3d46829ed01e 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -21,6 +21,7 @@ libspl_la_SOURCES = \ %D%/getexecname.c \ %D%/kmem.c \ %D%/kstat.c \ + %D%/libspl.c \ %D%/list.c \ %D%/mkdirp.c \ %D%/mutex.c \ diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 486cce3f161c..41139d33ef82 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 \ 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/libspl.c b/lib/libspl/libspl.c new file mode 100644 index 000000000000..7c24f5cc0668 --- /dev/null +++ b/lib/libspl/libspl.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2025, Rob Norris + */ + +#include + +void +libspl_init(void) +{ +} + +void +libspl_fini(void) +{ +} diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index d7ff74cba62a..24d6fada3c1e 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -505,6 +505,8 @@ kernel_init(int mode) { extern uint_t rrw_tsd_key; + libspl_init(); + umem_nofail_callback(umem_out_of_memory); physmem = sysconf(_SC_PHYS_PAGES); @@ -543,6 +545,8 @@ kernel_fini(void) system_taskq_fini(); random_fini(); + + libspl_fini(); } int From cea4596fabdac5c39cd95f107124d041ab6ff709 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Fri, 24 Oct 2025 23:19:53 +1100 Subject: [PATCH 31/57] libspl: move physmem to sys/systm.h; initialise at libspl_init() Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 5 ++++- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/systm.h | 34 ++++++++++++++++++++++++++++++++++ lib/libspl/libspl.c | 8 ++++++++ lib/libzpool/kernel.c | 3 --- 5 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 lib/libspl/include/sys/systm.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index ef5899b11972..d9eb64b1cbf4 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -127,6 +127,10 @@ extern "C" { #include #include #include +#include +#include +#include +#include #include @@ -206,7 +210,6 @@ extern char *vn_dumpdir; #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; diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 41139d33ef82..8c5bb7b72986 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -59,6 +59,7 @@ libspl_sys_HEADERS = \ %D%/sys/string.h \ %D%/sys/sunddi.h \ %D%/sys/systeminfo.h \ + %D%/sys/systm.h \ %D%/sys/thread.h \ %D%/sys/taskq.h \ %D%/sys/time.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/libspl.c b/lib/libspl/libspl.c index 7c24f5cc0668..d189357a1c30 100644 --- a/lib/libspl/libspl.c +++ b/lib/libspl/libspl.c @@ -20,14 +20,22 @@ * 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 + +uint64_t physmem; void libspl_init(void) { + physmem = sysconf(_SC_PHYS_PAGES); } void diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index 24d6fada3c1e..25663882b6e7 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -60,7 +60,6 @@ * Emulation of kernel services in userland. */ -uint64_t physmem; uint32_t hostid; struct utsname hw_utsname; @@ -509,8 +508,6 @@ kernel_init(int mode) umem_nofail_callback(umem_out_of_memory); - physmem = sysconf(_SC_PHYS_PAGES); - dprintf("physmem = %llu pages (%.2f GB)\n", (u_longlong_t)physmem, (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); From be4aa5b6e04fbdae6729a4e055550c1072da0314 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Fri, 24 Oct 2025 23:39:20 +1100 Subject: [PATCH 32/57] libspl: move utsname() etc to sys/misc.h; initialise in libspl_init() Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 5 +---- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/misc.h | 40 ++++++++++++++++++++++++++++++++++ lib/libspl/libspl.c | 12 ++++++++++ lib/libzpool/kernel.c | 10 --------- 5 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 lib/libspl/include/sys/misc.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index d9eb64b1cbf4..d1cf0bde046d 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -113,7 +113,6 @@ extern "C" { #include #include #include -#include #include #include @@ -131,6 +130,7 @@ extern "C" { #include #include #include +#include #include @@ -267,9 +267,6 @@ extern uint32_t zone_get_hostid(void *zonep); 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 { diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 8c5bb7b72986..dece09145b97 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -43,6 +43,7 @@ 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 \ diff --git a/lib/libspl/include/sys/misc.h b/lib/libspl/include/sys/misc.h new file mode 100644 index 000000000000..171bbc1de798 --- /dev/null +++ b/lib/libspl/include/sys/misc.h @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _LIBSPL_SYS_MISC_H +#define _LIBSPL_SYS_MISC_H + +#include + +/* + * Hostname information + */ +typedef struct utsname utsname_t; +extern utsname_t *utsname(void); + +#endif diff --git a/lib/libspl/libspl.c b/lib/libspl/libspl.c index d189357a1c30..84e44ef51194 100644 --- a/lib/libspl/libspl.c +++ b/lib/libspl/libspl.c @@ -28,14 +28,26 @@ */ #include +#include #include +#include +#include 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)); } void diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index 25663882b6e7..0d658be13057 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include @@ -61,7 +60,6 @@ */ uint32_t hostid; -struct utsname hw_utsname; /* If set, all blocks read will be copied to the specified directory. */ char *vn_dumpdir = NULL; @@ -405,12 +403,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 @@ -515,8 +507,6 @@ kernel_init(int mode) random_init(); - VERIFY0(uname(&hw_utsname)); - system_taskq_init(); icp_init(); From e606bef308db253e6288f2cbe069f11483aeec14 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Fri, 24 Oct 2025 23:42:12 +1100 Subject: [PATCH 33/57] zfs_context: move vn_dumpdir to libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/libzpool.h | 2 ++ include/sys/zfs_context.h | 2 -- lib/libspl/cred.c | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/libzpool.h b/include/libzpool.h index 3fd6c694d2f3..95991e68116e 100644 --- a/include/libzpool.h +++ b/include/libzpool.h @@ -35,6 +35,8 @@ extern "C" { #endif +extern char *vn_dumpdir; + _LIBZPOOL_H void kernel_init(int mode); _LIBZPOOL_H void kernel_fini(void); diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index d1cf0bde046d..741e3bd3c094 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -187,8 +187,6 @@ extern "C" { typedef off_t loff_t; #endif -extern char *vn_dumpdir; - /* * Random stuff */ diff --git a/lib/libspl/cred.c b/lib/libspl/cred.c index 48527b1998f3..130323ea91a7 100644 --- a/lib/libspl/cred.c +++ b/lib/libspl/cred.c @@ -62,4 +62,3 @@ crgetgroups(cred_t *cr) (void) cr; return (NULL); } - From dea8b904738074d209604d2cdc15fc1533b5e751 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 18 Oct 2025 23:39:19 +1100 Subject: [PATCH 34/57] libspl: move random definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 25 +---------------- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/misc.h | 3 ++ lib/libspl/include/sys/random.h | 50 +++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 lib/libspl/include/sys/random.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 741e3bd3c094..a209c19d22ab 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -126,11 +126,11 @@ extern "C" { #include #include #include -#include #include #include #include #include +#include #include @@ -208,31 +208,8 @@ typedef off_t loff_t; #define NN_DIVISOR_1000 (1U << 0) #define NN_NUMBUF_SZ (6) -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 random_init(void); -extern void random_fini(void); typedef struct callb_cpr { kmutex_t *cc_lockp; diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index dece09145b97..c7a39fccb206 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -53,6 +53,7 @@ libspl_sys_HEADERS = \ %D%/sys/priv.h \ %D%/sys/processor.h \ %D%/sys/procfs_list.h \ + %D%/sys/random.h \ %D%/sys/rwlock.h \ %D%/sys/simd.h \ %D%/sys/stack.h \ diff --git a/lib/libspl/include/sys/misc.h b/lib/libspl/include/sys/misc.h index 171bbc1de798..8f2f5f9332e7 100644 --- a/lib/libspl/include/sys/misc.h +++ b/lib/libspl/include/sys/misc.h @@ -31,6 +31,9 @@ #include +extern const char *random_path; +extern const char *urandom_path; + /* * Hostname information */ 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 */ From 94a3644c461bb506e73c2fd23f1bbcac638ac6de Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Fri, 24 Oct 2025 23:58:42 +1100 Subject: [PATCH 35/57] libspl: move random impl from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/libspl.c | 4 ++ lib/libspl/libspl_impl.h | 7 ++++ lib/libspl/random.c | 84 ++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 55 -------------------------- 5 files changed, 96 insertions(+), 55 deletions(-) create mode 100644 lib/libspl/random.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index 3d46829ed01e..c075be60bf35 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -27,6 +27,7 @@ libspl_la_SOURCES = \ %D%/mutex.c \ %D%/page.c \ %D%/procfs_list.c \ + %D%/random.c \ %D%/rwlock.c \ %D%/strlcat.c \ %D%/strlcpy.c \ diff --git a/lib/libspl/libspl.c b/lib/libspl/libspl.c index 84e44ef51194..63e948bc2829 100644 --- a/lib/libspl/libspl.c +++ b/lib/libspl/libspl.c @@ -32,6 +32,7 @@ #include #include #include +#include "libspl_impl.h" uint64_t physmem; struct utsname hw_utsname; @@ -48,9 +49,12 @@ 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/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/libzpool/kernel.c b/lib/libzpool/kernel.c index 0d658be13057..44a85f1ad62d 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -342,57 +342,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) { @@ -505,8 +454,6 @@ kernel_init(int mode) hostid = (mode & SPA_MODE_WRITE) ? get_system_hostid() : 0; - random_init(); - system_taskq_init(); icp_init(); @@ -531,8 +478,6 @@ kernel_fini(void) icp_fini(); system_taskq_fini(); - random_fini(); - libspl_fini(); } From e709dabc5e2c28e17a4f869caab9e426d496a113 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 18 Oct 2025 23:45:31 +1100 Subject: [PATCH 36/57] libspl: move callb stubs from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 23 +---------------------- lib/libspl/include/sys/callb.h | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index a209c19d22ab..c11c2c9e243f 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -79,7 +79,6 @@ extern "C" { #define _SYS_VFS_H #define _SYS_SUNDDI_H -#define _SYS_CALLB_H #include #include @@ -131,6 +130,7 @@ extern "C" { #include #include #include +#include #include @@ -211,27 +211,6 @@ typedef off_t loff_t; extern int highbit64(uint64_t i); extern int lowbit64(uint64_t i); -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); 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 From 653a360fa789b78de03d66d6f1197a5a1dc860e1 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 12:13:32 +1100 Subject: [PATCH 37/57] libspl: move SID definitions from zfs_context.h; remove kernel gate Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 10 -------- lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/sid.h | 44 ++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 1 + module/zfs/zfs_fuid.c | 2 +- 5 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 lib/libspl/include/sys/sid.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index c11c2c9e243f..bec036db5309 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -238,16 +238,6 @@ 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) diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index c7a39fccb206..6784823e58dc 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -55,6 +55,7 @@ libspl_sys_HEADERS = \ %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 \ 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/libzpool/kernel.c b/lib/libzpool/kernel.c index 44a85f1ad62d..33e03b127709 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include 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 From e6171c076f546148db38d06b944daafa7c8c86c2 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 27 Oct 2025 14:37:06 +1100 Subject: [PATCH 38/57] libspl: move SID implementation from libzpool Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/Makefile.am | 1 + lib/libspl/sid.c | 47 ++++++++++++++++++++++++++++++++++++++++++ lib/libzpool/kernel.c | 17 --------------- 3 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 lib/libspl/sid.c diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index c075be60bf35..27f004634487 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -29,6 +29,7 @@ libspl_la_SOURCES = \ %D%/procfs_list.c \ %D%/random.c \ %D%/rwlock.c \ + %D%/sid.c \ %D%/strlcat.c \ %D%/strlcpy.c \ %D%/taskq.c \ 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/kernel.c b/lib/libzpool/kernel.c index 33e03b127709..8fd9157f47c7 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -510,23 +510,6 @@ secpolicy_zfs(const cred_t *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)); -} - zfs_file_t * zfs_onexit_fd_hold(int fd, minor_t *minorp) { From aaec7ca7f8da66973c3cbdee4797f0ae1d21788b Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 13:09:34 +1100 Subject: [PATCH 39/57] libspl: move zone definitions from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 6 +----- lib/libspl/include/sys/zone.h | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index bec036db5309..d8c544663d65 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -113,6 +113,7 @@ extern "C" { #include #include #include +#include #include #include @@ -211,10 +212,6 @@ typedef off_t loff_t; extern int highbit64(uint64_t i); extern int lowbit64(uint64_t i); -#define zone_dataset_visible(x, y) (1) -#define INGLOBALZONE(z) (1) -extern uint32_t zone_get_hostid(void *zonep); - /* * Hostname information */ @@ -236,7 +233,6 @@ 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); #define DDI_SLEEP KM_SLEEP #define ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g) \ 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 */ From 2d5872f05e23c9e43e4695cac328a47f95d1985b Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 13:18:12 +1100 Subject: [PATCH 40/57] libzpool: remove unused userspace ioctl policy functions Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 6 ------ lib/libzpool/kernel.c | 28 ---------------------------- 2 files changed, 34 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index d8c544663d65..1d5d6e45a764 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -228,12 +228,6 @@ struct bootstat { uint64_t st_size; }; -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); - #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) diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index 8fd9157f47c7..7e3ffec3b81d 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -482,34 +482,6 @@ kernel_fini(void) libspl_fini(); } -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); -} - zfs_file_t * zfs_onexit_fd_hold(int fd, minor_t *minorp) { From 45a7d569ebd7b879347b3f543e37380e4cea56e3 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 13:25:44 +1100 Subject: [PATCH 41/57] zfs_context: remove misc unused Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 1d5d6e45a764..0cde355bea99 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -77,7 +77,6 @@ extern "C" { #include #else /* _KERNEL || _STANDALONE */ -#define _SYS_VFS_H #define _SYS_SUNDDI_H #include @@ -206,7 +205,6 @@ typedef off_t loff_t; #define CPU_SEQID ((uintptr_t)pthread_self() & (max_ncpus - 1)) #define CPU_SEQID_UNSTABLE CPU_SEQID -#define NN_DIVISOR_1000 (1U << 0) #define NN_NUMBUF_SZ (6) extern int highbit64(uint64_t i); @@ -218,20 +216,6 @@ extern int lowbit64(uint64_t i); extern int ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result); -/* ZFS Boot Related stuff. */ - -struct _buf { - intptr_t _fd; -}; - -struct bootstat { - uint64_t st_size; -}; - -#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) - /* * Kernel modules */ From 7a83db3cfa72376c0f5b8548dbf5b63e42e2386c Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 13:34:14 +1100 Subject: [PATCH 42/57] libspl: move remaining ddi_* prototypes from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 8 -------- lib/libspl/include/sys/sunddi.h | 8 +++++++- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 0cde355bea99..50f43c10c20b 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -77,8 +77,6 @@ extern "C" { #include #else /* _KERNEL || _STANDALONE */ -#define _SYS_SUNDDI_H - #include #include #include @@ -210,12 +208,6 @@ typedef off_t loff_t; extern int highbit64(uint64_t i); extern int lowbit64(uint64_t i); -/* - * Hostname information - */ -extern int ddi_strtoull(const char *str, char **nptr, int base, - u_longlong_t *result); - /* * Kernel modules */ 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 */ From e892745dba4e3623199d4c0615cdde7313347b70 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 13:42:49 +1100 Subject: [PATCH 43/57] libspl: move DTRACE_PROBE macros from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 42 +------------------ lib/libspl/include/Makefile.am | 1 + lib/libspl/include/sys/trace.h | 73 ++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 41 deletions(-) create mode 100644 lib/libspl/include/sys/trace.h diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 50f43c10c20b..da16f4ceea8a 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -129,6 +129,7 @@ extern "C" { #include #include #include +#include #include @@ -140,47 +141,6 @@ extern "C" { #define likely(x) __builtin_expect((x), 1) #define unlikely(x) __builtin_expect((x), 0) -/* - * 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) - #ifdef __FreeBSD__ typedef off_t loff_t; #endif diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 6784823e58dc..73c29cca5d6d 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -67,6 +67,7 @@ libspl_sys_HEADERS = \ %D%/sys/taskq.h \ %D%/sys/time.h \ %D%/sys/timer.h \ + %D%/sys/trace.h \ %D%/sys/trace_spl.h \ %D%/sys/tsd.h \ %D%/sys/tunables.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 */ From d3f55cdf6c6c40d92ec0d8f00c4eb21613f24005 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 13:57:19 +1100 Subject: [PATCH 44/57] libspl: common sysmacros.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 21 --------- lib/libspl/include/Makefile.am | 5 +-- lib/libspl/include/os/freebsd/sys/sysmacros.h | 1 - .../include/{os/linux => }/sys/sysmacros.h | 43 ++++++++++++++----- scripts/spdxcheck.pl | 1 - 5 files changed, 35 insertions(+), 36 deletions(-) delete mode 100644 lib/libspl/include/os/freebsd/sys/sysmacros.h rename lib/libspl/include/{os/linux => }/sys/sysmacros.h (72%) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index da16f4ceea8a..08c0b58a574c 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -145,29 +145,8 @@ extern "C" { typedef off_t loff_t; #endif -/* - * Random stuff - */ -#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 NN_NUMBUF_SZ (6) -extern int highbit64(uint64_t i); -extern int lowbit64(uint64_t i); - /* * Kernel modules */ diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 73c29cca5d6d..202f15944762 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -61,6 +61,7 @@ libspl_sys_HEADERS = \ %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 \ @@ -88,8 +89,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/vfs.h libspl_ia32_HEADERS = \ %D%/os/linux/sys/ia32/asm_linkage.h @@ -104,7 +104,6 @@ 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 libspl_ia32_HEADERS = \ diff --git a/lib/libspl/include/os/freebsd/sys/sysmacros.h b/lib/libspl/include/os/freebsd/sys/sysmacros.h deleted file mode 100644 index d9639d27b60e..000000000000 --- a/lib/libspl/include/os/freebsd/sys/sysmacros.h +++ /dev/null @@ -1 +0,0 @@ -/* keep me */ 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/scripts/spdxcheck.pl b/scripts/spdxcheck.pl index e119f13518cc..1b3dd639318f 100755 --- a/scripts/spdxcheck.pl +++ b/scripts/spdxcheck.pl @@ -127,7 +127,6 @@ include/os/freebsd/spl/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/libzdb/libzdb.c From 055e0c91b8f8747d2fe0e3f18c56d0e4569861a2 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 14:27:26 +1100 Subject: [PATCH 45/57] libzutil: move NN_NUMBUF_SZ from zfs_context.h nearer to nicenum() Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/libzutil.h | 1 + include/sys/zfs_context.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) 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/sys/zfs_context.h b/include/sys/zfs_context.h index 08c0b58a574c..d010b4eb39a2 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -145,8 +145,6 @@ extern "C" { typedef off_t loff_t; #endif -#define NN_NUMBUF_SZ (6) - /* * Kernel modules */ From 36c263ecf90a9ea9b4c57583faf1396b7c7c277f Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 14:41:38 +1100 Subject: [PATCH 46/57] libspl: move compiler attribute macros from zfs_context.h sys/debug.h is not really the right place for them, but we already have some there for libspl, so it is at least convenient. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 8 -------- lib/libspl/include/sys/debug.h | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index d010b4eb39a2..7c410dc23baa 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -133,14 +133,6 @@ extern "C" { #include -/* - * Stack - */ - -#define noinline __attribute__((noinline)) -#define likely(x) __builtin_expect((x), 1) -#define unlikely(x) __builtin_expect((x), 0) - #ifdef __FreeBSD__ typedef off_t loff_t; #endif diff --git a/lib/libspl/include/sys/debug.h b/lib/libspl/include/sys/debug.h index 02f33a68b75b..6ce8c88f6aa4 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,16 @@ #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 + #endif From ecad15c3c480eb6050602e5c9453248ff6d6cecb Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 14:44:14 +1100 Subject: [PATCH 47/57] zfs_context: move empty __init/__exit macros to sys/debug.h These are kind-of compiler attribute placeholders, so go here with the others for now. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 6 ------ lib/libspl/include/sys/debug.h | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 7c410dc23baa..dfd37930f7e8 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -137,12 +137,6 @@ extern "C" { typedef off_t loff_t; #endif -/* - * Kernel modules - */ -#define __init -#define __exit - #endif /* _KERNEL || _STANDALONE */ #ifdef __cplusplus diff --git a/lib/libspl/include/sys/debug.h b/lib/libspl/include/sys/debug.h index 6ce8c88f6aa4..2bd077686f1c 100644 --- a/lib/libspl/include/sys/debug.h +++ b/lib/libspl/include/sys/debug.h @@ -60,4 +60,10 @@ #define unlikely(x) __builtin_expect((x), 0) #endif +/* + * Kernel modules + */ +#define __init +#define __exit + #endif From 8769648f1264fe1ce08b04639c74dc94faf2ae7b Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 19 Oct 2025 15:09:48 +1100 Subject: [PATCH 48/57] libspl: move loff_t declaration from zfs_context.h Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 4 ---- lib/libspl/include/sys/types.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index dfd37930f7e8..4be22835d2a2 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -133,10 +133,6 @@ extern "C" { #include -#ifdef __FreeBSD__ -typedef off_t loff_t; -#endif - #endif /* _KERNEL || _STANDALONE */ #ifdef __cplusplus 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 From 7b48a236bd457bc69790626a56d7fea0348861f7 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 30 Oct 2025 17:23:27 -0700 Subject: [PATCH 49/57] debug: move all of the debug bits out of the spl Pull all of the internal debug infrastructure up in to the zfs code to clean up the layering. Remove all the dodgy usage of SET_ERROR and DTRACE_PROBE from the spl. Luckily it was lightly used in the spl layer so we're not losing much. Signed-off-by: Brian Behlendorf Signed-off-by: Rob Norris --- include/os/freebsd/Makefile.am | 4 +-- .../os/freebsd/{spl => zfs}/sys/trace_zfs.h | 0 .../{spl/sys/sdt.h => zfs/sys/zfs_debug_os.h} | 9 +++--- include/os/linux/Makefile.am | 2 +- include/os/linux/spl/sys/sysmacros.h | 8 ----- include/os/linux/zfs/sys/zfs_debug_os.h | 29 +++++++++++++++++++ include/sys/zfs_context.h | 1 - include/sys/zfs_debug.h | 1 + lib/libspl/include/Makefile.am | 1 - lib/libspl/include/sys/trace_spl.h | 24 --------------- lib/libzpool/include/Makefile.am | 3 +- lib/libzpool/include/sys/trace_zfs.h | 25 +--------------- lib/libzpool/include/sys/zfs_debug_os.h | 29 +++++++++++++++++++ module/os/freebsd/spl/spl_uio.c | 2 +- module/os/linux/spl/spl-taskq.c | 14 --------- scripts/spdxcheck.pl | 1 - 16 files changed, 71 insertions(+), 82 deletions(-) rename include/os/freebsd/{spl => zfs}/sys/trace_zfs.h (100%) rename include/os/freebsd/{spl/sys/sdt.h => zfs/sys/zfs_debug_os.h} (92%) create mode 100644 include/os/linux/zfs/sys/zfs_debug_os.h delete mode 100644 lib/libspl/include/sys/trace_spl.h create mode 100644 lib/libzpool/include/sys/zfs_debug_os.h 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/zfs_context.h b/include/sys/zfs_context.h index 4be22835d2a2..aeac81df9ea8 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -109,7 +109,6 @@ extern "C" { #include #include #include -#include #include #include 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/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 202f15944762..e68742409839 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -69,7 +69,6 @@ libspl_sys_HEADERS = \ %D%/sys/time.h \ %D%/sys/timer.h \ %D%/sys/trace.h \ - %D%/sys/trace_spl.h \ %D%/sys/tsd.h \ %D%/sys/tunables.h \ %D%/sys/types.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/libzpool/include/Makefile.am b/lib/libzpool/include/Makefile.am index 54d10e62358b..420b6f64666b 100644 --- a/lib/libzpool/include/Makefile.am +++ b/lib/libzpool/include/Makefile.am @@ -3,4 +3,5 @@ libzpool_sys_HEADERS = \ %D%/sys/abd_os.h \ %D%/sys/abd_impl_os.h \ %D%/sys/trace_zfs.h \ - %D%/sys/zfs_context_os.h + %D%/sys/zfs_context_os.h \ + %D%/sys/zfs_debug_os.h diff --git a/lib/libzpool/include/sys/trace_zfs.h b/lib/libzpool/include/sys/trace_zfs.h index 87ed5ad3c3be..d9639d27b60e 100644 --- a/lib/libzpool/include/sys/trace_zfs.h +++ b/lib/libzpool/include/sys/trace_zfs.h @@ -1,24 +1 @@ -/* 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 +/* keep me */ diff --git a/lib/libzpool/include/sys/zfs_debug_os.h b/lib/libzpool/include/sys/zfs_debug_os.h new file mode 100644 index 000000000000..b59165a6c903 --- /dev/null +++ b/lib/libzpool/include/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 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/scripts/spdxcheck.pl b/scripts/spdxcheck.pl index 1b3dd639318f..59300ea860f9 100755 --- a/scripts/spdxcheck.pl +++ b/scripts/spdxcheck.pl @@ -128,7 +128,6 @@ include/os/freebsd/zfs/sys/zpl.h include/os/linux/kernel/linux/page_compat.h lib/libspl/include/sys/string.h - lib/libspl/include/sys/trace_spl.h lib/libzdb/libzdb.c lib/libzpool/include/sys/trace_zfs.h module/lua/setjmp/setjmp.S From b6ed0ee3f5f82f163db2a40fe910fa8af0ab2353 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 8 Nov 2025 15:04:51 +1100 Subject: [PATCH 50/57] libzpool: add BE_POSIX_VENDOR for userspace bootenv This is mostly a placeholder; it's not actually clear if a boot environment makes any sense for userspace. Still, "posix" is the likely future name of libzpool as a port, and this define is mandatory, so lets roll with it for now. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- include/sys/zfs_bootenv.h | 1 + lib/libzpool/include/Makefile.am | 1 + lib/libzpool/include/sys/zfs_bootenv_os.h | 39 +++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 lib/libzpool/include/sys/zfs_bootenv_os.h 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/lib/libzpool/include/Makefile.am b/lib/libzpool/include/Makefile.am index 420b6f64666b..6cfa2d5ce089 100644 --- a/lib/libzpool/include/Makefile.am +++ b/lib/libzpool/include/Makefile.am @@ -3,5 +3,6 @@ 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/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 */ From 65ebc1f808bd1d6295afbe4c4e4a976420a206d2 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 30 Oct 2025 17:49:18 -0700 Subject: [PATCH 51/57] libzpool: remove global libzpool includes Only include the zfs headers where they're currently required to compile. Unfortunately, including zfs_ioctl.h in user space pulls in a bunch of internal zfs headers as a side effect. We'll need to move these structures in to a new shared header to avoid this. We should not need to add the LIBZPOOL_CPPFLAGS when building the zed, zinject, zpool, libzfs, ior libzfs_core. Signed-off-by: Brian Behlendorf Signed-off-by: Rob Norris --- lib/libspl/taskq.c | 7 ++++++- lib/libzfs/libzfs_crypto.c | 1 - lib/libzpool/Makefile.am | 1 - tests/zfs-tests/cmd/Makefile.am | 1 - tests/zfs-tests/cmd/ereports.c | 3 ++- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/libspl/taskq.c b/lib/libspl/taskq.c index 0457de21fa18..075d188930c1 100644 --- a/lib/libspl/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/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/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 9921c595e0d7..b86039a71de7 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -4,7 +4,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 diff --git a/tests/zfs-tests/cmd/Makefile.am b/tests/zfs-tests/cmd/Makefile.am index 85c3cf3c35a8..8d645248f8a2 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 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. From cc514fdc293555dae319c7f5989663902ac625fe Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 30 Oct 2025 17:41:25 -0700 Subject: [PATCH 52/57] icp: remove global icp includes Only include the required icp headers. There's no need to include sys/zfs_context.h and pull in all of the zfs headers. Signed-off-by: Brian Behlendorf Signed-off-by: Rob Norris --- config/Rules.am | 1 - include/sys/crypto/common.h | 2 ++ lib/libicp/Makefile.am | 3 +++ module/icp/spi/kcf_spi.c | 1 - 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/config/Rules.am b/config/Rules.am index 9c0714c82513..ecc7ab23cd75 100644 --- a/config/Rules.am +++ b/config/Rules.am @@ -8,7 +8,6 @@ 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/libzpool/include 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/lib/libicp/Makefile.am b/lib/libicp/Makefile.am index 23adba10bc44..b83ec461fda2 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 = \ 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 From 98afdf22a80fefb3fc1a08caf20bd5783079007b Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 30 Oct 2025 18:04:15 -0700 Subject: [PATCH 53/57] zfs_context: remove duplicate includes Signed-off-by: Brian Behlendorf Signed-off-by: Rob Norris --- include/sys/zfs_context.h | 2 -- scripts/spdxcheck.pl | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index aeac81df9ea8..5e571d497642 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -127,8 +127,6 @@ extern "C" { #include #include #include -#include -#include #include diff --git a/scripts/spdxcheck.pl b/scripts/spdxcheck.pl index 59300ea860f9..e1af3150bccd 100755 --- a/scripts/spdxcheck.pl +++ b/scripts/spdxcheck.pl @@ -124,7 +124,7 @@ 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/sys/string.h From 8afd140f71b4a89bbcceb84de771a19415bf0950 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 8 Nov 2025 18:04:29 +1100 Subject: [PATCH 54/57] libzpool: add zfs_impl.c, remove from libicp This isn't used by libicp directly, but is by some clients, and relies on headers specific to the zfs module, which makes using it difficult otherwise. Also switch the checksum tests over to use libzpool, so they can get access to it. That's not exactly what we want in the long term, but the icp and zfs modules have a complicated relationship so this will do for now. Signed-off-by: Rob Norris Sponsored-by: https://despairlabs.com/sponsor/ --- lib/libicp/Makefile.am | 3 +-- lib/libzpool/Makefile.am | 1 + tests/zfs-tests/cmd/Makefile.am | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/libicp/Makefile.am b/lib/libicp/Makefile.am index b83ec461fda2..a8937e60b770 100644 --- a/lib/libicp/Makefile.am +++ b/lib/libicp/Makefile.am @@ -38,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/libzpool/Makefile.am b/lib/libzpool/Makefile.am index b86039a71de7..890c5ccc08d1 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -180,6 +180,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/tests/zfs-tests/cmd/Makefile.am b/tests/zfs-tests/cmd/Makefile.am index 8d645248f8a2..b4efefdb7ab7 100644 --- a/tests/zfs-tests/cmd/Makefile.am +++ b/tests/zfs-tests/cmd/Makefile.am @@ -116,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) From cfa4e52d46cca8bd33cc4f4a07bd24785e4a9e9e Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Tue, 11 Nov 2025 11:16:30 +1100 Subject: [PATCH 55/57] libspl: hide global data objects Currently libspl is a static archive that is linked into multiple shared objects, which then re-export its symbols. We intend to fix this soon. For the moment though, most programs shipped with OpenZFS depend on two or more of these shared objects, and see the same symbols twice. For functions this is not a problem, as they do not have any mutable state and so the linker can simply select the first one and use that for all. For global data objects however, each shared object will have direct (non-relocatable) references to its own instance of the symbol, such that changes on one will not necessarily be seen by the other. While this shouldn't be a problem in practice as these reexported interfaces are not supposed to be used, they are technically undefined behaviour in C (C17 6.9.2) and are reported by ASAN as a violation of C++'s "One Definition Rule". To fix this, we hide these globals inside their compilation units, and add access functions and macros as appropriate to preserve the existing API (though not ABI). Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- cmd/zstream/zstream_redup.c | 4 ++-- cmd/ztest.c | 19 ++++------------- lib/libspl/include/sys/misc.h | 3 --- lib/libspl/include/sys/systm.h | 4 +++- lib/libspl/include/sys/taskq.h | 7 +++++-- lib/libspl/include/sys/thread.h | 6 ++---- lib/libspl/libspl.c | 13 +++++++++--- lib/libspl/random.c | 15 +++++++++---- lib/libspl/taskq.c | 37 ++++++++++++++++++--------------- lib/libspl/thread.c | 2 +- 10 files changed, 58 insertions(+), 52 deletions(-) diff --git a/cmd/zstream/zstream_redup.c b/cmd/zstream/zstream_redup.c index 0e18c52496fd..c1cb6d4d3ad7 100644 --- a/cmd/zstream/zstream_redup.c +++ b/cmd/zstream/zstream_redup.c @@ -191,9 +191,9 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose) #ifdef _ILP32 uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20; #else - uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); + uint64_t physbytes = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); uint64_t max_rde_size = - MAX((physmem * MAX_RDT_PHYSMEM_PERCENT) / 100, + MAX((physbytes * MAX_RDT_PHYSMEM_PERCENT) / 100, SMALLEST_POSSIBLE_MAX_RDT_MB << 20); #endif diff --git a/cmd/ztest.c b/cmd/ztest.c index 54b4fdb4c48a..d94451906aa0 100644 --- a/cmd/ztest.c +++ b/cmd/ztest.c @@ -140,9 +140,9 @@ #include #include #include +#include static int ztest_fd_data = -1; -static int ztest_fd_rand = -1; typedef struct ztest_shared_hdr { uint64_t zh_hdr_size; @@ -903,13 +903,10 @@ ztest_random(uint64_t range) { uint64_t r; - ASSERT3S(ztest_fd_rand, >=, 0); - if (range == 0) return (0); - if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r)) - fatal(B_TRUE, "short read from /dev/urandom"); + random_get_pseudo_bytes((uint8_t *)&r, sizeof (r)); return (r % range); } @@ -8146,10 +8143,8 @@ ztest_raidz_expand_run(ztest_shared_t *zs, spa_t *spa) /* Setup a 1 MiB buffer of random data */ uint64_t bufsize = 1024 * 1024; void *buffer = umem_alloc(bufsize, UMEM_NOFAIL); + random_get_pseudo_bytes((uint8_t *)&buffer, bufsize); - if (read(ztest_fd_rand, buffer, bufsize) != bufsize) { - fatal(B_TRUE, "short read from /dev/urandom"); - } /* * Put some data in the pool and then attach a vdev to initiate * reflow. @@ -8955,13 +8950,7 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } - /* - * Force random_get_bytes() to use /dev/urandom in order to prevent - * ztest from needlessly depleting the system entropy pool. - */ - random_path = "/dev/urandom"; - ztest_fd_rand = open(random_path, O_RDONLY | O_CLOEXEC); - ASSERT3S(ztest_fd_rand, >=, 0); + libspl_init(); if (!fd_data_str) { process_options(argc, argv); diff --git a/lib/libspl/include/sys/misc.h b/lib/libspl/include/sys/misc.h index 8f2f5f9332e7..171bbc1de798 100644 --- a/lib/libspl/include/sys/misc.h +++ b/lib/libspl/include/sys/misc.h @@ -31,9 +31,6 @@ #include -extern const char *random_path; -extern const char *urandom_path; - /* * Hostname information */ diff --git a/lib/libspl/include/sys/systm.h b/lib/libspl/include/sys/systm.h index 94fcfdd2a303..f984125c3315 100644 --- a/lib/libspl/include/sys/systm.h +++ b/lib/libspl/include/sys/systm.h @@ -29,6 +29,8 @@ #ifndef _LIBSPL_SYS_SYSTM_H #define _LIBSPL_SYS_SYSTM_H -extern uint64_t physmem; +uint64_t libspl_physmem(void); + +#define physmem libspl_physmem() #endif diff --git a/lib/libspl/include/sys/taskq.h b/lib/libspl/include/sys/taskq.h index 63238734b4fd..fbe3f388c05f 100644 --- a/lib/libspl/include/sys/taskq.h +++ b/lib/libspl/include/sys/taskq.h @@ -86,8 +86,11 @@ typedef struct taskq { #define TASKQID_INVALID ((taskqid_t)0) -extern taskq_t *system_taskq; -extern taskq_t *system_delay_taskq; +extern taskq_t *_system_taskq(void); +extern taskq_t *_system_delay_taskq(void); + +#define system_taskq _system_taskq() +#define system_delay_taskq _system_delay_taskq() extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t, diff --git a/lib/libspl/include/sys/thread.h b/lib/libspl/include/sys/thread.h index a5108a03d45f..6390c5bfd863 100644 --- a/lib/libspl/include/sys/thread.h +++ b/lib/libspl/include/sys/thread.h @@ -58,11 +58,9 @@ typedef pthread_t kthread_t; #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; +typedef void (proc_t)(void); +extern void p0(void); -extern struct proc p0; #define curproc (&p0) #define PS_NONE -1 diff --git a/lib/libspl/libspl.c b/lib/libspl/libspl.c index 63e948bc2829..208b3e428536 100644 --- a/lib/libspl/libspl.c +++ b/lib/libspl/libspl.c @@ -31,11 +31,18 @@ #include #include #include +#include #include #include "libspl_impl.h" -uint64_t physmem; -struct utsname hw_utsname; +static uint64_t hw_physmem = 0; +static struct utsname hw_utsname = {}; + +uint64_t +libspl_physmem(void) +{ + return (hw_physmem); +} utsname_t * utsname(void) @@ -46,7 +53,7 @@ utsname(void) void libspl_init(void) { - physmem = sysconf(_SC_PHYS_PAGES); + hw_physmem = sysconf(_SC_PHYS_PAGES); VERIFY0(uname(&hw_utsname)); diff --git a/lib/libspl/random.c b/lib/libspl/random.c index 0392737908fe..30281504f599 100644 --- a/lib/libspl/random.c +++ b/lib/libspl/random.c @@ -32,15 +32,22 @@ #include #include "libspl_impl.h" -const char *random_path = "/dev/random"; -const char *urandom_path = "/dev/urandom"; +#define RANDOM_PATH "/dev/random" +#define 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); + /* Handle multiple calls. */ + if (random_fd != -1) { + ASSERT3U(urandom_fd, !=, -1); + return; + } + + VERIFY((random_fd = open(RANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1); + VERIFY((urandom_fd = open(URANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1); } void diff --git a/lib/libspl/taskq.c b/lib/libspl/taskq.c index 075d188930c1..043f70225551 100644 --- a/lib/libspl/taskq.c +++ b/lib/libspl/taskq.c @@ -36,9 +36,20 @@ #include #include -int taskq_now; -taskq_t *system_taskq; -taskq_t *system_delay_taskq; +static taskq_t *__system_taskq = NULL; +static taskq_t *__system_delay_taskq = NULL; + +taskq_t +*_system_taskq(void) +{ + return (__system_taskq); +} + +taskq_t +*_system_delay_taskq(void) +{ + return (__system_delay_taskq); +} static pthread_key_t taskq_tsd; @@ -111,11 +122,6 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags) { taskq_ent_t *t; - if (taskq_now) { - func(arg); - return (1); - } - mutex_enter(&tq->tq_lock); ASSERT(tq->tq_flags & TASKQ_ACTIVE); if ((t = task_alloc(tq, tqflags)) == NULL) { @@ -378,9 +384,6 @@ taskq_member(taskq_t *tq, kthread_t *t) { int i; - if (taskq_now) - return (1); - for (i = 0; i < tq->tq_nthreads; i++) if (tq->tq_threadlist[i] == t) return (1); @@ -405,18 +408,18 @@ void system_taskq_init(void) { VERIFY0(pthread_key_create(&taskq_tsd, NULL)); - system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512, + __system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE); - system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4, + __system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4, 512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE); } void system_taskq_fini(void) { - taskq_destroy(system_taskq); - system_taskq = NULL; /* defensive */ - taskq_destroy(system_delay_taskq); - system_delay_taskq = NULL; + taskq_destroy(__system_taskq); + __system_taskq = NULL; /* defensive */ + taskq_destroy(__system_delay_taskq); + __system_delay_taskq = NULL; VERIFY0(pthread_key_delete(taskq_tsd)); } diff --git a/lib/libspl/thread.c b/lib/libspl/thread.c index 17c36c754621..f00e0a01a06b 100644 --- a/lib/libspl/thread.c +++ b/lib/libspl/thread.c @@ -32,7 +32,7 @@ #include /* this only exists to have its address taken */ -struct proc p0; +void p0(void) {} /* * ========================================================================= From b489c698d06f2b6bcd01ebbc691d0fbd8cf1f99a Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Tue, 11 Nov 2025 11:16:30 +1100 Subject: [PATCH 56/57] libspl/random: add switch to force pseudo-random numbers for all calls ztest wants to force all kernel random calls to use the pseudo-random generator (/dev/urandom), to avoid depleting the system entropy pool just for testing. Up until the previous commit, it did this by switching the path that the libzpool (now libspl) random API would use to get random data from; that is, it took advantage of an implementation detail. Now that that hole is closed to it, we need another method. This commit introduces that; a simple API call to enable/disable "force pseudo" mode. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- cmd/ztest.c | 6 ++++++ lib/libspl/include/sys/random.h | 2 ++ lib/libspl/random.c | 10 ++++++++++ 3 files changed, 18 insertions(+) diff --git a/cmd/ztest.c b/cmd/ztest.c index d94451906aa0..dc8ac85b6991 100644 --- a/cmd/ztest.c +++ b/cmd/ztest.c @@ -8952,6 +8952,12 @@ main(int argc, char **argv) libspl_init(); + /* + * Force random_get_bytes() to use /dev/urandom in order to prevent + * ztest from needlessly depleting the system entropy pool. + */ + random_force_pseudo(B_TRUE); + if (!fd_data_str) { process_options(argc, argv); diff --git a/lib/libspl/include/sys/random.h b/lib/libspl/include/sys/random.h index 27f2d4e3a684..d11580829ed2 100644 --- a/lib/libspl/include/sys/random.h +++ b/lib/libspl/include/sys/random.h @@ -32,6 +32,8 @@ extern int random_get_bytes(uint8_t *ptr, size_t len); extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len); +extern void random_force_pseudo(boolean_t onoff); + static __inline__ uint32_t random_in_range(uint32_t range) { diff --git a/lib/libspl/random.c b/lib/libspl/random.c index 30281504f599..c6f0ee7ae0f7 100644 --- a/lib/libspl/random.c +++ b/lib/libspl/random.c @@ -37,6 +37,8 @@ static int random_fd = -1, urandom_fd = -1; +static boolean_t force_pseudo = B_FALSE; + void random_init(void) { @@ -60,6 +62,12 @@ random_fini(void) urandom_fd = -1; } +void +random_force_pseudo(boolean_t onoff) +{ + force_pseudo = onoff; +} + static int random_get_bytes_common(uint8_t *ptr, size_t len, int fd) { @@ -81,6 +89,8 @@ random_get_bytes_common(uint8_t *ptr, size_t len, int fd) int random_get_bytes(uint8_t *ptr, size_t len) { + if (force_pseudo) + return (random_get_pseudo_bytes(ptr, len)); return (random_get_bytes_common(ptr, len, random_fd)); } From b0993ca6b660b0f1c132ce62001f36ac166a41b3 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Fri, 7 Nov 2025 14:11:12 +1100 Subject: [PATCH 57/57] lib: update ABI meta following libspl changes In theory they should not have resulted in a change. In practice, the way visibility is set up currently means that many of our convenience libraries will "leak through" into the available symbols in our public libraries. In this commit, we're seeing all the new symbols in libspl through libuutil, libzfs and libzfs_core. Importantly, none have been removed, so consumers of these libraries will not notice. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libuutil/libuutil.abi | 1337 +++++++++++++++++++++++++++---- lib/libzfs/libzfs.abi | 859 +++++++++++++++++++- lib/libzfs_core/libzfs_core.abi | 1070 ++++++++++++++++++++++++- 3 files changed, 3060 insertions(+), 206 deletions(-) diff --git a/lib/libuutil/libuutil.abi b/lib/libuutil/libuutil.abi index 2a740afa07ca..001b35ad3490 100644 --- a/lib/libuutil/libuutil.abi +++ b/lib/libuutil/libuutil.abi @@ -6,6 +6,8 @@ + + @@ -144,6 +146,19 @@ + + + + + + + + + + + + + @@ -151,8 +166,21 @@ + + + + + + + + + + + + + @@ -178,10 +206,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -248,6 +318,7 @@ + @@ -616,7 +687,6 @@ - @@ -635,8 +705,6 @@ - - @@ -800,6 +868,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -809,6 +1101,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -921,7 +1383,6 @@ - @@ -971,6 +1432,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -981,7 +1475,6 @@ - @@ -992,235 +1485,749 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + + + + + + + + + - + + - - - - - - + + + + - - + + + + + + + + + + + + - - - - - + + - + - - - - - - - - - - - - - + + - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - - - - + - + + - - - - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + - - + + - - - - - - - - - - + + + + + + + + + + + + + + - + - - + + + + + + - - - + + - - - - - + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + + - - - + - - - - - - - - - - + + + + + + - @@ -1351,8 +2358,6 @@ - - @@ -2334,10 +3339,6 @@ - - - - diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi index f988d27a286a..0acc5fc9f47e 100644 --- a/lib/libzfs/libzfs.abi +++ b/lib/libzfs/libzfs.abi @@ -15,6 +15,8 @@ + + @@ -160,6 +162,19 @@ + + + + + + + + + + + + + @@ -195,9 +210,22 @@ + + + + + + + + + + + + + @@ -243,10 +271,32 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -254,10 +304,29 @@ + + + + + + + + + + + + + + + + + + + @@ -270,6 +339,7 @@ + @@ -477,6 +547,7 @@ + @@ -1319,6 +1390,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1328,6 +1499,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1458,6 +1783,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1473,6 +1831,486 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1808,10 +2646,6 @@ - - - - @@ -1915,10 +2749,6 @@ - - - - @@ -2639,9 +3469,6 @@ - - - @@ -2658,6 +3485,9 @@ + + + @@ -3286,7 +4116,6 @@ - @@ -3588,6 +4417,7 @@ + @@ -6250,6 +7080,7 @@ + @@ -7988,6 +8819,10 @@ + + + + diff --git a/lib/libzfs_core/libzfs_core.abi b/lib/libzfs_core/libzfs_core.abi index 263cad045f7a..f94821219516 100644 --- a/lib/libzfs_core/libzfs_core.abi +++ b/lib/libzfs_core/libzfs_core.abi @@ -7,6 +7,8 @@ + + @@ -127,6 +129,19 @@ + + + + + + + + + + + + + @@ -134,8 +149,21 @@ + + + + + + + + + + + + + @@ -218,32 +246,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - @@ -617,7 +673,6 @@ - @@ -798,6 +853,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -807,6 +1079,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -918,7 +1372,6 @@ - @@ -967,6 +1420,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -977,7 +1483,6 @@ - @@ -1149,14 +1654,273 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1165,6 +1929,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1297,8 +2316,6 @@ - - @@ -1709,6 +2726,7 @@ + @@ -2342,10 +3360,10 @@ - + - +