Notable upstream pull request merges:
 #17477 02fdd26e5 Add knob to disable slow io notifications
 #17792 d0294aa75 Update dnode_next_offset_level to accept blkid instead
                  of offset
 #17824 8c225ff1b Fix gang write late_arrival bug
 #17861 -multiple Lift userspace definitions out of zfs_context.h
 #17872 dcada084b Pass flags to more DMU write/hold functions
 #17875 ec268cdf9 Fix caching of DDT log and BRT
 #17875 ea125eeb5 BRT: Round bv_entcount up to BRT_BLOCKSIZE
 #17877 6cfc3dba9 Cleanup ZIO_FLAG_IO_RETRY vs TRYHARD usage
 #17885 e63d026b9 cmd/zpool cstyle issues
 #17890 b4f073b5a Add BRT support to zpool prefetch command
 #17903 baefe098e ZIO: Set minimum number of free issue threads to 32
 #17906 6e12f0bd7 spa_misc: add an API for spa_namespace_lock
 #17908 e26b9fc87 FreeBSD: Add support for _PC_CASE_INSENSITIVE
 #17911 -multiple Update library ABI versions for v2.4.0
 #17915 8aaed7dc4 BRT: Fix ranges to blocks conversion math
 #17916 cc5cae547 BRT: Increase block size from 4KB to 8KB
 #17921 72b2a9571 ZAP: Remove dmu_object_info_from_dnode() call

Obtained from:	OpenZFS
OpenZFS commit:	e63d026b91
This commit is contained in:
Martin Matuska
2025-11-17 17:11:32 +01:00
190 changed files with 6916 additions and 3567 deletions
@@ -7,7 +7,7 @@
- the *last* commit message contains 'ZFS-CI-Type: quick'
or if (heuristics):
- the files changed are not in the list of specified directories, and
- all commit messages do not contain 'ZFS-CI-Type: full'
- all commit messages do not contain 'ZFS-CI-Type: (full|linux|freebsd)'
Otherwise prints "full".
"""
@@ -70,7 +70,7 @@ def output_type(type, reason):
for line in last_commit_message_raw.stdout.decode().splitlines():
if line.strip().lower() == 'zfs-ci-type: quick':
output_type('quick', f'explicitly requested by HEAD commit {head}')
output_type('quick', f'requested by HEAD commit {head}')
# check all commit messages
all_commit_message_raw = subprocess.run([
@@ -83,8 +83,12 @@ def output_type(type, reason):
for line in all_commit_message:
if line.startswith('ZFS-CI-Commit:'):
commit_ref = line.lstrip('ZFS-CI-Commit:').rstrip()
if line.strip().lower() == 'zfs-ci-type: freebsd':
output_type('freebsd', f'requested by commit {commit_ref}')
if line.strip().lower() == 'zfs-ci-type: linux':
output_type('linux', f'requested by commit {commit_ref}')
if line.strip().lower() == 'zfs-ci-type: full':
output_type('full', f'explicitly requested by commit {commit_ref}')
output_type('full', f'requested by commit {commit_ref}')
# check changed files
changed_files_raw = subprocess.run([
@@ -47,16 +47,15 @@ case "$OS" in
OSNAME="Archlinux"
URL="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"
;;
centos-stream10)
OSNAME="CentOS Stream 10"
# TODO: #16903 Overwrite OSv to stream9 for virt-install until it's added to osinfo
OSv="centos-stream9"
URL="https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2"
;;
centos-stream9)
OSNAME="CentOS Stream 9"
URL="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
;;
centos-stream10)
OSNAME="CentOS Stream 10"
OSv="centos-stream9"
URL="https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2"
;;
debian11)
OSNAME="Debian 11"
URL="https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2"
@@ -83,6 +82,11 @@ case "$OS" in
OSv="fedora-unknown"
URL="https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2"
;;
fedora43)
OSNAME="Fedora 43"
OSv="fedora-unknown"
URL="https://download.fedoraproject.org/pub/fedora/linux/releases/43/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2"
;;
freebsd13-5r)
FreeBSD="13.5-RELEASE"
OSNAME="FreeBSD $FreeBSD"
@@ -95,8 +99,8 @@ case "$OS" in
FreeBSD="14.2-RELEASE"
OSNAME="FreeBSD $FreeBSD"
OSv="freebsd14.0"
KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
URLxz="$FREEBSD_REL/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI.raw.xz"
KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
;;
freebsd14-3r)
FreeBSD="14.3-RELEASE"
@@ -120,8 +124,8 @@ case "$OS" in
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz"
;;
freebsd15-0c)
FreeBSD="15.0-ALPHA4"
freebsd15-0s)
FreeBSD="15.0-STABLE"
OSNAME="FreeBSD $FreeBSD"
OSv="freebsd14.0"
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
@@ -52,7 +52,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora41', 'fedora42']
os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora41', 'fedora42', 'fedora43']
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
+24 -14
View File
@@ -29,24 +29,34 @@ jobs:
- name: Generate OS config and CI type
id: os
run: |
FULL_OS='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora41", "fedora42", "freebsd13-5r", "freebsd14-3s", "freebsd15-0c", "ubuntu22", "ubuntu24"]'
QUICK_OS='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd14-3s", "ubuntu24"]'
ci_type="default"
# determine CI type when running on PR
ci_type="full"
if ${{ github.event_name == 'pull_request' }}; then
head=${{ github.event.pull_request.head.sha }}
base=${{ github.event.pull_request.base.sha }}
ci_type=$(python3 .github/workflows/scripts/generate-ci-type.py $head $base)
fi
if [ "$ci_type" == "quick" ]; then
os_selection="$QUICK_OS"
else
os_selection="$FULL_OS"
fi
case "$ci_type" in
quick)
os_selection='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd15-0s", "ubuntu24"]'
;;
linux)
os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "debian13", "fedora41", "fedora42", "fedora43", "ubuntu22", "ubuntu24"]'
;;
freebsd)
os_selection='["freebsd13-5r", "freebsd14-2r", "freebsd14-3r", "freebsd13-5s", "freebsd14-3s", "freebsd15-0s", "freebsd16-0c"]'
;;
*)
# default list
os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora42", "fedora43", "freebsd14-3r", "freebsd15-0s", "freebsd16-0c", "ubuntu22", "ubuntu24"]'
;;
esac
if ${{ github.event.inputs.fedora_kernel_ver != '' }}; then
# They specified a custom kernel version for Fedora. Use only
# Fedora runners.
# They specified a custom kernel version for Fedora.
# Use only Fedora runners.
os_json=$(echo ${os_selection} | jq -c '[.[] | select(startswith("fedora"))]')
else
# Normal case
@@ -62,13 +72,13 @@ jobs:
strategy:
fail-fast: false
matrix:
# rhl: almalinux8, almalinux9, centos-stream9, fedora4x
# rhl: almalinux8, almalinux9, centos-streamX, fedora4x
# debian: debian12, debian13, ubuntu22, ubuntu24
# misc: archlinux, tumbleweed
# FreeBSD variants of 2025-06:
# FreeBSD variants of november 2025:
# FreeBSD Release: freebsd13-5r, freebsd14-2r, freebsd14-3r
# FreeBSD Stable: freebsd13-5s, freebsd14-3s
# FreeBSD Current: freebsd15-0c, freebsd16-0c
# FreeBSD Stable: freebsd13-5s, freebsd14-3s, freebsd15-0s
# FreeBSD Current: freebsd16-0c
os: ${{ fromJson(needs.test-config.outputs.test_os) }}
runs-on: ubuntu-24.04
steps:
+1 -1
View File
@@ -10,7 +10,7 @@ This repository contains the code for running OpenZFS on Linux and FreeBSD.
# Official Resources
* [Documentation](https://openzfs.github.io/openzfs-docs/) - for using and developing this repo
* [ZoL Site](https://zfsonlinux.org) - Linux release info & links
* [ZoL site](https://zfsonlinux.org) - Linux release info & links
* [Mailing lists](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/Mailing%20Lists.html)
* [OpenZFS site](https://openzfs.org/) - for conference videos and info on other platforms (illumos, OSX, Windows, etc)
+1 -60
View File
@@ -1,62 +1,3 @@
#!/bin/sh
[ "${0%/*}" = "$0" ] || cd "${0%/*}" || exit
# %reldir%/%canon_reldir% (%D%/%C%) only appeared in automake 1.14, but RHEL/CentOS 7 has 1.13.4
# This is an (overly) simplistic preprocessor that papers around this for the duration of the generation step,
# and can be removed once support for CentOS 7 is dropped
automake --version | awk '{print $NF; exit}' | (
IFS=. read -r AM_MAJ AM_MIN _
[ "$AM_MAJ" -gt 1 ] || [ "$AM_MIN" -ge 14 ]
) || {
process_root() {
root="$1"; shift
grep -q '%[CD]%' "$root/Makefile.am" || return
find "$root" -name Makefile.am "$@" | while read -r dir; do
dir="${dir%/Makefile.am}"
grep -q '%[CD]%' "$dir/Makefile.am" || continue
reldir="${dir#"$root"}"
reldir="${reldir#/}"
canon_reldir="$(printf '%s' "$reldir" | tr -C 'a-zA-Z0-9@_' '_')"
reldir_slash="$reldir/"
canon_reldir_slash="${canon_reldir}_"
[ -z "$reldir" ] && reldir_slash=
[ -z "$reldir" ] && canon_reldir_slash=
echo "$dir/Makefile.am" >&3
sed -i~ -e "s:%D%/:$reldir_slash:g" -e "s:%D%:$reldir:g" \
-e "s:%C%_:$canon_reldir_slash:g" -e "s:%C%:$canon_reldir:g" "$dir/Makefile.am"
done 3>>"$substituted_files"
}
rollback() {
while read -r f; do
mv "$f~" "$f"
done < "$substituted_files"
rm -f "$substituted_files"
}
echo "Automake <1.14; papering over missing %reldir%/%canon_reldir% support" >&2
substituted_files="$(mktemp)"
trap rollback EXIT
roots="$(sed '/Makefile$/!d;/module/d;s:^\s*:./:;s:/Makefile::;/^\.$/d' configure.ac)"
IFS="
"
for root in $roots; do
root="${root#./}"
process_root "$root"
done
set -f
# shellcheck disable=SC2086,SC2046
process_root . $(printf '!\n-path\n%s/*\n' $roots)
}
autoreconf -fiv && rm -rf autom4te.cache
autoreconf -fiv "$(dirname "$0")" && rm -rf "$(dirname "$0")"/autom4te.cache
@@ -33,6 +33,7 @@
#include <sys/vdev_raidz_impl.h>
#include <assert.h>
#include <stdio.h>
#include <libzpool.h>
#include "raidz_test.h"
static int *rand_data;
+5 -4
View File
@@ -89,6 +89,7 @@
#include <sys/zstd/zstd.h>
#include <sys/backtrace.h>
#include <libzpool.h>
#include <libnvpair.h>
#include <libzutil.h>
#include <libzfs_core.h>
@@ -7899,11 +7900,11 @@ zdb_set_skip_mmp(char *target)
* Disable the activity check to allow examination of
* active pools.
*/
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
if ((spa = spa_lookup(target)) != NULL) {
spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP;
}
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
}
#define BOGUS_SUFFIX "_CHECKPOINTED_UNIVERSE"
@@ -10022,13 +10023,13 @@ main(int argc, char **argv)
* try opening the pool after clearing the
* log state.
*/
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
if ((spa = spa_lookup(target)) != NULL &&
spa->spa_log_state == SPA_LOG_MISSING) {
spa->spa_log_state = SPA_LOG_CLEAR;
error = 0;
}
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
if (!error) {
error = spa_open_rewind(target, &spa,
+28 -8
View File
@@ -145,11 +145,11 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
switch (zpc->zpc_op) {
case ZFS_PROJECT_OP_LIST:
(void) printf("%5u %c %s\n", fsx.fsx_projid,
(fsx.fsx_xflags & ZFS_PROJINHERIT_FL) ? 'P' : '-', name);
(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) ? 'P' : '-', name);
goto out;
case ZFS_PROJECT_OP_CHECK:
if (fsx.fsx_projid == zpc->zpc_expected_projid &&
fsx.fsx_xflags & ZFS_PROJINHERIT_FL)
fsx.fsx_xflags & FS_XFLAG_PROJINHERIT)
goto out;
if (!zpc->zpc_newline) {
@@ -164,29 +164,30 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
"(%u/%u)\n", name, fsx.fsx_projid,
(uint32_t)zpc->zpc_expected_projid);
if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL))
if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT))
(void) printf("%s - project inherit flag is not set\n",
name);
goto out;
case ZFS_PROJECT_OP_CLEAR:
if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL) &&
if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) &&
(zpc->zpc_keep_projid ||
fsx.fsx_projid == ZFS_DEFAULT_PROJID))
goto out;
fsx.fsx_xflags &= ~ZFS_PROJINHERIT_FL;
fsx.fsx_xflags &= ~FS_XFLAG_PROJINHERIT;
if (!zpc->zpc_keep_projid)
fsx.fsx_projid = ZFS_DEFAULT_PROJID;
break;
case ZFS_PROJECT_OP_SET:
if (fsx.fsx_projid == zpc->zpc_expected_projid &&
(!zpc->zpc_set_flag || fsx.fsx_xflags & ZFS_PROJINHERIT_FL))
(!zpc->zpc_set_flag ||
fsx.fsx_xflags & FS_XFLAG_PROJINHERIT))
goto out;
fsx.fsx_projid = zpc->zpc_expected_projid;
if (zpc->zpc_set_flag)
fsx.fsx_xflags |= ZFS_PROJINHERIT_FL;
fsx.fsx_xflags |= FS_XFLAG_PROJINHERIT;
break;
default:
ASSERT(0);
@@ -194,11 +195,30 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
}
ret = ioctl(fd, ZFS_IOC_FSSETXATTR, &fsx);
if (ret)
if (ret) {
(void) fprintf(stderr,
gettext("failed to set xattr for %s: %s\n"),
name, strerror(errno));
if (errno == ENOTSUP) {
char *kver = zfs_version_kernel();
/*
* Special case: a module/userspace version mismatch can
* return ENOTSUP due to us fixing the XFLAGs bits in
* #17884. In that case give a hint to the user that
* they should take action to make the versions match.
*/
if (strcmp(kver, ZFS_META_ALIAS) != 0) {
fprintf(stderr,
gettext("Warning: The zfs module version "
"(%s) and userspace\nversion (%s) do not "
"match up. This may be the\ncause of the "
"\"Operation not supported\" error.\n"),
kver, ZFS_META_ALIAS);
}
}
}
out:
close(fd);
return (ret);
+1
View File
@@ -55,6 +55,7 @@
#include <zfeature_common.h>
#include <libzutil.h>
#include <sys/metaslab_impl.h>
#include <libzpool.h>
static importargs_t g_importargs;
static char *g_pool;
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -195,7 +195,7 @@ is_shorthand_path(const char *arg, char *path, size_t path_size,
return (0);
}
strlcpy(path, arg, path_size);
(void) strlcpy(path, arg, path_size);
memset(statbuf, 0, sizeof (*statbuf));
*wholedisk = B_FALSE;
@@ -308,7 +308,7 @@ make_leaf_vdev(const char *arg, boolean_t is_primary, uint64_t ashift)
}
/* After whole disk check restore original passed path */
strlcpy(path, arg, sizeof (path));
(void) strlcpy(path, arg, sizeof (path));
} else if (zpool_is_draid_spare(arg)) {
if (!is_primary) {
(void) fprintf(stderr,
@@ -318,7 +318,7 @@ make_leaf_vdev(const char *arg, boolean_t is_primary, uint64_t ashift)
}
wholedisk = B_TRUE;
strlcpy(path, arg, sizeof (path));
(void) strlcpy(path, arg, sizeof (path));
type = VDEV_TYPE_DRAID_SPARE;
} else {
err = is_shorthand_path(arg, path, sizeof (path),
@@ -1010,7 +1010,7 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv, boolean_t replacing)
* window between when udev deletes and recreates the link
* during which access attempts will fail with ENOENT.
*/
strlcpy(udevpath, path, MAXPATHLEN);
(void) strlcpy(udevpath, path, MAXPATHLEN);
(void) zfs_append_partition(udevpath, MAXPATHLEN);
fd = open(devpath, O_RDWR|O_EXCL);
@@ -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
+29 -28
View File
@@ -139,9 +139,10 @@
#include <sys/crypto/icp.h>
#include <sys/zfs_impl.h>
#include <sys/backtrace.h>
#include <libzpool.h>
#include <libspl.h>
static int ztest_fd_data = -1;
static int ztest_fd_rand = -1;
typedef struct ztest_shared_hdr {
uint64_t zh_hdr_size;
@@ -902,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);
}
@@ -1228,10 +1226,10 @@ ztest_kill(ztest_shared_t *zs)
* See comment above spa_write_cachefile().
*/
if (raidz_expand_pause_point != RAIDZ_EXPAND_PAUSE_NONE) {
if (mutex_tryenter(&spa_namespace_lock)) {
if (spa_namespace_tryenter(FTAG)) {
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE,
B_FALSE);
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
ztest_scratch_state->zs_raidz_scratch_verify_pause =
raidz_expand_pause_point;
@@ -1246,9 +1244,9 @@ ztest_kill(ztest_shared_t *zs)
return;
}
} else {
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE, B_FALSE);
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
}
(void) raise(SIGKILL);
@@ -2306,7 +2304,8 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap)
}
if (abuf == NULL) {
dmu_write(os, lr->lr_foid, offset, length, data, tx);
dmu_write(os, lr->lr_foid, offset, length, data, tx,
DMU_READ_PREFETCH);
} else {
memcpy(abuf->b_data, data, length);
VERIFY0(dmu_assign_arcbuf_by_dbuf(db, offset, abuf, tx, 0));
@@ -3688,10 +3687,10 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
if (error == 0) {
(void) printf("successful split - results:\n");
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
show_pool_stats(spa);
show_pool_stats(spa_lookup("splitp"));
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
++zs->zs_splits;
--zs->zs_mirrors;
}
@@ -3975,11 +3974,11 @@ raidz_scratch_verify(void)
kernel_init(SPA_MODE_READ);
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
spa = spa_lookup(ztest_opts.zo_pool);
ASSERT(spa);
spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP;
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG));
@@ -5243,7 +5242,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
* We've verified all the old bufwads, and made new ones.
* Now write them out.
*/
dmu_write(os, packobj, packoff, packsize, packbuf, tx);
dmu_write(os, packobj, packoff, packsize, packbuf, tx,
DMU_READ_PREFETCH);
if (freeit) {
if (ztest_opts.zo_verbose >= 7) {
@@ -5258,7 +5258,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
" txg %"PRIx64"\n",
bigoff, bigsize, txg);
}
dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx);
dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx,
DMU_READ_PREFETCH);
}
dmu_tx_commit(tx);
@@ -5513,7 +5514,8 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
* We've verified all the old bufwads, and made new ones.
* Now write them out.
*/
dmu_write(os, packobj, packoff, packsize, packbuf, tx);
dmu_write(os, packobj, packoff, packsize, packbuf, tx,
DMU_READ_PREFETCH);
if (ztest_opts.zo_verbose >= 7) {
(void) printf("writing offset %"PRIx64" size %"PRIx64""
" txg %"PRIx64"\n",
@@ -6119,7 +6121,8 @@ ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id)
"future leak: got %"PRIu64", open txg is %"PRIu64"",
old_txg, txg);
dmu_write(os, od->od_object, 0, sizeof (uint64_t), &txg, tx);
dmu_write(os, od->od_object, 0, sizeof (uint64_t), &txg, tx,
DMU_READ_PREFETCH);
(void) mutex_enter(&zcl.zcl_callbacks_lock);
@@ -7422,11 +7425,11 @@ ztest_walk_pool_directory(const char *header)
if (ztest_opts.zo_verbose >= 6)
(void) puts(header);
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
while ((spa = spa_next(spa)) != NULL)
if (ztest_opts.zo_verbose >= 6)
(void) printf("\t%s\n", spa_name(spa));
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
}
static void
@@ -8140,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.
@@ -8541,11 +8542,11 @@ ztest_run(ztest_shared_t *zs)
/*
* Verify that we can loop over all pools.
*/
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
for (spa = spa_next(NULL); spa != NULL; spa = spa_next(spa))
if (ztest_opts.zo_verbose > 3)
(void) printf("spa_next: found %s\n", spa_name(spa));
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
/*
* Verify that we can export the pool and reimport it under a
@@ -8949,13 +8950,13 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
libspl_init();
/*
* 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);
random_force_pseudo(B_TRUE);
if (!fd_data_str) {
process_options(argc, argv);
+2 -2
View File
@@ -8,9 +8,9 @@ AM_CPPFLAGS = \
-include $(top_builddir)/zfs_config.h \
-I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/module/icp/include \
-I$(top_srcdir)/lib/libspl/include \
-I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@
-I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@ \
-I$(top_srcdir)/lib/libzpool/include
AM_LIBTOOLFLAGS = --silent
+4 -4
View File
@@ -58,9 +58,9 @@ deb-utils: deb-local rpm-utils-initramfs
pkg1=$${name}-$${version}.$${arch}.rpm; \
pkg2=libnvpair3-$${version}.$${arch}.rpm; \
pkg3=libuutil3-$${version}.$${arch}.rpm; \
pkg4=libzfs6-$${version}.$${arch}.rpm; \
pkg5=libzpool6-$${version}.$${arch}.rpm; \
pkg6=libzfs6-devel-$${version}.$${arch}.rpm; \
pkg4=libzfs7-$${version}.$${arch}.rpm; \
pkg5=libzpool7-$${version}.$${arch}.rpm; \
pkg6=libzfs7-devel-$${version}.$${arch}.rpm; \
pkg7=$${name}-test-$${version}.$${arch}.rpm; \
pkg8=$${name}-dracut-$${version}.noarch.rpm; \
pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
@@ -72,7 +72,7 @@ deb-utils: deb-local rpm-utils-initramfs
path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \
echo "#!$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
echo "`which dh_shlibdeps` -- \
-xlibuutil3linux -xlibnvpair3linux -xlibzfs6linux -xlibzpool6linux" \
-xlibuutil3linux -xlibnvpair3linux -xlibzfs7linux -xlibzpool7linux" \
>> $${path_prepend}/dh_shlibdeps; \
## These -x arguments are passed to dpkg-shlibdeps, which exclude the
## Debianized packages from the auto-generated dependencies of the new debs,
@@ -12,14 +12,14 @@ dist_noinst_DATA += %D%/openzfs-libpam-zfs.postinst
dist_noinst_DATA += %D%/openzfs-libpam-zfs.prerm
dist_noinst_DATA += %D%/openzfs-libuutil3.docs
dist_noinst_DATA += %D%/openzfs-libuutil3.install.in
dist_noinst_DATA += %D%/openzfs-libzfs6.docs
dist_noinst_DATA += %D%/openzfs-libzfs6.install.in
dist_noinst_DATA += %D%/openzfs-libzfs7.docs
dist_noinst_DATA += %D%/openzfs-libzfs7.install.in
dist_noinst_DATA += %D%/openzfs-libzfsbootenv1.docs
dist_noinst_DATA += %D%/openzfs-libzfsbootenv1.install.in
dist_noinst_DATA += %D%/openzfs-libzfs-dev.docs
dist_noinst_DATA += %D%/openzfs-libzfs-dev.install.in
dist_noinst_DATA += %D%/openzfs-libzpool6.docs
dist_noinst_DATA += %D%/openzfs-libzpool6.install.in
dist_noinst_DATA += %D%/openzfs-libzpool7.docs
dist_noinst_DATA += %D%/openzfs-libzpool7.install.in
dist_noinst_DATA += %D%/openzfs-python3-pyzfs.install
dist_noinst_DATA += %D%/openzfs-zfs-dkms.config
dist_noinst_DATA += %D%/openzfs-zfs-dkms.dkms
+2 -2
View File
@@ -6,6 +6,6 @@ contrib/pyzfs/libzfs_core/bindings/__pycache__/
contrib/pyzfs/pyzfs.egg-info/
debian/openzfs-libnvpair3.install
debian/openzfs-libuutil3.install
debian/openzfs-libzfs6.install
debian/openzfs-libzfs7.install
debian/openzfs-libzfs-dev.install
debian/openzfs-libzpool6.install
debian/openzfs-libzpool7.install
+13 -13
View File
@@ -79,9 +79,9 @@ Architecture: linux-any
Depends: libssl-dev | libssl1.0-dev,
openzfs-libnvpair3 (= ${binary:Version}),
openzfs-libuutil3 (= ${binary:Version}),
openzfs-libzfs6 (= ${binary:Version}),
openzfs-libzfs7 (= ${binary:Version}),
openzfs-libzfsbootenv1 (= ${binary:Version}),
openzfs-libzpool6 (= ${binary:Version}),
openzfs-libzpool7 (= ${binary:Version}),
${misc:Depends}
Replaces: libzfslinux-dev
Conflicts: libzfslinux-dev
@@ -91,18 +91,18 @@ Description: OpenZFS filesystem development files for Linux
libraries of OpenZFS filesystem.
.
This package includes the development files of libnvpair3, libuutil3,
libzpool6 and libzfs6.
libzpool7 and libzfs7.
Package: openzfs-libzfs6
Package: openzfs-libzfs7
Section: contrib/libs
Architecture: linux-any
Depends: ${misc:Depends}, ${shlibs:Depends}
# The libcurl4 is loaded through dlopen("libcurl.so.4").
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=988521
Recommends: libcurl4
Breaks: libzfs2, libzfs4, libzfs4linux, libzfs6linux, openzfs-libzfs4
Replaces: libzfs2, libzfs4, libzfs4linux, libzfs6linux, openzfs-libzfs4
Conflicts: libzfs6linux
Breaks: libzfs2, libzfs4, libzfs4linux, libzfs6linux, libzfs7linux, openzfs-libzfs4, openzfs-libzfs6
Replaces: libzfs2, libzfs4, libzfs4linux, libzfs6linux, libzfs7linux, openzfs-libzfs4, openzfs-libzfs6
Conflicts: libzfs7linux
Description: OpenZFS filesystem library for Linux - general support
OpenZFS is a storage platform that encompasses the functionality of
traditional filesystems and volume managers. It supports data checksums,
@@ -124,13 +124,13 @@ Description: OpenZFS filesystem library for Linux - label info support
.
The zfsbootenv library provides support for modifying ZFS label information.
Package: openzfs-libzpool6
Package: openzfs-libzpool7
Section: contrib/libs
Architecture: linux-any
Depends: ${misc:Depends}, ${shlibs:Depends}
Breaks: libzpool2, libzpool5, libzpool6linux
Replaces: libzpool2, libzpool5, libzpool6linux
Conflicts: libzpool6linux
Breaks: libzpool2, libzpool5, libzpool6linux, libzpool7linux
Replaces: libzpool2, libzpool5, libzpool6linux, libzpool7linux
Conflicts: libzpool7linux
Description: OpenZFS pool library for Linux
OpenZFS is a storage platform that encompasses the functionality of
traditional filesystems and volume managers. It supports data checksums,
@@ -247,8 +247,8 @@ Architecture: linux-any
Pre-Depends: ${misc:Pre-Depends}
Depends: openzfs-libnvpair3 (= ${binary:Version}),
openzfs-libuutil3 (= ${binary:Version}),
openzfs-libzfs6 (= ${binary:Version}),
openzfs-libzpool6 (= ${binary:Version}),
openzfs-libzfs7 (= ${binary:Version}),
openzfs-libzpool7 (= ${binary:Version}),
python3,
${misc:Depends},
${shlibs:Depends}
+1
View File
@@ -191,6 +191,7 @@ USER_H = \
libzfs.h \
libzfs_core.h \
libzfsbootenv.h \
libzpool.h \
libzutil.h \
thread_pool.h
+51
View File
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBZPOOL_H
#define _LIBZPOOL_H extern __attribute__((visibility("default")))
#include <sys/zfs_context.h>
#ifdef __cplusplus
extern "C" {
#endif
extern char *vn_dumpdir;
_LIBZPOOL_H void kernel_init(int mode);
_LIBZPOOL_H void kernel_fini(void);
struct spa;
_LIBZPOOL_H void show_pool_stats(struct spa *);
_LIBZPOOL_H int handle_tunable_option(const char *, boolean_t);
#ifdef __cplusplus
}
#endif
#endif
+1
View File
@@ -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 ***,
@@ -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 \
@@ -104,6 +104,9 @@
#define spa_taskq_write_param_set_args(var) \
CTLTYPE_STRING, NULL, 0, spa_taskq_write_param, "A"
#define spa_taskq_free_param_set_args(var) \
CTLTYPE_STRING, NULL, 0, spa_taskq_free_param, "A"
#define fletcher_4_param_set_args(var) \
CTLTYPE_STRING, NULL, 0, fletcher_4_param, "A"
@@ -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 <sys/sdt.h>
#include_next <sys/sdt.h>
#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 */
@@ -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 \
@@ -34,11 +34,6 @@
#include <sys/signal.h>
#include <asm/page.h>
#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 <linux/sort.h>
#define qsort(base, num, size, cmp) \
sort(base, num, size, cmp, NULL)
@@ -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 */
+1
View File
@@ -56,6 +56,7 @@ extern void brt_create(spa_t *spa);
extern int brt_load(spa_t *spa);
extern void brt_unload(spa_t *spa);
extern void brt_sync(spa_t *spa, uint64_t txg);
extern void brt_prefetch_all(spa_t *spa);
#ifdef __cplusplus
}
+1 -1
View File
@@ -65,7 +65,7 @@ _Static_assert(BRT_RANGESIZE / SPA_MINBLOCKSIZE <= UINT16_MAX,
*/
#define BRT_BLOCKSIZE (32 * 1024)
#define BRT_RANGESIZE_TO_NBLOCKS(size) \
(((size) - 1) / BRT_BLOCKSIZE / sizeof (uint16_t) + 1)
(((size) - 1) / (BRT_BLOCKSIZE / sizeof (uint16_t)) + 1)
#define BRT_LITTLE_ENDIAN 0
#define BRT_BIG_ENDIAN 1
@@ -38,6 +38,8 @@ extern "C" {
#endif
#include <sys/zfs_context.h>
#include <sys/types.h>
#include <sys/uio.h>
/* Cryptographic Mechanisms */
+4 -4
View File
@@ -126,7 +126,7 @@ typedef enum dmu_object_byteswap {
(ot) < DMU_OT_NUMTYPES)
#define DMU_OT_IS_METADATA_CACHED(ot) (((ot) & DMU_OT_NEWTYPE) ? \
B_TRUE : dmu_ot[(ot)].ot_dbuf_metadata_cache)
((ot) & DMU_OT_METADATA) != 0 : dmu_ot[(ot)].ot_dbuf_metadata_cache)
/*
* MDB doesn't have dmu_ot; it defines these macros itself.
@@ -625,7 +625,7 @@ int dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset,
const void *tag, dmu_buf_t **, dmu_flags_t flags);
int dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset,
uint64_t length, int read, const void *tag, int *numbufsp,
dmu_buf_t ***dbpp);
dmu_buf_t ***dbpp, dmu_flags_t flags);
int dmu_buf_hold_noread(objset_t *os, uint64_t object, uint64_t offset,
const void *tag, dmu_buf_t **dbp);
int dmu_buf_hold_by_dnode(dnode_t *dn, uint64_t offset,
@@ -668,7 +668,7 @@ uint64_t dmu_buf_user_refcount(dmu_buf_t *db);
*/
int dmu_buf_hold_array_by_bonus(dmu_buf_t *db, uint64_t offset,
uint64_t length, boolean_t read, const void *tag,
int *numbufsp, dmu_buf_t ***dbpp);
int *numbufsp, dmu_buf_t ***dbpp, dmu_flags_t flags);
void dmu_buf_rele_array(dmu_buf_t **, int numbufs, const void *tag);
typedef void dmu_buf_evict_func_t(void *user_ptr);
@@ -924,7 +924,7 @@ int dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
int dmu_read_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size, void *buf,
dmu_flags_t flags);
void dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
const void *buf, dmu_tx_t *tx);
const void *buf, dmu_tx_t *tx, dmu_flags_t flags);
int dmu_write_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size,
const void *buf, dmu_tx_t *tx, dmu_flags_t flags);
void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
+3 -1
View File
@@ -387,6 +387,7 @@ typedef enum {
VDEV_PROP_SLOW_IOS,
VDEV_PROP_SIT_OUT,
VDEV_PROP_AUTOSIT,
VDEV_PROP_SLOW_IO_EVENTS,
VDEV_NUM_PROPS
} vdev_prop_t;
@@ -1713,7 +1714,8 @@ typedef enum {
typedef enum {
ZPOOL_PREFETCH_NONE = 0,
ZPOOL_PREFETCH_DDT
ZPOOL_PREFETCH_DDT,
ZPOOL_PREFETCH_BRT
} zpool_prefetch_type_t;
typedef enum {
+9 -5
View File
@@ -29,7 +29,7 @@
* Copyright 2017 Joyent, Inc.
* Copyright (c) 2017, Intel Corporation.
* Copyright (c) 2019, Allan Jude
* Copyright (c) 2019, Klara Inc.
* Copyright (c) 2019, 2025, Klara, Inc.
* Copyright (c) 2019, Datto Inc.
*/
@@ -867,10 +867,14 @@ uint_t spa_acq_allocator(spa_t *spa);
void spa_rel_allocator(spa_t *spa, uint_t allocator);
void spa_select_allocator(zio_t *zio);
/* spa namespace global mutex */
extern kmutex_t spa_namespace_lock;
extern avl_tree_t spa_namespace_avl;
extern kcondvar_t spa_namespace_cv;
/* spa namespace global lock */
extern void spa_namespace_enter(const void *tag);
extern boolean_t spa_namespace_tryenter(const void *tag);
extern int spa_namespace_enter_interruptible(const void *tag);
extern void spa_namespace_exit(const void *tag);
extern boolean_t spa_namespace_held(void);
extern void spa_namespace_wait(void);
extern void spa_namespace_broadcast(void);
/*
* SPA configuration functions in spa_config.c
@@ -470,6 +470,7 @@ struct vdev {
uint64_t vdev_checksum_t;
uint64_t vdev_io_n;
uint64_t vdev_io_t;
boolean_t vdev_slow_io_events;
uint64_t vdev_slow_io_n;
uint64_t vdev_slow_io_t;
};
+1 -1
View File
@@ -29,8 +29,8 @@
#ifdef _KERNEL
#include <sys/isa_defs.h>
#include <sys/types32.h>
#include <sys/xvattr.h>
#endif
#include <sys/xvattr.h>
#include <sys/acl.h>
#include <sys/dmu.h>
#include <sys/zfs_fuid.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 <sys/zfs_bootenv_os.h>
+18 -668
View File
@@ -77,14 +77,6 @@ extern "C" {
#include <sys/zfs_context_os.h>
#else /* _KERNEL || _STANDALONE */
#define _SYS_MUTEX_H
#define _SYS_RWLOCK_H
#define _SYS_CONDVAR_H
#define _SYS_VNODE_H
#define _SYS_VFS_H
#define _SYS_SUNDDI_H
#define _SYS_CALLB_H
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -93,10 +85,8 @@ extern "C" {
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <setjmp.h>
#include <assert.h>
#include <umem.h>
#include <limits.h>
#include <atomic.h>
#include <dirent.h>
@@ -119,667 +109,27 @@ extern "C" {
#include <sys/sysevent/eventdefs.h>
#include <sys/sunddi.h>
#include <sys/debug.h>
#include <sys/utsname.h>
#include <sys/trace_zfs.h>
#include <sys/zone.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
#include <sys/condvar.h>
#include <sys/cmn_err.h>
#include <sys/thread.h>
#include <sys/taskq.h>
#include <sys/tsd.h>
#include <sys/procfs_list.h>
#include <sys/kmem.h>
#include <sys/zfs_delay.h>
#include <sys/vnode.h>
#include <sys/callb.h>
#include <sys/trace.h>
#include <sys/systm.h>
#include <sys/misc.h>
#include <sys/random.h>
#include <sys/zfs_context_os.h>
/*
* Stack
*/
#define noinline __attribute__((noinline))
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
/*
* Debugging
*/
/*
* Note that we are not using the debugging levels.
*/
#define CE_CONT 0 /* continuation */
#define CE_NOTE 1 /* notice */
#define CE_WARN 2 /* warning */
#define CE_PANIC 3 /* panic */
#define CE_IGNORE 4 /* print nothing */
/*
* ZFS debugging
*/
extern void dprintf_setup(int *argc, char **argv);
extern void cmn_err(int, const char *, ...)
__attribute__((format(printf, 2, 3)));
extern void vcmn_err(int, const char *, va_list)
__attribute__((format(printf, 2, 0)));
extern void panic(const char *, ...)
__attribute__((format(printf, 1, 2), noreturn));
extern void vpanic(const char *, va_list)
__attribute__((format(printf, 1, 0), noreturn));
#define fm_panic panic
/*
* DTrace SDT probes have different signatures in userland than they do in
* the kernel. If they're being used in kernel code, re-define them out of
* existence for their counterparts in libzpool.
*
* Here's an example of how to use the set-error probes in userland:
* zfs$target:::set-error /arg0 == EBUSY/ {stack();}
*
* Here's an example of how to use DTRACE_PROBE probes in userland:
* If there is a probe declared as follows:
* DTRACE_PROBE2(zfs__probe_name, uint64_t, blkid, dnode_t *, dn);
* Then you can use it as follows:
* zfs$target:::probe2 /copyinstr(arg0) == "zfs__probe_name"/
* {printf("%u %p\n", arg1, arg2);}
*/
#ifdef DTRACE_PROBE
#undef DTRACE_PROBE
#endif /* DTRACE_PROBE */
#define DTRACE_PROBE(a)
#ifdef DTRACE_PROBE1
#undef DTRACE_PROBE1
#endif /* DTRACE_PROBE1 */
#define DTRACE_PROBE1(a, b, c)
#ifdef DTRACE_PROBE2
#undef DTRACE_PROBE2
#endif /* DTRACE_PROBE2 */
#define DTRACE_PROBE2(a, b, c, d, e)
#ifdef DTRACE_PROBE3
#undef DTRACE_PROBE3
#endif /* DTRACE_PROBE3 */
#define DTRACE_PROBE3(a, b, c, d, e, f, g)
#ifdef DTRACE_PROBE4
#undef DTRACE_PROBE4
#endif /* DTRACE_PROBE4 */
#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i)
/*
* Threads.
*/
typedef pthread_t kthread_t;
#define TS_RUN 0x00000002
#define TS_JOINABLE 0x00000004
#define curthread ((void *)(uintptr_t)pthread_self())
#define getcomm() "unknown"
#define thread_create_named(name, stk, stksize, func, arg, len, \
pp, state, pri) \
zk_thread_create(name, func, arg, stksize, state)
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
zk_thread_create(#func, func, arg, stksize, state)
#define thread_exit() pthread_exit(NULL)
#define thread_join(t) pthread_join((pthread_t)(t), NULL)
#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS)
/*
* Check if the current thread is a memory reclaim thread.
* Always returns false in userspace (no memory reclaim thread).
*/
#define current_is_reclaim_thread() (0)
/* in libzpool, p0 exists only to have its address taken */
typedef struct proc {
uintptr_t this_is_never_used_dont_dereference_it;
} proc_t;
extern struct proc p0;
#define curproc (&p0)
#define PS_NONE -1
extern kthread_t *zk_thread_create(const char *name, void (*func)(void *),
void *arg, size_t stksize, int state);
#define issig() (FALSE)
#define KPREEMPT_SYNC (-1)
#define kpreempt(x) sched_yield()
#define kpreempt_disable() ((void)0)
#define kpreempt_enable() ((void)0)
/*
* Mutexes
*/
typedef struct kmutex {
pthread_mutex_t m_lock;
pthread_t m_owner;
} kmutex_t;
#define MUTEX_DEFAULT 0
#define MUTEX_NOLOCKDEP MUTEX_DEFAULT
#define MUTEX_HELD(mp) pthread_equal((mp)->m_owner, pthread_self())
#define MUTEX_NOT_HELD(mp) !MUTEX_HELD(mp)
extern void mutex_init(kmutex_t *mp, char *name, int type, void *cookie);
extern void mutex_destroy(kmutex_t *mp);
extern void mutex_enter(kmutex_t *mp);
extern int mutex_enter_check_return(kmutex_t *mp);
extern void mutex_exit(kmutex_t *mp);
extern int mutex_tryenter(kmutex_t *mp);
#define NESTED_SINGLE 1
#define mutex_enter_nested(mp, class) mutex_enter(mp)
#define mutex_enter_interruptible(mp) mutex_enter_check_return(mp)
/*
* RW locks
*/
typedef struct krwlock {
pthread_rwlock_t rw_lock;
pthread_t rw_owner;
uint_t rw_readers;
} krwlock_t;
typedef int krw_t;
#define RW_READER 0
#define RW_WRITER 1
#define RW_DEFAULT RW_READER
#define RW_NOLOCKDEP RW_READER
#define RW_READ_HELD(rw) ((rw)->rw_readers > 0)
#define RW_WRITE_HELD(rw) pthread_equal((rw)->rw_owner, pthread_self())
#define RW_LOCK_HELD(rw) (RW_READ_HELD(rw) || RW_WRITE_HELD(rw))
extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
extern void rw_destroy(krwlock_t *rwlp);
extern void rw_enter(krwlock_t *rwlp, krw_t rw);
extern int rw_tryenter(krwlock_t *rwlp, krw_t rw);
extern int rw_tryupgrade(krwlock_t *rwlp);
extern void rw_exit(krwlock_t *rwlp);
#define rw_downgrade(rwlp) do { } while (0)
/*
* Credentials
*/
extern uid_t crgetuid(cred_t *cr);
extern uid_t crgetruid(cred_t *cr);
extern gid_t crgetgid(cred_t *cr);
extern int crgetngroups(cred_t *cr);
extern gid_t *crgetgroups(cred_t *cr);
/*
* Condition variables
*/
typedef pthread_cond_t kcondvar_t;
#define CV_DEFAULT 0
#define CALLOUT_FLAG_ABSOLUTE 0x2
extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
extern void cv_destroy(kcondvar_t *cv);
extern void cv_wait(kcondvar_t *cv, kmutex_t *mp);
extern int cv_wait_sig(kcondvar_t *cv, kmutex_t *mp);
extern int cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime);
extern int cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
hrtime_t res, int flag);
extern void cv_signal(kcondvar_t *cv);
extern void cv_broadcast(kcondvar_t *cv);
#define cv_timedwait_io(cv, mp, at) cv_timedwait(cv, mp, at)
#define cv_timedwait_idle(cv, mp, at) cv_timedwait(cv, mp, at)
#define cv_timedwait_sig(cv, mp, at) cv_timedwait(cv, mp, at)
#define cv_wait_io(cv, mp) cv_wait(cv, mp)
#define cv_wait_idle(cv, mp) cv_wait(cv, mp)
#define cv_wait_io_sig(cv, mp) cv_wait_sig(cv, mp)
#define cv_timedwait_sig_hires(cv, mp, t, r, f) \
cv_timedwait_hires(cv, mp, t, r, f)
#define cv_timedwait_idle_hires(cv, mp, t, r, f) \
cv_timedwait_hires(cv, mp, t, r, f)
/*
* Thread-specific data
*/
#define tsd_get(k) pthread_getspecific(k)
#define tsd_set(k, v) pthread_setspecific(k, v)
#define tsd_create(kp, d) pthread_key_create((pthread_key_t *)kp, d)
#define tsd_destroy(kp) /* nothing */
#ifdef __FreeBSD__
typedef off_t loff_t;
#endif
/*
* kstat creation, installation and deletion
*/
extern kstat_t *kstat_create(const char *, int,
const char *, const char *, uchar_t, ulong_t, uchar_t);
extern void kstat_install(kstat_t *);
extern void kstat_delete(kstat_t *);
extern void kstat_set_raw_ops(kstat_t *ksp,
int (*headers)(char *buf, size_t size),
int (*data)(char *buf, size_t size, void *data),
void *(*addr)(kstat_t *ksp, loff_t index));
/*
* procfs list manipulation
*/
typedef struct procfs_list {
void *pl_private;
kmutex_t pl_lock;
list_t pl_list;
uint64_t pl_next_id;
size_t pl_node_offset;
} procfs_list_t;
#ifndef __cplusplus
struct seq_file { };
void seq_printf(struct seq_file *m, const char *fmt, ...);
typedef struct procfs_list_node {
list_node_t pln_link;
uint64_t pln_id;
} procfs_list_node_t;
void procfs_list_install(const char *module,
const char *submodule,
const char *name,
mode_t mode,
procfs_list_t *procfs_list,
int (*show)(struct seq_file *f, void *p),
int (*show_header)(struct seq_file *f),
int (*clear)(procfs_list_t *procfs_list),
size_t procfs_list_node_off);
void procfs_list_uninstall(procfs_list_t *procfs_list);
void procfs_list_destroy(procfs_list_t *procfs_list);
void procfs_list_add(procfs_list_t *procfs_list, void *p);
#endif
/*
* Kernel memory
*/
#define KM_SLEEP UMEM_NOFAIL
#define KM_PUSHPAGE KM_SLEEP
#define KM_NOSLEEP UMEM_DEFAULT
#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */
#define KMC_NODEBUG UMC_NODEBUG
#define KMC_KVMEM 0x0
#define KMC_RECLAIMABLE 0x0
#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f)
#define kmem_free(_b, _s) umem_free(_b, _s)
#define vmem_alloc(_s, _f) kmem_alloc(_s, _f)
#define vmem_zalloc(_s, _f) kmem_zalloc(_s, _f)
#define vmem_free(_b, _s) kmem_free(_b, _s)
#define kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \
umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i)
#define kmem_cache_destroy(_c) umem_cache_destroy(_c)
#define kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f)
#define kmem_cache_free(_c, _b) umem_cache_free(_c, _b)
#define kmem_debugging() 0
#define kmem_cache_reap_now(_c) umem_cache_reap_now(_c);
#define kmem_cache_set_move(_c, _cb) /* nothing */
#define POINTER_INVALIDATE(_pp) /* nothing */
#define POINTER_IS_VALID(_p) 0
typedef umem_cache_t kmem_cache_t;
typedef enum kmem_cbrc {
KMEM_CBRC_YES,
KMEM_CBRC_NO,
KMEM_CBRC_LATER,
KMEM_CBRC_DONT_NEED,
KMEM_CBRC_DONT_KNOW
} kmem_cbrc_t;
/*
* Task queues
*/
#define TASKQ_NAMELEN 31
typedef uintptr_t taskqid_t;
typedef void (task_func_t)(void *);
typedef struct taskq_ent {
struct taskq_ent *tqent_next;
struct taskq_ent *tqent_prev;
task_func_t *tqent_func;
void *tqent_arg;
uintptr_t tqent_flags;
} taskq_ent_t;
typedef struct taskq {
char tq_name[TASKQ_NAMELEN + 1];
kmutex_t tq_lock;
krwlock_t tq_threadlock;
kcondvar_t tq_dispatch_cv;
kcondvar_t tq_wait_cv;
kthread_t **tq_threadlist;
int tq_flags;
int tq_active;
int tq_nthreads;
int tq_nalloc;
int tq_minalloc;
int tq_maxalloc;
kcondvar_t tq_maxalloc_cv;
int tq_maxalloc_wait;
taskq_ent_t *tq_freelist;
taskq_ent_t tq_task;
} taskq_t;
#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */
#define TASKQ_PREPOPULATE 0x0001
#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */
#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */
#define TQ_SLEEP KM_SLEEP /* Can block for memory */
#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */
#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
#define TQ_FRONT 0x08 /* Queue in front */
#define TASKQID_INVALID ((taskqid_t)0)
extern taskq_t *system_taskq;
extern taskq_t *system_delay_taskq;
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t,
kthread_t ***);
#define taskq_create_proc(a, b, c, d, e, p, f) \
(taskq_create(a, b, c, d, e, f))
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f))
extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t,
clock_t);
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
taskq_ent_t *);
extern int taskq_empty_ent(taskq_ent_t *);
extern void taskq_init_ent(taskq_ent_t *);
extern void taskq_destroy(taskq_t *);
extern void taskq_wait(taskq_t *);
extern void taskq_wait_id(taskq_t *, taskqid_t);
extern void taskq_wait_outstanding(taskq_t *, taskqid_t);
extern int taskq_member(taskq_t *, kthread_t *);
extern taskq_t *taskq_of_curthread(void);
extern int taskq_cancel_id(taskq_t *, taskqid_t);
extern void system_taskq_init(void);
extern void system_taskq_fini(void);
#define XVA_MAPSIZE 3
#define XVA_MAGIC 0x78766174
extern char *vn_dumpdir;
#define AV_SCANSTAMP_SZ 32 /* length of anti-virus scanstamp */
typedef struct xoptattr {
inode_timespec_t xoa_createtime; /* Create time of file */
uint8_t xoa_archive;
uint8_t xoa_system;
uint8_t xoa_readonly;
uint8_t xoa_hidden;
uint8_t xoa_nounlink;
uint8_t xoa_immutable;
uint8_t xoa_appendonly;
uint8_t xoa_nodump;
uint8_t xoa_settable;
uint8_t xoa_opaque;
uint8_t xoa_av_quarantined;
uint8_t xoa_av_modified;
uint8_t xoa_av_scanstamp[AV_SCANSTAMP_SZ];
uint8_t xoa_reparse;
uint8_t xoa_offline;
uint8_t xoa_sparse;
} xoptattr_t;
typedef struct vattr {
uint_t va_mask; /* bit-mask of attributes */
u_offset_t va_size; /* file size in bytes */
} vattr_t;
typedef struct xvattr {
vattr_t xva_vattr; /* Embedded vattr structure */
uint32_t xva_magic; /* Magic Number */
uint32_t xva_mapsize; /* Size of attr bitmap (32-bit words) */
uint32_t *xva_rtnattrmapp; /* Ptr to xva_rtnattrmap[] */
uint32_t xva_reqattrmap[XVA_MAPSIZE]; /* Requested attrs */
uint32_t xva_rtnattrmap[XVA_MAPSIZE]; /* Returned attrs */
xoptattr_t xva_xoptattrs; /* Optional attributes */
} xvattr_t;
typedef struct vsecattr {
uint_t vsa_mask; /* See below */
int vsa_aclcnt; /* ACL entry count */
void *vsa_aclentp; /* pointer to ACL entries */
int vsa_dfaclcnt; /* default ACL entry count */
void *vsa_dfaclentp; /* pointer to default ACL entries */
size_t vsa_aclentsz; /* ACE size in bytes of vsa_aclentp */
} vsecattr_t;
#define AT_MODE 0x00002
#define AT_UID 0x00004
#define AT_GID 0x00008
#define AT_FSID 0x00010
#define AT_NODEID 0x00020
#define AT_NLINK 0x00040
#define AT_SIZE 0x00080
#define AT_ATIME 0x00100
#define AT_MTIME 0x00200
#define AT_CTIME 0x00400
#define AT_RDEV 0x00800
#define AT_BLKSIZE 0x01000
#define AT_NBLOCKS 0x02000
#define AT_SEQ 0x08000
#define AT_XVATTR 0x10000
#define CRCREAT 0
#define F_FREESP 11
#define FIGNORECASE 0x80000 /* request case-insensitive lookups */
/*
* Random stuff
*/
#define ddi_get_lbolt() (gethrtime() >> 23)
#define ddi_get_lbolt64() (gethrtime() >> 23)
#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */
#define ddi_time_before(a, b) (a < b)
#define ddi_time_after(a, b) ddi_time_before(b, a)
#define ddi_time_before_eq(a, b) (!ddi_time_after(a, b))
#define ddi_time_after_eq(a, b) ddi_time_before_eq(b, a)
#define ddi_time_before64(a, b) (a < b)
#define ddi_time_after64(a, b) ddi_time_before64(b, a)
#define ddi_time_before_eq64(a, b) (!ddi_time_after64(a, b))
#define ddi_time_after_eq64(a, b) ddi_time_before_eq64(b, a)
extern void delay(clock_t ticks);
#define SEC_TO_TICK(sec) ((sec) * hz)
#define MSEC_TO_TICK(msec) (howmany((hrtime_t)(msec) * hz, MILLISEC))
#define USEC_TO_TICK(usec) (howmany((hrtime_t)(usec) * hz, MICROSEC))
#define NSEC_TO_TICK(nsec) (howmany((hrtime_t)(nsec) * hz, NANOSEC))
#define max_ncpus 64
#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN))
/*
* Process priorities as defined by setpriority(2) and getpriority(2).
*/
#define minclsyspri 19
#define defclsyspri 0
/* Write issue taskq priority. */
#define wtqclsyspri -19
#define maxclsyspri -20
#define CPU_SEQID ((uintptr_t)pthread_self() & (max_ncpus - 1))
#define CPU_SEQID_UNSTABLE CPU_SEQID
#define kcred NULL
#define CRED() NULL
#define crhold(cr) ((void)cr)
#define crfree(cr) ((void)cr)
#define ptob(x) ((x) * PAGESIZE)
#define NN_DIVISOR_1000 (1U << 0)
#define NN_NUMBUF_SZ (6)
extern uint64_t physmem;
extern const char *random_path;
extern const char *urandom_path;
extern int highbit64(uint64_t i);
extern int lowbit64(uint64_t i);
extern int random_get_bytes(uint8_t *ptr, size_t len);
extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
static __inline__ uint32_t
random_in_range(uint32_t range)
{
uint32_t r;
ASSERT(range != 0);
if (range == 1)
return (0);
(void) random_get_pseudo_bytes((uint8_t *)&r, sizeof (r));
return (r % range);
}
extern void kernel_init(int mode);
extern void kernel_fini(void);
extern void random_init(void);
extern void random_fini(void);
struct spa;
extern void show_pool_stats(struct spa *);
extern int handle_tunable_option(const char *, boolean_t);
typedef struct callb_cpr {
kmutex_t *cc_lockp;
} callb_cpr_t;
#define CALLB_CPR_INIT(cp, lockp, func, name) { \
(cp)->cc_lockp = lockp; \
}
#define CALLB_CPR_SAFE_BEGIN(cp) { \
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
}
#define CALLB_CPR_SAFE_END(cp, lockp) { \
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
}
#define CALLB_CPR_EXIT(cp) { \
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
mutex_exit((cp)->cc_lockp); \
}
#define zone_dataset_visible(x, y) (1)
#define INGLOBALZONE(z) (1)
extern uint32_t zone_get_hostid(void *zonep);
extern char *kmem_vasprintf(const char *fmt, va_list adx);
extern char *kmem_asprintf(const char *fmt, ...);
#define kmem_strfree(str) kmem_free((str), strlen(str) + 1)
#define kmem_strdup(s) strdup(s)
#ifndef __cplusplus
extern int kmem_scnprintf(char *restrict str, size_t size,
const char *restrict fmt, ...);
#endif
/*
* Hostname information
*/
extern int ddi_strtoull(const char *str, char **nptr, int base,
u_longlong_t *result);
typedef struct utsname utsname_t;
extern utsname_t *utsname(void);
/* ZFS Boot Related stuff. */
struct _buf {
intptr_t _fd;
};
struct bootstat {
uint64_t st_size;
};
typedef struct ace_object {
uid_t a_who;
uint32_t a_access_mask;
uint16_t a_flags;
uint16_t a_type;
uint8_t a_obj_type[16];
uint8_t a_inherit_obj_type[16];
} ace_object_t;
#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05
#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06
#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08
extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
extern int zfs_secpolicy_rename_perms(const char *from, const char *to,
cred_t *cr);
extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
extern int secpolicy_zfs(const cred_t *cr);
extern zoneid_t getzoneid(void);
/* SID stuff */
typedef struct ksiddomain {
uint_t kd_ref;
uint_t kd_len;
char *kd_name;
} ksiddomain_t;
ksiddomain_t *ksid_lookupdomain(const char *);
void ksiddomain_rele(ksiddomain_t *);
#define DDI_SLEEP KM_SLEEP
#define ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g) \
sysevent_post_event(_c, _d, _b, "libzpool", _e, _f)
#define zfs_sleep_until(wakeup) \
do { \
hrtime_t delta = wakeup - gethrtime(); \
struct timespec ts; \
ts.tv_sec = delta / NANOSEC; \
ts.tv_nsec = delta % NANOSEC; \
(void) nanosleep(&ts, NULL); \
} while (0)
typedef int fstrans_cookie_t;
extern fstrans_cookie_t spl_fstrans_mark(void);
extern void spl_fstrans_unmark(fstrans_cookie_t);
extern int kmem_cache_reap_active(void);
/*
* Kernel modules
*/
#define __init
#define __exit
#endif /* _KERNEL || _STANDALONE */
#ifdef __cplusplus
@@ -40,6 +40,7 @@ extern "C" {
#endif
#include <sys/nvpair.h>
#include <sys/zfs_debug_os.h>
extern int zfs_flags;
extern int zfs_recover;
@@ -35,18 +35,16 @@
#include <sys/vfs.h>
#ifdef FS_PROJINHERIT_FL
#define ZFS_PROJINHERIT_FL FS_PROJINHERIT_FL
#else
#define ZFS_PROJINHERIT_FL 0x20000000
#endif
#ifdef FS_IOC_FSGETXATTR
typedef struct fsxattr zfsxattr_t;
#define ZFS_IOC_FSGETXATTR FS_IOC_FSGETXATTR
#define ZFS_IOC_FSSETXATTR FS_IOC_FSSETXATTR
#else
/* Non-Linux OS */
#define FS_PROJINHERIT_FL 0x20000000
#define FS_XFLAG_PROJINHERIT FS_PROJINHERIT_FL
struct zfsxattr {
uint32_t fsx_xflags; /* xflags field value (get/set) */
uint32_t fsx_extsize; /* extsize field value (get/set) */
+4 -2
View File
@@ -1,6 +1,9 @@
libicp_la_CCASFLAGS = $(AM_CCASFLAGS)
libicp_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) $(LIBRARY_CFLAGS)
libicp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS)
libicp_la_CPPFLAGS += -I$(top_srcdir)/module/icp/include
noinst_LTLIBRARIES += libicp.la
nodist_libicp_la_SOURCES = \
@@ -35,8 +38,7 @@ nodist_libicp_la_SOURCES = \
module/icp/core/kcf_prov_lib.c \
module/icp/core/kcf_callprov.c \
module/icp/core/kcf_mech_tabs.c \
module/icp/core/kcf_prov_tabs.c \
module/zfs/zfs_impl.c
module/icp/core/kcf_prov_tabs.c
if TARGET_CPU_AARCH64
nodist_libicp_la_SOURCES += \
@@ -30,6 +30,6 @@ if !ASAN_ENABLED
libnvpair_la_LDFLAGS += -Wl,-z,defs
endif
libnvpair_la_LDFLAGS += -version-info 3:0:0
libnvpair_la_LDFLAGS += -version-info 4:0:1
dist_noinst_DATA += %D%/libnvpair.abi %D%/libnvpair.suppr
@@ -16,12 +16,24 @@ libspl_assert_la_SOURCES = \
libspl_la_SOURCES = \
%D%/libspl_impl.h \
%D%/atomic.c \
%D%/condvar.c \
%D%/cred.c \
%D%/getexecname.c \
%D%/kmem.c \
%D%/kstat.c \
%D%/libspl.c \
%D%/list.c \
%D%/mkdirp.c \
%D%/mutex.c \
%D%/page.c \
%D%/procfs_list.c \
%D%/random.c \
%D%/rwlock.c \
%D%/sid.c \
%D%/strlcat.c \
%D%/strlcpy.c \
%D%/taskq.c \
%D%/thread.c \
%D%/timestamp.c \
%D%/tunables.c \
%D%/include/sys/list.h \
+153
View File
@@ -0,0 +1,153 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <assert.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <sys/timer.h>
#include <sys/condvar.h>
/*
* =========================================================================
* condition variables
* =========================================================================
*/
void
cv_init(kcondvar_t *cv, char *name, int type, void *arg)
{
(void) name, (void) type, (void) arg;
VERIFY0(pthread_cond_init(cv, NULL));
}
void
cv_destroy(kcondvar_t *cv)
{
VERIFY0(pthread_cond_destroy(cv));
}
void
cv_wait(kcondvar_t *cv, kmutex_t *mp)
{
memset(&mp->m_owner, 0, sizeof (pthread_t));
VERIFY0(pthread_cond_wait(cv, &mp->m_lock));
mp->m_owner = pthread_self();
}
int
cv_wait_sig(kcondvar_t *cv, kmutex_t *mp)
{
cv_wait(cv, mp);
return (1);
}
int
cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
{
int error;
struct timeval tv;
struct timespec ts;
clock_t delta;
delta = abstime - ddi_get_lbolt();
if (delta <= 0)
return (-1);
VERIFY0(gettimeofday(&tv, NULL));
ts.tv_sec = tv.tv_sec + delta / hz;
ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz);
if (ts.tv_nsec >= NANOSEC) {
ts.tv_sec++;
ts.tv_nsec -= NANOSEC;
}
memset(&mp->m_owner, 0, sizeof (pthread_t));
error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
mp->m_owner = pthread_self();
if (error == ETIMEDOUT)
return (-1);
VERIFY0(error);
return (1);
}
int
cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
int flag)
{
(void) res;
int error;
struct timeval tv;
struct timespec ts;
hrtime_t delta;
ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);
delta = tim;
if (flag & CALLOUT_FLAG_ABSOLUTE)
delta -= gethrtime();
if (delta <= 0)
return (-1);
VERIFY0(gettimeofday(&tv, NULL));
ts.tv_sec = tv.tv_sec + delta / NANOSEC;
ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC);
if (ts.tv_nsec >= NANOSEC) {
ts.tv_sec++;
ts.tv_nsec -= NANOSEC;
}
memset(&mp->m_owner, 0, sizeof (pthread_t));
error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
mp->m_owner = pthread_self();
if (error == ETIMEDOUT)
return (-1);
VERIFY0(error);
return (1);
}
void
cv_signal(kcondvar_t *cv)
{
VERIFY0(pthread_cond_signal(cv));
}
void
cv_broadcast(kcondvar_t *cv)
{
VERIFY0(pthread_cond_broadcast(cv));
}
+64
View File
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <sys/cred.h>
uid_t
crgetuid(cred_t *cr)
{
(void) cr;
return (0);
}
uid_t
crgetruid(cred_t *cr)
{
(void) cr;
return (0);
}
gid_t
crgetgid(cred_t *cr)
{
(void) cr;
return (0);
}
int
crgetngroups(cred_t *cr)
{
(void) cr;
return (0);
}
gid_t *
crgetgroups(cred_t *cr)
{
(void) cr;
return (NULL);
}
@@ -4,6 +4,7 @@ libspl_HEADERS = \
%D%/atomic.h \
%D%/libgen.h \
%D%/libshare.h \
%D%/libspl.h \
%D%/statcommon.h \
%D%/stdlib.h \
%D%/string.h \
@@ -24,14 +25,13 @@ libspl_rpc_HEADERS = \
libspl_sysdir = $(libspldir)/sys
libspl_sys_HEADERS = \
%D%/sys/abd_os.h \
%D%/sys/abd_impl_os.h \
%D%/sys/acl.h \
%D%/sys/acl_impl.h \
%D%/sys/asm_linkage.h \
%D%/sys/backtrace.h \
%D%/sys/callb.h \
%D%/sys/cmn_err.h \
%D%/sys/condvar.h \
%D%/sys/cred.h \
%D%/sys/debug.h \
%D%/sys/dkio.h \
@@ -43,22 +43,33 @@ libspl_sys_HEADERS = \
%D%/sys/kstat.h \
%D%/sys/list.h \
%D%/sys/list_impl.h \
%D%/sys/misc.h \
%D%/sys/mhd.h \
%D%/sys/mkdev.h \
%D%/sys/mod.h \
%D%/sys/mutex.h \
%D%/sys/policy.h \
%D%/sys/poll.h \
%D%/sys/priv.h \
%D%/sys/processor.h \
%D%/sys/procfs_list.h \
%D%/sys/random.h \
%D%/sys/rwlock.h \
%D%/sys/sid.h \
%D%/sys/simd.h \
%D%/sys/stack.h \
%D%/sys/stdtypes.h \
%D%/sys/string.h \
%D%/sys/sunddi.h \
%D%/sys/sysmacros.h \
%D%/sys/systeminfo.h \
%D%/sys/systm.h \
%D%/sys/thread.h \
%D%/sys/taskq.h \
%D%/sys/time.h \
%D%/sys/trace_spl.h \
%D%/sys/trace_zfs.h \
%D%/sys/timer.h \
%D%/sys/trace.h \
%D%/sys/tsd.h \
%D%/sys/tunables.h \
%D%/sys/types.h \
%D%/sys/types32.h \
@@ -77,8 +88,7 @@ libspl_sys_HEADERS += \
%D%/os/linux/sys/mount.h \
%D%/os/linux/sys/param.h \
%D%/os/linux/sys/stat.h \
%D%/os/linux/sys/sysmacros.h \
%D%/os/linux/sys/zfs_context_os.h
%D%/os/linux/sys/vfs.h
libspl_ia32_HEADERS = \
%D%/os/linux/sys/ia32/asm_linkage.h
@@ -93,9 +103,7 @@ libspl_sys_HEADERS += \
%D%/os/freebsd/sys/mount.h \
%D%/os/freebsd/sys/param.h \
%D%/os/freebsd/sys/stat.h \
%D%/os/freebsd/sys/sysmacros.h \
%D%/os/freebsd/sys/vfs.h \
%D%/os/freebsd/sys/zfs_context_os.h
%D%/os/freebsd/sys/vfs.h
libspl_ia32_HEADERS = \
%D%/os/freebsd/sys/ia32/asm_linkage.h
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
*/
#ifndef _LIBSPL_H
#define _LIBSPL_H extern __attribute__((visibility("default")))
#ifdef __cplusplus
extern "C" {
#endif
_LIBSPL_H void libspl_init(void);
_LIBSPL_H void libspl_fini(void);
#ifdef __cplusplus
};
#endif
#endif /* _LIBSPL_H */
@@ -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
@@ -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
@@ -65,4 +65,6 @@
extern size_t spl_pagesize(void);
#define PAGESIZE (spl_pagesize())
#define ptob(x) ((x) * PAGESIZE)
#endif
@@ -20,10 +20,14 @@
*
* CDDL HEADER END
*/
/* Copyright 2025 by Lawrence Livermore National Security, LLC. */
#ifndef ZFS_CONTEXT_OS_H
#define ZFS_CONTEXT_OS_H
/* This is the Linux userspace version of include/os/linux/spl/sys/vfs.h */
#define HAVE_LARGE_STACKS 1
#ifndef _LIBSPL_SYS_VFS_H
#define _LIBSPL_SYS_VFS_H
#include <linux/fs.h>
#include <sys/statfs.h>
#endif
@@ -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| \
@@ -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 <sys/mutex.h>
typedef struct callb_cpr {
kmutex_t *cc_lockp;
} callb_cpr_t;
#define CALLB_CPR_INIT(cp, lockp, func, name) { \
(cp)->cc_lockp = lockp; \
}
#define CALLB_CPR_SAFE_BEGIN(cp) { \
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
}
#define CALLB_CPR_SAFE_END(cp, lockp) { \
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
}
#define CALLB_CPR_EXIT(cp) { \
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
mutex_exit((cp)->cc_lockp); \
}
#endif
@@ -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
@@ -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 <pthread.h>
#include <sys/time.h>
#include <sys/mutex.h>
/*
* Condition variables
*/
typedef pthread_cond_t kcondvar_t;
#define CV_DEFAULT 0
#define CALLOUT_FLAG_ABSOLUTE 0x2
extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
extern void cv_destroy(kcondvar_t *cv);
extern void cv_wait(kcondvar_t *cv, kmutex_t *mp);
extern int cv_wait_sig(kcondvar_t *cv, kmutex_t *mp);
extern int cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime);
extern int cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
hrtime_t res, int flag);
extern void cv_signal(kcondvar_t *cv);
extern void cv_broadcast(kcondvar_t *cv);
#define cv_timedwait_io(cv, mp, at) cv_timedwait(cv, mp, at)
#define cv_timedwait_idle(cv, mp, at) cv_timedwait(cv, mp, at)
#define cv_timedwait_sig(cv, mp, at) cv_timedwait(cv, mp, at)
#define cv_wait_io(cv, mp) cv_wait(cv, mp)
#define cv_wait_idle(cv, mp) cv_wait(cv, mp)
#define cv_wait_io_sig(cv, mp) cv_wait_sig(cv, mp)
#define cv_timedwait_sig_hires(cv, mp, t, r, f) \
cv_timedwait_hires(cv, mp, t, r, f)
#define cv_timedwait_idle_hires(cv, mp, t, r, f) \
cv_timedwait_hires(cv, mp, t, r, f)
#endif /* _SYS_CONDVAR_H */
@@ -28,6 +28,24 @@
#ifndef _LIBSPL_SYS_CRED_H
#define _LIBSPL_SYS_CRED_H
#include <sys/stat.h>
/*
* Credentials
*/
typedef struct cred cred_t;
extern uid_t crgetuid(cred_t *cr);
extern uid_t crgetruid(cred_t *cr);
extern gid_t crgetgid(cred_t *cr);
extern int crgetngroups(cred_t *cr);
extern gid_t *crgetgroups(cred_t *cr);
#define kcred NULL
#define CRED() NULL
#define crhold(cr) ((void)cr)
#define crfree(cr) ((void)cr)
#endif
@@ -24,6 +24,12 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBSPL_SYS_DEBUG_H
#define _LIBSPL_SYS_DEBUG_H
@@ -42,4 +48,22 @@
#define __must_check __attribute__((warn_unused_result))
#endif
#ifndef noinline
#define noinline __attribute__((noinline))
#endif
#ifndef likely
#define likely(x) __builtin_expect((x), 1)
#endif
#ifndef unlikely
#define unlikely(x) __builtin_expect((x), 0)
#endif
/*
* Kernel modules
*/
#define __init
#define __exit
#endif
@@ -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 <stdlib.h>
#include <umem.h>
#include <sys/types.h>
#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
#define KM_SLEEP 0x00000000 /* same as KM_SLEEP */
#define KM_NOSLEEP 0x00000001 /* same as KM_NOSLEEP */
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)
#define kmem_alloc(size, flags) ((void) sizeof (flags), malloc(size))
#define kmem_free(ptr, size) ((void) sizeof (size), free(ptr))
extern int kmem_scnprintf(char *restrict str, size_t size,
const char *restrict fmt, ...);
#ifdef __cplusplus
}
#endif
typedef umem_cache_t kmem_cache_t;
typedef enum kmem_cbrc {
KMEM_CBRC_YES,
KMEM_CBRC_NO,
KMEM_CBRC_LATER,
KMEM_CBRC_DONT_NEED,
KMEM_CBRC_DONT_KNOW
} kmem_cbrc_t;
typedef int fstrans_cookie_t;
extern fstrans_cookie_t spl_fstrans_mark(void);
extern void spl_fstrans_unmark(fstrans_cookie_t);
#endif /* _SYS_KMEM_H */
@@ -27,758 +27,65 @@
#ifndef _SYS_KSTAT_H
#define _SYS_KSTAT_H
/*
* Definition of general kernel statistics structures and /dev/kstat ioctls
*/
#include <sys/types.h>
#include <sys/time.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int kid_t; /* unique kstat id */
/*
* Kernel statistics driver (/dev/kstat) ioctls
*/
#define KSTAT_IOC_BASE ('K' << 8)
#define KSTAT_IOC_CHAIN_ID KSTAT_IOC_BASE | 0x01
#define KSTAT_IOC_READ KSTAT_IOC_BASE | 0x02
#define KSTAT_IOC_WRITE KSTAT_IOC_BASE | 0x03
/*
* /dev/kstat ioctl usage (kd denotes /dev/kstat descriptor):
*
* kcid = ioctl(kd, KSTAT_IOC_CHAIN_ID, NULL);
* kcid = ioctl(kd, KSTAT_IOC_READ, kstat_t *);
* kcid = ioctl(kd, KSTAT_IOC_WRITE, kstat_t *);
*/
#define KSTAT_STRLEN 255 /* 254 chars + NULL; must be 16 * n - 1 */
/*
* The generic kstat header
*/
typedef struct kstat {
/*
* Fields relevant to both kernel and user
*/
hrtime_t ks_crtime; /* creation time (from gethrtime()) */
struct kstat *ks_next; /* kstat chain linkage */
kid_t ks_kid; /* unique kstat ID */
char ks_module[KSTAT_STRLEN]; /* provider module name */
uchar_t ks_resv; /* reserved, currently just padding */
int ks_instance; /* provider module's instance */
char ks_name[KSTAT_STRLEN]; /* kstat name */
uchar_t ks_type; /* kstat data type */
char ks_class[KSTAT_STRLEN]; /* kstat class */
uchar_t ks_flags; /* kstat flags */
void *ks_data; /* kstat type-specific data */
uint_t ks_ndata; /* # of type-specific data records */
size_t ks_data_size; /* total size of kstat data section */
hrtime_t ks_snaptime; /* time of last data snapshot */
/*
* Fields relevant to kernel only
*/
int (*ks_update)(struct kstat *, int); /* dynamic update */
void *ks_private; /* arbitrary provider-private data */
int (*ks_snapshot)(struct kstat *, void *, int);
void *ks_lock; /* protects this kstat's data */
uchar_t ks_flags;
void *ks_data;
uint_t ks_ndata;
size_t ks_data_size;
int (*ks_update)(struct kstat *, int);
void *ks_private;
void *ks_lock;
} kstat_t;
/*
* kstat structure and locking strategy
*
* Each kstat consists of a header section (a kstat_t) and a data section.
* The system maintains a set of kstats, protected by kstat_chain_lock.
* kstat_chain_lock protects all additions to/deletions from this set,
* as well as all changes to kstat headers. kstat data sections are
* *optionally* protected by the per-kstat ks_lock. If ks_lock is non-NULL,
* kstat clients (e.g. /dev/kstat) will acquire this lock for all of their
* operations on that kstat. It is up to the kstat provider to decide whether
* guaranteeing consistent data to kstat clients is sufficiently important
* to justify the locking cost. Note, however, that most statistic updates
* already occur under one of the provider's mutexes, so if the provider sets
* ks_lock to point to that mutex, then kstat data locking is free.
*
* NOTE: variable-size kstats MUST employ kstat data locking, to prevent
* data-size races with kstat clients.
*
* NOTE: ks_lock is really of type (kmutex_t *); it is declared as (void *)
* in the kstat header so that users don't have to be exposed to all of the
* kernel's lock-related data structures.
*/
#if defined(_KERNEL)
#define KSTAT_ENTER(k) \
{ kmutex_t *lp = (k)->ks_lock; if (lp) mutex_enter(lp); }
#define KSTAT_EXIT(k) \
{ kmutex_t *lp = (k)->ks_lock; if (lp) mutex_exit(lp); }
#define KSTAT_UPDATE(k, rw) (*(k)->ks_update)((k), (rw))
#define KSTAT_SNAPSHOT(k, buf, rw) (*(k)->ks_snapshot)((k), (buf), (rw))
#endif /* defined(_KERNEL) */
/*
* kstat time
*
* All times associated with kstats (e.g. creation time, snapshot time,
* kstat_timer_t and kstat_io_t timestamps, etc.) are 64-bit nanosecond values,
* as returned by gethrtime(). The accuracy of these timestamps is machine
* dependent, but the precision (units) is the same across all platforms.
*/
/*
* kstat identity (KID)
*
* Each kstat is assigned a unique KID (kstat ID) when it is added to the
* global kstat chain. The KID is used as a cookie by /dev/kstat to
* request information about the corresponding kstat. There is also
* an identity associated with the entire kstat chain, kstat_chain_id,
* which is bumped each time a kstat is added or deleted. /dev/kstat uses
* the chain ID to detect changes in the kstat chain (e.g., a new disk
* coming online) between ioctl()s.
*/
/*
* kstat module, kstat instance
*
* ks_module and ks_instance contain the name and instance of the module
* that created the kstat. In cases where there can only be one instance,
* ks_instance is 0. The kernel proper (/kernel/unix) uses "unix" as its
* module name.
*/
/*
* kstat name
*
* ks_name gives a meaningful name to a kstat. The full kstat namespace
* is module.instance.name, so the name only need be unique within a
* module. kstat_create() will fail if you try to create a kstat with
* an already-used (ks_module, ks_instance, ks_name) triplet. Spaces are
* allowed in kstat names, but strongly discouraged, since they hinder
* awk-style processing at user level.
*/
/*
* kstat type
*
* The kstat mechanism provides several flavors of kstat data, defined
* below. The "raw" kstat type is just treated as an array of bytes; you
* can use this to export any kind of data you want.
*
* Some kstat types allow multiple data structures per kstat, e.g.
* KSTAT_TYPE_NAMED; others do not. This is part of the spec for each
* kstat data type.
*
* User-level tools should *not* rely on the #define KSTAT_NUM_TYPES. To
* get this information, read out the standard system kstat "kstat_types".
*/
#define KSTAT_TYPE_RAW 0 /* can be anything */
/* ks_ndata >= 1 */
#define KSTAT_TYPE_NAMED 1 /* name/value pair */
/* ks_ndata >= 1 */
#define KSTAT_TYPE_INTR 2 /* interrupt statistics */
/* ks_ndata == 1 */
#define KSTAT_TYPE_IO 3 /* I/O statistics */
/* ks_ndata == 1 */
#define KSTAT_TYPE_TIMER 4 /* event timer */
/* ks_ndata >= 1 */
#define KSTAT_NUM_TYPES 5
/*
* kstat class
*
* Each kstat can be characterized as belonging to some broad class
* of statistics, e.g. disk, tape, net, vm, streams, etc. This field
* can be used as a filter to extract related kstats. The following
* values are currently in use: disk, tape, net, controller, vm, kvm,
* hat, streams, kstat, and misc. (The kstat class encompasses things
* like kstat_types.)
*/
/*
* kstat flags
*
* Any of the following flags may be passed to kstat_create(). They are
* all zero by default.
*
* KSTAT_FLAG_VIRTUAL:
*
* Tells kstat_create() not to allocate memory for the
* kstat data section; instead, you will set the ks_data
* field to point to the data you wish to export. This
* provides a convenient way to export existing data
* structures.
*
* KSTAT_FLAG_VAR_SIZE:
*
* The size of the kstat you are creating will vary over time.
* For example, you may want to use the kstat mechanism to
* export a linked list. NOTE: The kstat framework does not
* manage the data section, so all variable-size kstats must be
* virtual kstats. Moreover, variable-size kstats MUST employ
* kstat data locking to prevent data-size races with kstat
* clients. See the section on "kstat snapshot" for details.
*
* KSTAT_FLAG_WRITABLE:
*
* Makes the kstat's data section writable by root.
* The ks_snapshot routine (see below) does not need to check for
* this; permission checking is handled in the kstat driver.
*
* KSTAT_FLAG_PERSISTENT:
*
* Indicates that this kstat is to be persistent over time.
* For persistent kstats, kstat_delete() simply marks the
* kstat as dormant; a subsequent kstat_create() reactivates
* the kstat. This feature is provided so that statistics
* are not lost across driver close/open (e.g., raw disk I/O
* on a disk with no mounted partitions.)
* NOTE: Persistent kstats cannot be virtual, since ks_data
* points to garbage as soon as the driver goes away.
*
* The following flags are maintained by the kstat framework:
*
* KSTAT_FLAG_DORMANT:
*
* For persistent kstats, indicates that the kstat is in the
* dormant state (e.g., the corresponding device is closed).
*
* KSTAT_FLAG_INVALID:
*
* This flag is set when a kstat is in a transitional state,
* e.g. between kstat_create() and kstat_install().
* kstat clients must not attempt to access the kstat's data
* if this flag is set.
*/
#define KSTAT_TYPE_RAW 0
#define KSTAT_TYPE_NAMED 1
#define KSTAT_FLAG_VIRTUAL 0x01
#define KSTAT_FLAG_VAR_SIZE 0x02
#define KSTAT_FLAG_WRITABLE 0x04
#define KSTAT_FLAG_PERSISTENT 0x08
#define KSTAT_FLAG_DORMANT 0x10
#define KSTAT_FLAG_INVALID 0x20
#define KSTAT_FLAG_LONGSTRINGS 0x40
#define KSTAT_FLAG_NO_HEADERS 0x80
/*
* Dynamic update support
*
* The kstat mechanism allows for an optional ks_update function to update
* kstat data. This is useful for drivers where the underlying device
* keeps cheap hardware stats, but extraction is expensive. Instead of
* constantly keeping the kstat data section up to date, you can supply a
* ks_update function which updates the kstat's data section on demand.
* To take advantage of this feature, simply set the ks_update field before
* calling kstat_install().
*
* The ks_update function, if supplied, must have the following structure:
*
* int
* foo_kstat_update(kstat_t *ksp, int rw)
* {
* if (rw == KSTAT_WRITE) {
* ... update the native stats from ksp->ks_data;
* return EACCES if you don't support this
* } else {
* ... update ksp->ks_data from the native stats
* }
* }
*
* The ks_update return codes are: 0 for success, EACCES if you don't allow
* KSTAT_WRITE, and EIO for any other type of error.
*
* In general, the ks_update function may need to refer to provider-private
* data; for example, it may need a pointer to the provider's raw statistics.
* The ks_private field is available for this purpose. Its use is entirely
* at the provider's discretion.
*
* All variable-size kstats MUST supply a ks_update routine, which computes
* and sets ks_data_size (and ks_ndata if that is meaningful), since these
* are needed to perform kstat snapshots (see below).
*
* No kstat locking should be done inside the ks_update routine. The caller
* will already be holding the kstat's ks_lock (to ensure consistent data).
*/
#define KSTAT_READ 0
#define KSTAT_WRITE 1
/*
* Kstat snapshot
*
* In order to get a consistent view of a kstat's data, clients must obey
* the kstat's locking strategy. However, these clients may need to perform
* operations on the data which could cause a fault (e.g. copyout()), or
* operations which are simply expensive. Doing so could cause deadlock
* (e.g. if you're holding a disk's kstat lock which is ultimately required
* to resolve a copyout() fault), performance degradation (since the providers'
* activity is serialized at the kstat lock), device timing problems, etc.
*
* To avoid these problems, kstat data is provided via snapshots. Taking
* a snapshot is a simple process: allocate a wired-down kernel buffer,
* acquire the kstat's data lock, copy the data into the buffer ("take the
* snapshot"), and release the lock. This ensures that the kstat's data lock
* will be held as briefly as possible, and that no faults will occur while
* the lock is held.
*
* Normally, the snapshot is taken by default_kstat_snapshot(), which
* timestamps the data (sets ks_snaptime), copies it, and does a little
* massaging to deal with incomplete transactions on i/o kstats. However,
* this routine only works for kstats with contiguous data (the typical case).
* If you create a kstat whose data is, say, a linked list, you must provide
* your own ks_snapshot routine. The routine you supply must have the
* following prototype (replace "foo" with something appropriate):
*
* int foo_kstat_snapshot(kstat_t *ksp, void *buf, int rw);
*
* The minimal snapshot routine -- one which copies contiguous data that
* doesn't need any massaging -- would be this:
*
* ksp->ks_snaptime = gethrtime();
* if (rw == KSTAT_WRITE)
* memcpy(ksp->ks_data, buf, ksp->ks_data_size);
* else
* memcpy(buf, ksp->ks_data, ksp->ks_data_size);
* return (0);
*
* A more illuminating example is taking a snapshot of a linked list:
*
* ksp->ks_snaptime = gethrtime();
* if (rw == KSTAT_WRITE)
* return (EACCES); ... See below ...
* for (foo = first_foo; foo; foo = foo->next) {
* memcpy(buf, foo, sizeof (struct foo));
* buf = ((struct foo *) buf) + 1;
* }
* return (0);
*
* In the example above, we have decided that we don't want to allow
* KSTAT_WRITE access, so we return EACCES if this is attempted.
*
* The key points are:
*
* (1) ks_snaptime must be set (via gethrtime()) to timestamp the data.
* (2) Data gets copied from the kstat to the buffer on KSTAT_READ,
* and from the buffer to the kstat on KSTAT_WRITE.
* (3) ks_snapshot return values are: 0 for success, EACCES if you
* don't allow KSTAT_WRITE, and EIO for any other type of error.
*
* Named kstats (see section on "Named statistics" below) containing long
* strings (KSTAT_DATA_STRING) need special handling. The kstat driver
* assumes that all strings are copied into the buffer after the array of
* named kstats, and the pointers (KSTAT_NAMED_STR_PTR()) are updated to point
* into the copy within the buffer. The default snapshot routine does this,
* but overriding routines should contain at least the following:
*
* if (rw == KSTAT_READ) {
* kstat_named_t *knp = buf;
* char *end = knp + ksp->ks_ndata;
* uint_t i;
*
* ... Do the regular copy ...
* memcpy(buf, ksp->ks_data, sizeof (kstat_named_t) * ksp->ks_ndata);
*
* for (i = 0; i < ksp->ks_ndata; i++, knp++) {
* if (knp[i].data_type == KSTAT_DATA_STRING &&
* KSTAT_NAMED_STR_PTR(knp) != NULL) {
* memcpy(end, KSTAT_NAMED_STR_PTR(knp),
* KSTAT_NAMED_STR_BUFLEN(knp));
* KSTAT_NAMED_STR_PTR(knp) = end;
* end += KSTAT_NAMED_STR_BUFLEN(knp);
* }
* }
*/
/*
* Named statistics.
*
* List of arbitrary name=value statistics.
*/
typedef struct kstat_named {
char name[KSTAT_STRLEN]; /* name of counter */
uchar_t data_type; /* data type */
char name[KSTAT_STRLEN];
uchar_t data_type;
union {
char c[16]; /* enough for 128-bit ints */
int32_t i32;
uint32_t ui32;
struct {
union {
char *ptr; /* NULL-term string */
#if defined(_KERNEL) && defined(_MULTI_DATAMODEL)
caddr32_t ptr32;
#endif
char __pad[8]; /* 64-bit padding */
char *ptr;
char __pad[8];
} addr;
uint32_t len; /* # bytes for strlen + '\0' */
uint32_t len;
} str;
/*
* The int64_t and uint64_t types are not valid for a maximally conformant
* 32-bit compilation environment (cc -Xc) using compilers prior to the
* introduction of C99 conforming compiler (reference ISO/IEC 9899:1990).
* In these cases, the visibility of i64 and ui64 is only permitted for
* 64-bit compilation environments or 32-bit non-maximally conformant
* C89 or C90 ANSI C compilation environments (cc -Xt and cc -Xa). In the
* C99 ANSI C compilation environment, the long long type is supported.
* The _INT64_TYPE is defined by the implementation (see sys/inttypes.h).
*/
#if defined(_INT64_TYPE)
int64_t i64;
uint64_t ui64;
#endif
long l;
ulong_t ul;
/* These structure members are obsolete */
longlong_t ll;
u_longlong_t ull;
float f;
double d;
} value; /* value of counter */
} value;
} kstat_named_t;
#define KSTAT_DATA_CHAR 0
#define KSTAT_DATA_INT32 1
#define KSTAT_DATA_UINT32 2
#define KSTAT_DATA_INT64 3
#define KSTAT_DATA_UINT64 4
#if !defined(_LP64)
#define KSTAT_DATA_LONG KSTAT_DATA_INT32
#define KSTAT_DATA_ULONG KSTAT_DATA_UINT32
#else
#if !defined(_KERNEL)
#define KSTAT_DATA_LONG KSTAT_DATA_INT64
#define KSTAT_DATA_ULONG KSTAT_DATA_UINT64
#else
#define KSTAT_DATA_LONG 7 /* only visible to the kernel */
#define KSTAT_DATA_ULONG 8 /* only visible to the kernel */
#endif /* !_KERNEL */
#endif /* !_LP64 */
/*
* Statistics exporting named kstats with long strings (KSTAT_DATA_STRING)
* may not make the assumption that ks_data_size is equal to (ks_ndata * sizeof
* (kstat_named_t)). ks_data_size in these cases is equal to the sum of the
* amount of space required to store the strings (ie, the sum of
* KSTAT_NAMED_STR_BUFLEN() for all KSTAT_DATA_STRING statistics) plus the
* space required to store the kstat_named_t's.
*
* The default update routine will update ks_data_size automatically for
* variable-length kstats containing long strings (using the default update
* routine only makes sense if the string is the only thing that is changing
* in size, and ks_ndata is constant). Fixed-length kstats containing long
* strings must explicitly change ks_data_size (after creation but before
* initialization) to reflect the correct amount of space required for the
* long strings and the kstat_named_t's.
*/
#define KSTAT_DATA_STRING 9
/* These types are obsolete */
#define KSTAT_DATA_LONGLONG KSTAT_DATA_INT64
#define KSTAT_DATA_ULONGLONG KSTAT_DATA_UINT64
#define KSTAT_DATA_FLOAT 5
#define KSTAT_DATA_DOUBLE 6
#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data)
#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)
/*
* Retrieve the pointer of the string contained in the given named kstat.
* kstat creation, installation and deletion
*/
#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr)
/*
* Retrieve the length of the buffer required to store the string in the given
* named kstat.
*/
#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.str.len)
/*
* Interrupt statistics.
*
* An interrupt is a hard interrupt (sourced from the hardware device
* itself), a soft interrupt (induced by the system via the use of
* some system interrupt source), a watchdog interrupt (induced by
* a periodic timer call), spurious (an interrupt entry point was
* entered but there was no interrupt condition to service),
* or multiple service (an interrupt condition was detected and
* serviced just prior to returning from any of the other types).
*
* Measurement of the spurious class of interrupts is useful for
* autovectored devices in order to pinpoint any interrupt latency
* problems in a particular system configuration.
*
* Devices that have more than one interrupt of the same
* type should use multiple structures.
*/
#define KSTAT_INTR_HARD 0
#define KSTAT_INTR_SOFT 1
#define KSTAT_INTR_WATCHDOG 2
#define KSTAT_INTR_SPURIOUS 3
#define KSTAT_INTR_MULTSVC 4
#define KSTAT_NUM_INTRS 5
typedef struct kstat_intr {
uint_t intrs[KSTAT_NUM_INTRS]; /* interrupt counters */
} kstat_intr_t;
#define KSTAT_INTR_PTR(kptr) ((kstat_intr_t *)(kptr)->ks_data)
/*
* I/O statistics.
*/
typedef struct kstat_io {
/*
* Basic counters.
*
* The counters should be updated at the end of service
* (e.g., just prior to calling biodone()).
*/
u_longlong_t nread; /* number of bytes read */
u_longlong_t nwritten; /* number of bytes written */
uint_t reads; /* number of read operations */
uint_t writes; /* number of write operations */
/*
* Accumulated time and queue length statistics.
*
* Accumulated time statistics are kept as a running sum
* of "active" time. Queue length statistics are kept as a
* running sum of the product of queue length and elapsed time
* at that length -- i.e., a Riemann sum for queue length
* integrated against time. (You can also think of the active time
* as a Riemann sum, for the boolean function (queue_length > 0)
* integrated against time, or you can think of it as the
* Lebesgue measure of the set on which queue_length > 0.)
*
* ^
* | _________
* 8 | i4 |
* | | |
* Queue 6 | |
* Length | _________ | |
* 4 | i2 |_______| |
* | | i3 |
* 2_______| |
* | i1 |
* |_______________________________|
* Time-> t1 t2 t3 t4
*
* At each change of state (entry or exit from the queue),
* we add the elapsed time (since the previous state change)
* to the active time if the queue length was non-zero during
* that interval; and we add the product of the elapsed time
* times the queue length to the running length*time sum.
*
* This method is generalizable to measuring residency
* in any defined system: instead of queue lengths, think
* of "outstanding RPC calls to server X".
*
* A large number of I/O subsystems have at least two basic
* "lists" of transactions they manage: one for transactions
* that have been accepted for processing but for which processing
* has yet to begin, and one for transactions which are actively
* being processed (but not done). For this reason, two cumulative
* time statistics are defined here: wait (pre-service) time,
* and run (service) time.
*
* All times are 64-bit nanoseconds (hrtime_t), as returned by
* gethrtime().
*
* The units of cumulative busy time are accumulated nanoseconds.
* The units of cumulative length*time products are elapsed time
* times queue length.
*
* Updates to the fields below are performed implicitly by calls to
* these five functions:
*
* kstat_waitq_enter()
* kstat_waitq_exit()
* kstat_runq_enter()
* kstat_runq_exit()
*
* kstat_waitq_to_runq() (see below)
* kstat_runq_back_to_waitq() (see below)
*
* Since kstat_waitq_exit() is typically followed immediately
* by kstat_runq_enter(), there is a single kstat_waitq_to_runq()
* function which performs both operations. This is a performance
* win since only one timestamp is required.
*
* In some instances, it may be necessary to move a request from
* the run queue back to the wait queue, e.g. for write throttling.
* For these situations, call kstat_runq_back_to_waitq().
*
* These fields should never be updated by any other means.
*/
hrtime_t wtime; /* cumulative wait (pre-service) time */
hrtime_t wlentime; /* cumulative wait length*time product */
hrtime_t wlastupdate; /* last time wait queue changed */
hrtime_t rtime; /* cumulative run (service) time */
hrtime_t rlentime; /* cumulative run length*time product */
hrtime_t rlastupdate; /* last time run queue changed */
uint_t wcnt; /* count of elements in wait state */
uint_t rcnt; /* count of elements in run state */
} kstat_io_t;
#define KSTAT_IO_PTR(kptr) ((kstat_io_t *)(kptr)->ks_data)
/*
* Event timer statistics - cumulative elapsed time and number of events.
*
* Updates to these fields are performed implicitly by calls to
* kstat_timer_start() and kstat_timer_stop().
*/
typedef struct kstat_timer {
char name[KSTAT_STRLEN]; /* event name */
uchar_t resv; /* reserved */
u_longlong_t num_events; /* number of events */
hrtime_t elapsed_time; /* cumulative elapsed time */
hrtime_t min_time; /* shortest event duration */
hrtime_t max_time; /* longest event duration */
hrtime_t start_time; /* previous event start time */
hrtime_t stop_time; /* previous event stop time */
} kstat_timer_t;
#define KSTAT_TIMER_PTR(kptr) ((kstat_timer_t *)(kptr)->ks_data)
#if defined(_KERNEL)
#include <sys/t_lock.h>
extern kid_t kstat_chain_id; /* bumped at each state change */
extern void kstat_init(void); /* initialize kstat framework */
/*
* Adding and deleting kstats.
*
* The typical sequence to add a kstat is:
*
* ksp = kstat_create(module, instance, name, class, type, ndata, flags);
* if (ksp) {
* ... provider initialization, if necessary
* kstat_install(ksp);
* }
*
* There are three logically distinct steps here:
*
* Step 1: System Initialization (kstat_create)
*
* kstat_create() performs system initialization. kstat_create()
* allocates memory for the entire kstat (header plus data), initializes
* all header fields, initializes the data section to all zeroes, assigns
* a unique KID, and puts the kstat onto the system's kstat chain.
* The returned kstat is marked invalid (KSTAT_FLAG_INVALID is set),
* because the provider (caller) has not yet had a chance to initialize
* the data section.
*
* By default, kstats are exported to all zones on the system. A kstat may be
* created via kstat_create_zone() to specify a zone to which the statistics
* should be exported. kstat_zone_add() may be used to specify additional
* zones to which the statistics are to be exported.
*
* Step 2: Provider Initialization
*
* The provider performs any necessary initialization of the data section,
* e.g. setting the name fields in a KSTAT_TYPE_NAMED. Virtual kstats set
* the ks_data field at this time. The provider may also set the ks_update,
* ks_snapshot, ks_private, and ks_lock fields if necessary.
*
* Step 3: Installation (kstat_install)
*
* Once the kstat is completely initialized, kstat_install() clears the
* INVALID flag, thus making the kstat accessible to the outside world.
* kstat_install() also clears the DORMANT flag for persistent kstats.
*
* Removing a kstat from the system
*
* kstat_delete(ksp) removes ksp from the kstat chain and frees all
* associated system resources. NOTE: When you call kstat_delete(),
* you must NOT be holding that kstat's ks_lock. Otherwise, you may
* deadlock with a kstat reader.
*
* Persistent kstats
*
* From the provider's point of view, persistence is transparent. The only
* difference between ephemeral (normal) kstats and persistent kstats
* is that you pass KSTAT_FLAG_PERSISTENT to kstat_create(). Magically,
* this has the effect of making your data visible even when you're
* not home. Persistence is important to tools like iostat, which want
* to get a meaningful picture of disk activity. Without persistence,
* raw disk i/o statistics could never accumulate: they would come and
* go with each open/close of the raw device.
*
* The magic of persistence works by slightly altering the behavior of
* kstat_create() and kstat_delete(). The first call to kstat_create()
* creates a new kstat, as usual. However, kstat_delete() does not
* actually delete the kstat: it performs one final update of the data
* (i.e., calls the ks_update routine), marks the kstat as dormant, and
* sets the ks_lock, ks_update, ks_private, and ks_snapshot fields back
* to their default values (since they might otherwise point to garbage,
* e.g. if the provider is going away). kstat clients can still access
* the dormant kstat just like a live kstat; they just continue to see
* the final data values as long as the kstat remains dormant.
* All subsequent kstat_create() calls simply find the already-existing,
* dormant kstat and return a pointer to it, without altering any fields.
* The provider then performs its usual initialization sequence, and
* calls kstat_install(). kstat_install() uses the old data values to
* initialize the native data (i.e., ks_update is called with KSTAT_WRITE),
* thus making it seem like you were never gone.
*/
extern kstat_t *kstat_create(const char *, int, const char *, const char *,
uchar_t, uint_t, uchar_t);
extern kstat_t *kstat_create_zone(const char *, int, const char *,
const char *, uchar_t, uint_t, uchar_t, zoneid_t);
extern 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 */
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBSPL_SYS_MISC_H
#define _LIBSPL_SYS_MISC_H
#include <sys/utsname.h>
/*
* Hostname information
*/
typedef struct utsname utsname_t;
extern utsname_t *utsname(void);
#endif
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_MUTEX_H
#define _SYS_MUTEX_H
#include <pthread.h>
/*
* Mutexes
*/
typedef struct kmutex {
pthread_mutex_t m_lock;
pthread_t m_owner;
} kmutex_t;
#define MUTEX_DEFAULT 0
#define MUTEX_NOLOCKDEP MUTEX_DEFAULT
#define MUTEX_HELD(mp) pthread_equal((mp)->m_owner, pthread_self())
#define MUTEX_NOT_HELD(mp) !MUTEX_HELD(mp)
extern void mutex_init(kmutex_t *mp, char *name, int type, void *cookie);
extern void mutex_destroy(kmutex_t *mp);
extern void mutex_enter(kmutex_t *mp);
extern int mutex_enter_check_return(kmutex_t *mp);
extern void mutex_exit(kmutex_t *mp);
extern int mutex_tryenter(kmutex_t *mp);
#define NESTED_SINGLE 1
#define mutex_enter_nested(mp, class) mutex_enter(mp)
#define mutex_enter_interruptible(mp) mutex_enter_check_return(mp)
#endif /* _SYS_MUTEX_H */
@@ -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 <sys/types.h>
#include <sys/mutex.h>
#include <sys/list.h>
/*
* procfs list manipulation
*/
typedef struct procfs_list {
void *pl_private;
kmutex_t pl_lock;
list_t pl_list;
uint64_t pl_next_id;
size_t pl_node_offset;
} procfs_list_t;
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 */
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_RANDOM_H
#define _SYS_RANDOM_H
extern int random_get_bytes(uint8_t *ptr, size_t len);
extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
extern void random_force_pseudo(boolean_t onoff);
static __inline__ uint32_t
random_in_range(uint32_t range)
{
uint32_t r;
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 */
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_RWLOCK_H
#define _SYS_RWLOCK_H
#include <pthread.h>
/*
* RW locks
*/
typedef struct krwlock {
pthread_rwlock_t rw_lock;
pthread_t rw_owner;
uint_t rw_readers;
} krwlock_t;
typedef int krw_t;
#define RW_READER 0
#define RW_WRITER 1
#define RW_DEFAULT RW_READER
#define RW_NOLOCKDEP RW_READER
#define RW_READ_HELD(rw) ((rw)->rw_readers > 0)
#define RW_WRITE_HELD(rw) pthread_equal((rw)->rw_owner, pthread_self())
#define RW_LOCK_HELD(rw) (RW_READ_HELD(rw) || RW_WRITE_HELD(rw))
extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
extern void rw_destroy(krwlock_t *rwlp);
extern void rw_enter(krwlock_t *rwlp, krw_t rw);
extern int rw_tryenter(krwlock_t *rwlp, krw_t rw);
extern int rw_tryupgrade(krwlock_t *rwlp);
extern void rw_exit(krwlock_t *rwlp);
#define rw_downgrade(rwlp) do { } while (0)
#endif /* _SYS_RWLOCK_H */
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_SID_H
#define _SYS_SID_H
#include <sys/types.h>
/* SID stuff */
typedef struct ksiddomain {
uint_t kd_ref;
uint_t kd_len;
char *kd_name;
} ksiddomain_t;
ksiddomain_t *ksid_lookupdomain(const char *);
void ksiddomain_rele(ksiddomain_t *);
#endif
@@ -1 +1,4 @@
#ifndef _LIBSPL_SYS_STRING_H
#define _LIBSPL_SYS_STRING_H
#include <string.h>
#endif
@@ -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 */
@@ -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 <stdint.h>
#ifdef __linux__
/*
* On Linux, we need the system-provided sysmacros.h to get the makedev(),
* major() and minor() definitions for makedevice() below. FreeBSD does not
* have this header, so include_next won't find it and will abort. So, we
* protect it with a platform check.
*/
#include_next <sys/sysmacros.h>
#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 <stddef.h> version */
#if defined(_KERNEL) && !defined(_KMEMUSER) && !defined(offsetof)
#define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
#endif
/*
* Process priorities as defined by setpriority(2) and getpriority(2).
*/
#define minclsyspri 19
#define defclsyspri 0
/* Write issue taskq priority. */
#define wtqclsyspri -19
#define maxclsyspri -20
#endif /* _LIBSPL_SYS_SYSMACROS_H */
#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 /* _SYS_SYSMACROS_H */
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBSPL_SYS_SYSTM_H
#define _LIBSPL_SYS_SYSTM_H
uint64_t libspl_physmem(void);
#define physmem libspl_physmem()
#endif
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_TASKQ_H
#define _SYS_TASKQ_H
#include <pthread.h>
#include <stdint.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
#include <sys/condvar.h>
/*
* Task queues
*/
#define TASKQ_NAMELEN 31
typedef uintptr_t taskqid_t;
typedef void (task_func_t)(void *);
typedef struct taskq_ent {
struct taskq_ent *tqent_next;
struct taskq_ent *tqent_prev;
task_func_t *tqent_func;
void *tqent_arg;
uintptr_t tqent_flags;
} taskq_ent_t;
typedef struct taskq {
char tq_name[TASKQ_NAMELEN + 1];
kmutex_t tq_lock;
krwlock_t tq_threadlock;
kcondvar_t tq_dispatch_cv;
kcondvar_t tq_wait_cv;
kthread_t **tq_threadlist;
int tq_flags;
int tq_active;
int tq_nthreads;
int tq_nalloc;
int tq_minalloc;
int tq_maxalloc;
kcondvar_t tq_maxalloc_cv;
int tq_maxalloc_wait;
taskq_ent_t *tq_freelist;
taskq_ent_t tq_task;
} taskq_t;
#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */
#define TASKQ_PREPOPULATE 0x0001
#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */
#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */
#define TQ_SLEEP KM_SLEEP /* Can block for memory */
#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */
#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
#define TQ_FRONT 0x08 /* Queue in front */
#define TASKQID_INVALID ((taskqid_t)0)
extern taskq_t *_system_taskq(void);
extern taskq_t *_system_delay_taskq(void);
#define system_taskq _system_taskq()
#define system_delay_taskq _system_delay_taskq()
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t,
kthread_t ***);
#define taskq_create_proc(a, b, c, d, e, p, f) \
(taskq_create(a, b, c, d, e, f))
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f))
extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t,
clock_t);
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
taskq_ent_t *);
extern int taskq_empty_ent(taskq_ent_t *);
extern void taskq_init_ent(taskq_ent_t *);
extern void taskq_destroy(taskq_t *);
extern void taskq_wait(taskq_t *);
extern void taskq_wait_id(taskq_t *, taskqid_t);
extern void taskq_wait_outstanding(taskq_t *, taskqid_t);
extern int taskq_member(taskq_t *, kthread_t *);
extern taskq_t *taskq_of_curthread(void);
extern int taskq_cancel_id(taskq_t *, taskqid_t);
extern void system_taskq_init(void);
extern void system_taskq_fini(void);
#endif /* _SYS_TASKQ_H */
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_THREAD_H
#define _SYS_THREAD_H
#include <pthread.h>
/*
* Threads.
*/
typedef pthread_t kthread_t;
#define TS_RUN 0x00000002
#define TS_JOINABLE 0x00000004
#define curthread ((void *)(uintptr_t)pthread_self())
#define getcomm() "unknown"
#define thread_create_named(name, stk, stksize, func, arg, len, \
pp, state, pri) \
zk_thread_create(name, func, arg, stksize, state)
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
zk_thread_create(#func, func, arg, stksize, state)
#define thread_exit() pthread_exit(NULL)
#define thread_join(t) pthread_join((pthread_t)(t), NULL)
#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS)
/*
* Check if the current thread is a memory reclaim thread.
* Always returns false in userspace (no memory reclaim thread).
*/
#define current_is_reclaim_thread() (0)
/* in libzpool, p0 exists only to have its address taken */
typedef void (proc_t)(void);
extern void p0(void);
#define curproc (&p0)
#define PS_NONE -1
extern kthread_t *zk_thread_create(const char *name, void (*func)(void *),
void *arg, size_t stksize, int state);
#define issig() (FALSE)
#define KPREEMPT_SYNC (-1)
#define kpreempt(x) sched_yield()
#define kpreempt_disable() ((void)0)
#define kpreempt_enable() ((void)0)
#endif /* _SYS_THREAD_H */
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SPL_TIMER_H
#define _SPL_TIMER_H
#include <sys/time.h>
#define ddi_get_lbolt() (gethrtime() >> 23)
#define ddi_get_lbolt64() (gethrtime() >> 23)
#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */
#define ddi_time_before(a, b) (a < b)
#define ddi_time_after(a, b) ddi_time_before(b, a)
#define ddi_time_before_eq(a, b) (!ddi_time_after(a, b))
#define ddi_time_after_eq(a, b) ddi_time_before_eq(b, a)
#define ddi_time_before64(a, b) (a < b)
#define ddi_time_after64(a, b) ddi_time_before64(b, a)
#define ddi_time_before_eq64(a, b) (!ddi_time_after64(a, b))
#define ddi_time_after_eq64(a, b) ddi_time_before_eq64(b, a)
extern void delay(clock_t ticks);
#define SEC_TO_TICK(sec) ((sec) * hz)
#define MSEC_TO_TICK(msec) (howmany((hrtime_t)(msec) * hz, MILLISEC))
#define USEC_TO_TICK(usec) (howmany((hrtime_t)(usec) * hz, MICROSEC))
#define NSEC_TO_TICK(nsec) (howmany((hrtime_t)(nsec) * hz, NANOSEC))
#define usleep_range(min, max) \
do { \
struct timespec ts; \
ts.tv_sec = min / MICROSEC; \
ts.tv_nsec = USEC2NSEC(min); \
(void) nanosleep(&ts, NULL); \
} while (0)
#endif /* _SPL_TIMER_H */
@@ -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 */
@@ -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
@@ -1,24 +0,0 @@
/* Here to keep the libspl build happy */
#ifndef _LIBSPL_ZFS_TRACE_H
#define _LIBSPL_ZFS_TRACE_H
/*
* The set-error SDT probe is extra static, in that we declare its fake
* function literally, rather than with the DTRACE_PROBE1() macro. This is
* necessary so that SET_ERROR() can evaluate to a value, which wouldn't
* be possible if it required multiple statements (to declare the function
* and then call it).
*
* SET_ERROR() uses the comma operator so that it can be used without much
* additional code. For example, "return (EINVAL);" becomes
* "return (SET_ERROR(EINVAL));". Note that the argument will be evaluated
* twice, so it should not have side effects (e.g. something like:
* "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice).
*/
#undef SET_ERROR
#define SET_ERROR(err) \
(__set_error(__FILE__, __func__, __LINE__, err), err)
#endif
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_TSD_H
#define _SYS_TSD_H
#include <pthread.h>
/*
* Thread-specific data
*/
#define tsd_get(k) pthread_getspecific(k)
#define tsd_set(k, v) pthread_setspecific(k, v)
#define tsd_create(kp, d) pthread_key_create((pthread_key_t *)kp, d)
#define tsd_destroy(kp) /* nothing */
#endif /* _SYS_MUTEX_H */
@@ -25,7 +25,7 @@
*/
#ifndef _SYS_TUNABLES_H
#define _SYS_TUNABLES_H
#define _SYS_TUNABLES_H extern __attribute__((visibility("hidden")))
typedef enum {
ZFS_TUNABLE_TYPE_INT,
@@ -49,12 +49,14 @@ typedef struct zfs_tunable {
const char *zt_desc;
} zfs_tunable_t;
int zfs_tunable_set(const zfs_tunable_t *tunable, const char *val);
int zfs_tunable_get(const zfs_tunable_t *tunable, char *val, size_t valsz);
_SYS_TUNABLES_H int zfs_tunable_set(const zfs_tunable_t *tunable,
const char *val);
_SYS_TUNABLES_H int zfs_tunable_get(const zfs_tunable_t *tunable, char *val,
size_t valsz);
const zfs_tunable_t *zfs_tunable_lookup(const char *name);
_SYS_TUNABLES_H const zfs_tunable_t *zfs_tunable_lookup(const char *name);
typedef int (*zfs_tunable_iter_t)(const zfs_tunable_t *tunable, void *arg);
void zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg);
_SYS_TUNABLES_H void zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg);
#endif
@@ -50,4 +50,8 @@ typedef int projid_t;
#include <sys/param.h> /* for NBBY */
#ifdef __FreeBSD__
typedef off_t loff_t;
#endif
#endif
@@ -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 */
@@ -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 */
@@ -42,6 +42,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#ifdef __cplusplus
extern "C" {
+102
View File
@@ -0,0 +1,102 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <sys/kmem.h>
char *
kmem_vasprintf(const char *fmt, va_list adx)
{
char *buf = NULL;
va_list adx_copy;
va_copy(adx_copy, adx);
VERIFY(vasprintf(&buf, fmt, adx_copy) != -1);
va_end(adx_copy);
return (buf);
}
char *
kmem_asprintf(const char *fmt, ...)
{
char *buf = NULL;
va_list adx;
va_start(adx, fmt);
VERIFY(vasprintf(&buf, fmt, adx) != -1);
va_end(adx);
return (buf);
}
/*
* kmem_scnprintf() will return the number of characters that it would have
* printed whenever it is limited by value of the size variable, rather than
* the number of characters that it did print. This can cause misbehavior on
* subsequent uses of the return value, so we define a safe version that will
* return the number of characters actually printed, minus the NULL format
* character. Subsequent use of this by the safe string functions is safe
* whether it is snprintf(), strlcat() or strlcpy().
*/
int
kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...)
{
int n;
va_list ap;
/* Make the 0 case a no-op so that we do not return -1 */
if (size == 0)
return (0);
va_start(ap, fmt);
n = vsnprintf(str, size, fmt, ap);
va_end(ap);
if (n >= size)
n = size - 1;
return (n);
}
fstrans_cookie_t
spl_fstrans_mark(void)
{
return ((fstrans_cookie_t)0);
}
void
spl_fstrans_unmark(fstrans_cookie_t cookie)
{
(void) cookie;
}
int
kmem_cache_reap_active(void)
{
return (0);
}
+64
View File
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <sys/kstat.h>
/*
* =========================================================================
* kstats
* =========================================================================
*/
kstat_t *
kstat_create(const char *module, int instance, const char *name,
const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag)
{
(void) module, (void) instance, (void) name, (void) class, (void) type,
(void) ndata, (void) ks_flag;
return (NULL);
}
void
kstat_install(kstat_t *ksp)
{
(void) ksp;
}
void
kstat_delete(kstat_t *ksp)
{
(void) ksp;
}
void
kstat_set_raw_ops(kstat_t *ksp,
int (*headers)(char *buf, size_t size),
int (*data)(char *buf, size_t size, void *data),
void *(*addr)(kstat_t *ksp, loff_t index))
{
(void) ksp, (void) headers, (void) data, (void) addr;
}
+67
View File
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
*/
#include <libspl.h>
#include <assert.h>
#include <unistd.h>
#include <sys/misc.h>
#include <sys/systm.h>
#include <sys/utsname.h>
#include "libspl_impl.h"
static uint64_t hw_physmem = 0;
static struct utsname hw_utsname = {};
uint64_t
libspl_physmem(void)
{
return (hw_physmem);
}
utsname_t *
utsname(void)
{
return (&hw_utsname);
}
void
libspl_init(void)
{
hw_physmem = sysconf(_SC_PHYS_PAGES);
VERIFY0(uname(&hw_utsname));
random_init();
}
void
libspl_fini(void)
{
random_fini();
}
@@ -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
+89
View File
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <assert.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/mutex.h>
/*
* =========================================================================
* mutexes
* =========================================================================
*/
void
mutex_init(kmutex_t *mp, char *name, int type, void *cookie)
{
(void) name, (void) type, (void) cookie;
VERIFY0(pthread_mutex_init(&mp->m_lock, NULL));
memset(&mp->m_owner, 0, sizeof (pthread_t));
}
void
mutex_destroy(kmutex_t *mp)
{
VERIFY0(pthread_mutex_destroy(&mp->m_lock));
}
void
mutex_enter(kmutex_t *mp)
{
VERIFY0(pthread_mutex_lock(&mp->m_lock));
mp->m_owner = pthread_self();
}
int
mutex_enter_check_return(kmutex_t *mp)
{
int error = pthread_mutex_lock(&mp->m_lock);
if (error == 0)
mp->m_owner = pthread_self();
return (error);
}
int
mutex_tryenter(kmutex_t *mp)
{
int error = pthread_mutex_trylock(&mp->m_lock);
if (error == 0) {
mp->m_owner = pthread_self();
return (1);
} else {
VERIFY3S(error, ==, EBUSY);
return (0);
}
}
void
mutex_exit(kmutex_t *mp)
{
memset(&mp->m_owner, 0, sizeof (pthread_t));
VERIFY0(pthread_mutex_unlock(&mp->m_lock));
}
@@ -0,0 +1,93 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <assert.h>
#include <pthread.h>
#include <stddef.h>
#include <sys/procfs_list.h>
#include <sys/mutex.h>
#include <sys/list.h>
/*
* =========================================================================
* procfs list
* =========================================================================
*/
void
seq_printf(struct seq_file *m, const char *fmt, ...)
{
(void) m, (void) fmt;
}
void
procfs_list_install(const char *module,
const char *submodule,
const char *name,
mode_t mode,
procfs_list_t *procfs_list,
int (*show)(struct seq_file *f, void *p),
int (*show_header)(struct seq_file *f),
int (*clear)(procfs_list_t *procfs_list),
size_t procfs_list_node_off)
{
(void) module, (void) submodule, (void) name, (void) mode, (void) show,
(void) show_header, (void) clear;
mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL);
list_create(&procfs_list->pl_list,
procfs_list_node_off + sizeof (procfs_list_node_t),
procfs_list_node_off + offsetof(procfs_list_node_t, pln_link));
procfs_list->pl_next_id = 1;
procfs_list->pl_node_offset = procfs_list_node_off;
}
void
procfs_list_uninstall(procfs_list_t *procfs_list)
{
(void) procfs_list;
}
void
procfs_list_destroy(procfs_list_t *procfs_list)
{
ASSERT(list_is_empty(&procfs_list->pl_list));
list_destroy(&procfs_list->pl_list);
mutex_destroy(&procfs_list->pl_lock);
}
#define NODE_ID(procfs_list, obj) \
(((procfs_list_node_t *)(((char *)obj) + \
(procfs_list)->pl_node_offset))->pln_id)
void
procfs_list_add(procfs_list_t *procfs_list, void *p)
{
ASSERT(MUTEX_HELD(&procfs_list->pl_lock));
NODE_ID(procfs_list, p) = procfs_list->pl_next_id++;
list_insert_tail(&procfs_list->pl_list, p);
}
+101
View File
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <stdint.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/random.h>
#include "libspl_impl.h"
#define RANDOM_PATH "/dev/random"
#define URANDOM_PATH "/dev/urandom"
static int random_fd = -1, urandom_fd = -1;
static boolean_t force_pseudo = B_FALSE;
void
random_init(void)
{
/* Handle multiple calls. */
if (random_fd != -1) {
ASSERT3U(urandom_fd, !=, -1);
return;
}
VERIFY((random_fd = open(RANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1);
VERIFY((urandom_fd = open(URANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1);
}
void
random_fini(void)
{
close(random_fd);
close(urandom_fd);
random_fd = -1;
urandom_fd = -1;
}
void
random_force_pseudo(boolean_t onoff)
{
force_pseudo = onoff;
}
static int
random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
{
size_t resid = len;
ssize_t bytes;
ASSERT(fd != -1);
while (resid != 0) {
bytes = read(fd, ptr, resid);
ASSERT3S(bytes, >=, 0);
ptr += bytes;
resid -= bytes;
}
return (0);
}
int
random_get_bytes(uint8_t *ptr, size_t len)
{
if (force_pseudo)
return (random_get_pseudo_bytes(ptr, len));
return (random_get_bytes_common(ptr, len, random_fd));
}
int
random_get_pseudo_bytes(uint8_t *ptr, size_t len)
{
return (random_get_bytes_common(ptr, len, urandom_fd));
}
+108
View File
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <assert.h>
#include <pthread.h>
#include <errno.h>
#include <atomic.h>
#include <sys/rwlock.h>
/*
* =========================================================================
* rwlocks
* =========================================================================
*/
void
rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
{
(void) name, (void) type, (void) arg;
VERIFY0(pthread_rwlock_init(&rwlp->rw_lock, NULL));
rwlp->rw_readers = 0;
rwlp->rw_owner = 0;
}
void
rw_destroy(krwlock_t *rwlp)
{
VERIFY0(pthread_rwlock_destroy(&rwlp->rw_lock));
}
void
rw_enter(krwlock_t *rwlp, krw_t rw)
{
if (rw == RW_READER) {
VERIFY0(pthread_rwlock_rdlock(&rwlp->rw_lock));
atomic_inc_uint(&rwlp->rw_readers);
} else {
VERIFY0(pthread_rwlock_wrlock(&rwlp->rw_lock));
rwlp->rw_owner = pthread_self();
}
}
void
rw_exit(krwlock_t *rwlp)
{
if (RW_READ_HELD(rwlp))
atomic_dec_uint(&rwlp->rw_readers);
else
rwlp->rw_owner = 0;
VERIFY0(pthread_rwlock_unlock(&rwlp->rw_lock));
}
int
rw_tryenter(krwlock_t *rwlp, krw_t rw)
{
int error;
if (rw == RW_READER)
error = pthread_rwlock_tryrdlock(&rwlp->rw_lock);
else
error = pthread_rwlock_trywrlock(&rwlp->rw_lock);
if (error == 0) {
if (rw == RW_READER)
atomic_inc_uint(&rwlp->rw_readers);
else
rwlp->rw_owner = pthread_self();
return (1);
}
VERIFY3S(error, ==, EBUSY);
return (0);
}
int
rw_tryupgrade(krwlock_t *rwlp)
{
(void) rwlp;
return (0);
}
+47
View File
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <sys/sid.h>
#include <umem.h>
ksiddomain_t *
ksid_lookupdomain(const char *dom)
{
ksiddomain_t *kd;
kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
kd->kd_name = strdup(dom);
return (kd);
}
void
ksiddomain_rele(ksiddomain_t *ksid)
{
free(ksid->kd_name);
umem_free(ksid, sizeof (ksiddomain_t));
}
@@ -29,11 +29,27 @@
* Copyright (c) 2014 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
#include <sys/sysmacros.h>
#include <sys/timer.h>
#include <sys/types.h>
#include <sys/thread.h>
#include <sys/taskq.h>
#include <sys/kmem.h>
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;
@@ -106,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) {
@@ -373,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);
@@ -400,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));
}
+118
View File
@@ -0,0 +1,118 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <assert.h>
#include <pthread.h>
#include <string.h>
#include <sys/thread.h>
/* this only exists to have its address taken */
void p0(void) {}
/*
* =========================================================================
* threads
* =========================================================================
*
* TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While
* TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for
* the expected stack depth while small enough to avoid exhausting address
* space with high thread counts.
*/
#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768)
#define TS_STACK_MAX (256 * 1024)
struct zk_thread_wrapper {
void (*func)(void *);
void *arg;
};
static void *
zk_thread_wrapper(void *arg)
{
struct zk_thread_wrapper ztw;
memcpy(&ztw, arg, sizeof (ztw));
free(arg);
ztw.func(ztw.arg);
return (NULL);
}
kthread_t *
zk_thread_create(const char *name, void (*func)(void *), void *arg,
size_t stksize, int state)
{
pthread_attr_t attr;
pthread_t tid;
char *stkstr;
struct zk_thread_wrapper *ztw;
int detachstate = PTHREAD_CREATE_DETACHED;
VERIFY0(pthread_attr_init(&attr));
if (state & TS_JOINABLE)
detachstate = PTHREAD_CREATE_JOINABLE;
VERIFY0(pthread_attr_setdetachstate(&attr, detachstate));
/*
* We allow the default stack size in user space to be specified by
* setting the ZFS_STACK_SIZE environment variable. This allows us
* the convenience of observing and debugging stack overruns in
* user space. Explicitly specified stack sizes will be honored.
* The usage of ZFS_STACK_SIZE is discussed further in the
* ENVIRONMENT VARIABLES sections of the ztest(1) man page.
*/
if (stksize == 0) {
stkstr = getenv("ZFS_STACK_SIZE");
if (stkstr == NULL)
stksize = TS_STACK_MAX;
else
stksize = MAX(atoi(stkstr), TS_STACK_MIN);
}
VERIFY3S(stksize, >, 0);
stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);
/*
* If this ever fails, it may be because the stack size is not a
* multiple of system page size.
*/
VERIFY0(pthread_attr_setstacksize(&attr, stksize));
VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));
VERIFY(ztw = malloc(sizeof (*ztw)));
ztw->func = func;
ztw->arg = arg;
VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw));
VERIFY0(pthread_attr_destroy(&attr));
pthread_setname_np(tid, name);
return ((void *)(uintptr_t)tid);
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -70,7 +70,7 @@ if BUILD_FREEBSD
libzfs_la_LIBADD += -lutil -lgeom
endif
libzfs_la_LDFLAGS += -version-info 6:0:0
libzfs_la_LDFLAGS += -version-info 7:0:0
pkgconfig_DATA += %D%/libzfs.pc
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More