aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsys/contrib/openzfs/.github/workflows/scripts/generate-ci-type.py10
-rwxr-xr-xsys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh20
-rw-r--r--sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml2
-rw-r--r--sys/contrib/openzfs/.github/workflows/zfs-qemu.yml38
-rw-r--r--sys/contrib/openzfs/.mailmap8
-rw-r--r--sys/contrib/openzfs/AUTHORS14
-rw-r--r--sys/contrib/openzfs/META2
-rw-r--r--sys/contrib/openzfs/README.md2
-rwxr-xr-xsys/contrib/openzfs/autogen.sh61
-rw-r--r--sys/contrib/openzfs/cmd/zdb/zdb.c8
-rw-r--r--sys/contrib/openzfs/cmd/zfs/zfs_project.c36
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_main.c34
-rw-r--r--sys/contrib/openzfs/cmd/ztest.c39
-rw-r--r--sys/contrib/openzfs/config/deb.am8
-rw-r--r--sys/contrib/openzfs/contrib/debian/Makefile.am8
-rw-r--r--sys/contrib/openzfs/contrib/debian/clean4
-rw-r--r--sys/contrib/openzfs/contrib/debian/control26
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.docs (renamed from sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.docs)0
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.install.in (renamed from sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.install.in)0
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.docs (renamed from sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.docs)0
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.install.in (renamed from sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.install.in)0
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/mod.h3
-rw-r--r--sys/contrib/openzfs/include/sys/brt.h1
-rw-r--r--sys/contrib/openzfs/include/sys/brt_impl.h2
-rw-r--r--sys/contrib/openzfs/include/sys/dmu.h8
-rw-r--r--sys/contrib/openzfs/include/sys/fs/zfs.h4
-rw-r--r--sys/contrib/openzfs/include/sys/spa.h14
-rw-r--r--sys/contrib/openzfs/include/sys/vdev_impl.h1
-rw-r--r--sys/contrib/openzfs/include/sys/zfs_project.h10
-rw-r--r--sys/contrib/openzfs/lib/libnvpair/Makefile.am2
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/Makefile.am1
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h33
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/tunables.h12
-rw-r--r--sys/contrib/openzfs/lib/libuutil/libuutil.abi69
-rw-r--r--sys/contrib/openzfs/lib/libzfs/Makefile.am2
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs.abi83
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c2
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_pool.c8
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c5
-rw-r--r--sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c37
-rw-r--r--sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi70
-rw-r--r--sys/contrib/openzfs/lib/libzfsbootenv/libzfsbootenv.abi2
-rw-r--r--sys/contrib/openzfs/lib/libzpool/Makefile.am2
-rw-r--r--sys/contrib/openzfs/lib/libzpool/kernel.c4
-rw-r--r--sys/contrib/openzfs/man/man4/zfs.442
-rw-r--r--sys/contrib/openzfs/man/man7/vdevprops.78
-rw-r--r--sys/contrib/openzfs/man/man7/zpoolconcepts.75
-rw-r--r--sys/contrib/openzfs/man/man8/zfs-jail.879
-rw-r--r--sys/contrib/openzfs/man/man8/zfs-rewrite.822
-rw-r--r--sys/contrib/openzfs/man/man8/zpool-events.873
-rw-r--r--sys/contrib/openzfs/man/man8/zpool-prefetch.827
-rw-r--r--sys/contrib/openzfs/module/Kbuild.in3
-rw-r--r--sys/contrib/openzfs/module/Makefile.bsd24
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c5
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c10
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c8
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c3
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c4
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c20
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c2
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c12
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c3
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c3
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c93
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c6
-rw-r--r--sys/contrib/openzfs/module/zcommon/zpool_prop.c3
-rw-r--r--sys/contrib/openzfs/module/zfs/arc.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/bpobj.c7
-rw-r--r--sys/contrib/openzfs/module/zfs/bptree.c9
-rw-r--r--sys/contrib/openzfs/module/zfs/brt.c48
-rw-r--r--sys/contrib/openzfs/module/zfs/dbuf.c5
-rw-r--r--sys/contrib/openzfs/module/zfs/ddt_log.c7
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu.c27
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_redact.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/dnode.c156
-rw-r--r--sys/contrib/openzfs/module/zfs/metaslab.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/mmp.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/spa.c281
-rw-r--r--sys/contrib/openzfs/module/zfs/spa_checkpoint.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/spa_config.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/spa_history.c5
-rw-r--r--sys/contrib/openzfs/module/zfs/spa_misc.c110
-rw-r--r--sys/contrib/openzfs/module/zfs/space_map.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev.c86
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_indirect_births.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_indirect_mapping.c5
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_initialize.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_label.c33
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_raidz.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_rebuild.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_removal.c20
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_trim.c12
-rw-r--r--sys/contrib/openzfs/module/zfs/zap_micro.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_fm.c9
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_fuid.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_ioctl.c41
-rw-r--r--sys/contrib/openzfs/module/zfs/zio.c13
-rw-r--r--sys/contrib/openzfs/module/zfs/zio_inject.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/zvol.c9
-rw-r--r--sys/contrib/openzfs/module/zstd/include/aarch64_compat.h38
-rw-r--r--sys/contrib/openzfs/module/zstd/lib/common/compiler.h3
-rw-r--r--sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h9
-rw-r--r--sys/contrib/openzfs/rpm/generic/zfs.spec.in44
-rw-r--r--sys/contrib/openzfs/scripts/Makefile.am4
-rwxr-xr-xsys/contrib/openzfs/scripts/zfs-tests.sh4
-rwxr-xr-xsys/contrib/openzfs/scripts/zfs2zol-patch.sed32
-rwxr-xr-xsys/contrib/openzfs/scripts/zol2zfs-patch.sed20
-rw-r--r--sys/contrib/openzfs/tests/runfiles/common.run2
-rwxr-xr-xsys/contrib/openzfs/tests/test-runner/bin/test-runner.py.in33
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am1
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_get/vdev_get.cfg1
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh12
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_002_pos.ksh95
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_slow_io.ksh44
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh2
115 files changed, 1386 insertions, 1059 deletions
diff --git a/sys/contrib/openzfs/.github/workflows/scripts/generate-ci-type.py b/sys/contrib/openzfs/.github/workflows/scripts/generate-ci-type.py
index 08021aabcb61..059d6ad3872b 100755
--- a/sys/contrib/openzfs/.github/workflows/scripts/generate-ci-type.py
+++ b/sys/contrib/openzfs/.github/workflows/scripts/generate-ci-type.py
@@ -7,7 +7,7 @@ Prints "quick" if (explicity required by user):
- 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 @@ if __name__ == '__main__':
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 @@ if __name__ == '__main__':
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([
diff --git a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
index 422b3e9df388..5bdd84ca2435 100755
--- a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
+++ b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
@@ -47,16 +47,15 @@ case "$OS" in
OSNAME="Archlinux"
URL="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.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"
- # 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"
- ;;
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"
diff --git a/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml b/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml
index d8a95954fe1a..6367fb3a6ce2 100644
--- a/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml
+++ b/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml
@@ -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
diff --git a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml
index f1b189062bb7..2436b3d73e56 100644
--- a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml
+++ b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml
@@ -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:
diff --git a/sys/contrib/openzfs/.mailmap b/sys/contrib/openzfs/.mailmap
index e6f09c6c9d43..3397fbc3745d 100644
--- a/sys/contrib/openzfs/.mailmap
+++ b/sys/contrib/openzfs/.mailmap
@@ -53,6 +53,7 @@ Jason Harmening <jason.harmening@gmail.com>
Jeremy Faulkner <gldisater@gmail.com>
Jinshan Xiong <jinshan.xiong@gmail.com>
John Poduska <jpoduska@datto.com>
+Jo Zzsi <jozzsicsataban@gmail.com>
Justin Scholz <git@justinscholz.de>
Ka Ho Ng <khng300@gmail.com>
Kash Pande <github@tripleback.net>
@@ -67,6 +68,7 @@ Michael Gmelin <grembo@FreeBSD.org>
Olivier Mazouffre <olivier.mazouffre@ims-bordeaux.fr>
Piotr Kubaj <pkubaj@anongoth.pl>
Quentin Zdanis <zdanisq@gmail.com>
+Roberto Ricci <io@r-ricci.it>
Roberto Ricci <ricci@disroot.org>
Rob Norris <robn@despairlabs.com>
Rob Norris <rob.norris@klarasystems.com>
@@ -83,7 +85,10 @@ Youzhong Yang <youzhong@gmail.com>
# Signed-off-by: overriding Author:
Alexander Ziaee <ziaee@FreeBSD.org> <concussious@runbox.com>
Felix Schmidt <felixschmidt20@aol.com> <f.sch.prototype@gmail.com>
+Jean-Sébastien Pédron <dumbbell@FreeBSD.org> <jean-sebastien.pedron@dumbbell.fr>
+Konstantin Belousov <kib@FreeBSD.org> <kib@kib.kiev.ua>
Olivier Certner <olce@FreeBSD.org> <olce.freebsd@certner.fr>
+Patrick Xia <patrickx@google.com> <octalc0de@aim.com>
Phil Sutter <phil@nwl.cc> <p.github@nwl.cc>
poscat <poscat@poscat.moe> <poscat0x04@outlook.com>
Qiuhao Chen <chenqiuhao1997@gmail.com> <haohao0924@126.com>
@@ -125,6 +130,7 @@ buzzingwires <buzzingwires@outlook.com> <131118055+buzzingwires@users.noreply.gi
Cedric Maunoury <cedric.maunoury@gmail.com> <38213715+cedricmaunoury@users.noreply.github.com>
Charles Suh <charles.suh@gmail.com> <charlessuh@users.noreply.github.com>
Chris Peredun <chris.peredun@ixsystems.com> <126915832+chrisperedun@users.noreply.github.com>
+classabbyamp <dev@placeviolette.net> <5366828+classabbyamp@users.noreply.github.com>
Dacian Reece-Stremtan <dacianstremtan@gmail.com> <35844628+dacianstremtan@users.noreply.github.com>
Damian Szuberski <szuberskidamian@gmail.com> <30863496+szubersk@users.noreply.github.com>
Daniel Hiepler <d-git@coderdu.de> <32984777+heeplr@users.noreply.github.com>
@@ -185,6 +191,7 @@ Michael Niewöhner <foss@mniewoehner.de> <c0d3z3r0@users.noreply.github.com>
Michael Zhivich <mzhivich@akamai.com> <33133421+mzhivich@users.noreply.github.com>
MigeljanImeri <ImeriMigel@gmail.com> <78048439+MigeljanImeri@users.noreply.github.com>
Mo Zhou <cdluminate@gmail.com> <5723047+cdluminate@users.noreply.github.com>
+nav1s <nav1s@proton.me> <42621369+nav1s@users.noreply.github.com>
Nick Mattis <nickm970@gmail.com> <nmattis@users.noreply.github.com>
omni <omni+vagant@hack.org> <79493359+omnivagant@users.noreply.github.com>
Pablo Correa Gómez <ablocorrea@hotmail.com> <32678034+pablofsf@users.noreply.github.com>
@@ -206,6 +213,7 @@ Samuel Wycliffe <samuelwycliffe@gmail.com> <50765275+npc203@users.noreply.github
Savyasachee Jha <hi@savyasacheejha.com> <savyajha@users.noreply.github.com>
Scott Colby <scott@scolby.com> <scolby33@users.noreply.github.com>
Sean Eric Fagan <kithrup@mac.com> <kithrup@users.noreply.github.com>
+Shreshth Srivastava <shreshthsrivastava2@gmail.com> <66148173+Shreshth3@users.noreply.github.com>
Spencer Kinny <spencerkinny1995@gmail.com> <30333052+Spencer-Kinny@users.noreply.github.com>
Srikanth N S <srikanth.nagasubbaraoseetharaman@hpe.com> <75025422+nssrikanth@users.noreply.github.com>
Stefan Lendl <s.lendl@proxmox.com> <1321542+stfl@users.noreply.github.com>
diff --git a/sys/contrib/openzfs/AUTHORS b/sys/contrib/openzfs/AUTHORS
index 6c34c07f39ef..e496c0e8a807 100644
--- a/sys/contrib/openzfs/AUTHORS
+++ b/sys/contrib/openzfs/AUTHORS
@@ -154,6 +154,7 @@ CONTRIBUTORS:
Chris Zubrzycki <github@mid-earth.net>
Chuck Tuffli <ctuffli@gmail.com>
Chunwei Chen <david.chen@nutanix.com>
+ classabbyamp <dev@placeviolette.net>
Clemens Fruhwirth <clemens@endorphin.org>
Clemens Lang <cl@clang.name>
Clint Armstrong <clint@clintarmstrong.net>
@@ -161,6 +162,7 @@ CONTRIBUTORS:
Colin Ian King <colin.king@canonical.com>
Colin Percival <cperciva@tarsnap.com>
Colm Buckley <colm@tuatha.org>
+ Cong Zhang <congzhangzh@users.noreply.github.com>
Crag Wang <crag0715@gmail.com>
Craig Loomis <cloomis@astro.princeton.edu>
Craig Sanders <github@taz.net.au>
@@ -217,6 +219,7 @@ CONTRIBUTORS:
Eitan Adler <lists@eitanadler.com>
Eli Rosenthal <eli.rosenthal@delphix.com>
Eli Schwartz <eschwartz93@gmail.com>
+ Eric A. Borisch <eborisch@gmail.com>
Eric Desrochers <eric.desrochers@canonical.com>
Eric Dillmann <eric@jave.fr>
Eric Schrock <Eric.Schrock@delphix.com>
@@ -288,6 +291,7 @@ CONTRIBUTORS:
Henrik Riomar <henrik.riomar@gmail.com>
Herb Wartens <wartens2@llnl.gov>
Hiếu Lê <leorize+oss@disroot.org>
+ hoshinomori <hoshinomorimorimo@gmail.com>
Huang Liu <liu.huang@zte.com.cn>
HÃ¥kan Johansson <f96hajo@chalmers.se>
Igor K <igor@dilos.org>
@@ -300,6 +304,7 @@ CONTRIBUTORS:
ilovezfs <ilovezfs@icloud.com>
InsanePrawn <Insane.Prawny@gmail.com>
Isaac Huang <he.huang@intel.com>
+ Ivan Shapovalov <intelfx@intelfx.name>
Ivan Volosyuk <Ivan.Volosyuk@gmail.com>
Jacek Fefliński <feflik@gmail.com>
Jacob Adams <tookmund@gmail.com>
@@ -322,6 +327,7 @@ CONTRIBUTORS:
Javen Wu <wu.javen@gmail.com>
Jaydeep Kshirsagar <jkshirsagar@maxlinear.com>
Jean-Baptiste Lallement <jean-baptiste@ubuntu.com>
+ Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
Jeff Dike <jdike@akamai.com>
Jeremy Faulkner <gldisater@gmail.com>
Jeremy Gill <jgill@parallax-innovations.com>
@@ -355,7 +361,9 @@ CONTRIBUTORS:
Josh Soref <jsoref@users.noreply.github.com>
Joshua M. Clulow <josh@sysmgr.org>
José Luis Salvador Rufo <salvador.joseluis@gmail.com>
+ Jo Zzsi <jozzsicsataban@gmail.com>
João Carlos Mendes Luís <jonny@jonny.eng.br>
+ JT Pennington <jt.pennington@klarasystems.com>
Julian Brunner <julian.brunner@gmail.com>
Julian Heuking <JulianH@beckhoff.com>
jumbi77 <jumbi77@users.noreply.github.com>
@@ -388,6 +396,7 @@ CONTRIBUTORS:
Kleber Tarcísio <klebertarcisio@yahoo.com.br>
Kody A Kantor <kody.kantor@gmail.com>
Kohsuke Kawaguchi <kk@kohsuke.org>
+ Konstantin Belousov <kib@FreeBSD.org>
Konstantin Khorenko <khorenko@virtuozzo.com>
KORN Andras <korn@elan.rulez.org>
kotauskas <v.toncharov@gmail.com>
@@ -416,6 +425,7 @@ CONTRIBUTORS:
luozhengzheng <luo.zhengzheng@zte.com.cn>
Luís Henriques <henrix@camandro.org>
Madhav Suresh <madhav.suresh@delphix.com>
+ Maksym Shkolnyi <maksym.shkolnyi@workato.com>
manfromafar <jonsonb10@gmail.com>
Manoj Joseph <manoj.joseph@delphix.com>
Manuel Amador (Rudd-O) <rudd-o@rudd-o.com>
@@ -482,6 +492,7 @@ CONTRIBUTORS:
Nathaniel Clark <Nathaniel.Clark@misrule.us>
Nathaniel Wesley Filardo <nwf@cs.jhu.edu>
Nathan Lewis <linux.robotdude@gmail.com>
+ nav1s <nav1s@proton.me>
Nav Ravindranath <nav@delphix.com>
Neal Gompa (ニール・ゴンパ) <ngompa13@gmail.com>
Ned Bass <bass6@llnl.gov>
@@ -506,6 +517,7 @@ CONTRIBUTORS:
Palash Gandhi <pbg4930@rit.edu>
Patrick Fasano <patrick@patrickfasano.com>
Patrick Mooney <pmooney@pfmooney.com>
+ Patrick Xia <patrickx@google.com>
Patrik Greco <sikevux@sikevux.se>
Paul B. Henson <henson@acm.org>
Paul Dagnelie <pcd@delphix.com>
@@ -605,6 +617,7 @@ CONTRIBUTORS:
Shengqi Chen <harry-chen@outlook.com>
SHENGYI HONG <aokblast@FreeBSD.org>
Shen Yan <shenyanxxxy@qq.com>
+ Shreshth Srivastava <shreshthsrivastava2@gmail.com>
Sietse <sietse@wizdom.nu>
Simon Guest <simon.guest@tesujimath.org>
Simon Howard <fraggle@soulsphere.org>
@@ -665,6 +678,7 @@ CONTRIBUTORS:
Toyam Cox <aviator45003@gmail.com>
Trevor Bautista <trevrb@trevrb.net>
Trey Dockendorf <treydock@gmail.com>
+ trick2011 <trick2011@users.noreply.github.com>
Troels Nørgaard <tnn@tradeshift.com>
tstabrawa <tstabrawa@users.noreply.github.com>
Tulsi Jain <tulsi.jain@delphix.com>
diff --git a/sys/contrib/openzfs/META b/sys/contrib/openzfs/META
index 2bfa51841cc4..da43a41ab824 100644
--- a/sys/contrib/openzfs/META
+++ b/sys/contrib/openzfs/META
@@ -2,7 +2,7 @@ Meta: 1
Name: zfs
Branch: 1.0
Version: 2.4.0
-Release: rc3
+Release: rc4
Release-Tags: relext
License: CDDL
Author: OpenZFS
diff --git a/sys/contrib/openzfs/README.md b/sys/contrib/openzfs/README.md
index a90736bb56b7..a39b88fedd12 100644
--- a/sys/contrib/openzfs/README.md
+++ b/sys/contrib/openzfs/README.md
@@ -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)
diff --git a/sys/contrib/openzfs/autogen.sh b/sys/contrib/openzfs/autogen.sh
index 39eb82203d69..5cb152474698 100755
--- a/sys/contrib/openzfs/autogen.sh
+++ b/sys/contrib/openzfs/autogen.sh
@@ -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
diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c
index 2560ad045db3..fa8e7fa691db 100644
--- a/sys/contrib/openzfs/cmd/zdb/zdb.c
+++ b/sys/contrib/openzfs/cmd/zdb/zdb.c
@@ -7899,11 +7899,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 +10022,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,
diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_project.c b/sys/contrib/openzfs/cmd/zfs/zfs_project.c
index fbf5e6cbdc68..8925e6672bef 100644
--- a/sys/contrib/openzfs/cmd/zfs/zfs_project.c
+++ b/sys/contrib/openzfs/cmd/zfs/zfs_project.c
@@ -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);
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
index 1feec55c0e8b..18952775bcfe 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
@@ -494,8 +494,7 @@ get_usage(zpool_help_t idx)
"[--json-int, --json-pool-key-guid]] ...\n"
"\t [-T d|u] [pool] [interval [count]]\n"));
case HELP_PREFETCH:
- return (gettext("\tprefetch -t <type> [<type opts>] <pool>\n"
- "\t -t ddt <pool>\n"));
+ return (gettext("\tprefetch [-t <type>] <pool>\n"));
case HELP_OFFLINE:
return (gettext("\toffline [--power]|[[-f][-t]] <pool> "
"<device> ...\n"));
@@ -4200,7 +4199,7 @@ zpool_do_checkpoint(int argc, char **argv)
#define CHECKPOINT_OPT 1024
/*
- * zpool prefetch <type> [<type opts>] <pool>
+ * zpool prefetch [-t <type>] <pool>
*
* Prefetchs a particular type of data in the specified pool.
*/
@@ -4245,20 +4244,27 @@ zpool_do_prefetch(int argc, char **argv)
poolname = argv[0];
- argc--;
- argv++;
-
- if (strcmp(typestr, "ddt") == 0) {
- type = ZPOOL_PREFETCH_DDT;
- } else {
- (void) fprintf(stderr, gettext("unsupported prefetch type\n"));
- usage(B_FALSE);
- }
-
if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
return (1);
- err = zpool_prefetch(zhp, type);
+ if (typestr == NULL) {
+ /* Prefetch all types */
+ err = zpool_prefetch(zhp, ZPOOL_PREFETCH_DDT);
+ if (err == 0)
+ err = zpool_prefetch(zhp, ZPOOL_PREFETCH_BRT);
+ } else {
+ if (strcmp(typestr, "ddt") == 0) {
+ type = ZPOOL_PREFETCH_DDT;
+ } else if (strcmp(typestr, "brt") == 0) {
+ type = ZPOOL_PREFETCH_BRT;
+ } else {
+ (void) fprintf(stderr,
+ gettext("unsupported prefetch type\n"));
+ zpool_close(zhp);
+ usage(B_FALSE);
+ }
+ err = zpool_prefetch(zhp, type);
+ }
zpool_close(zhp);
diff --git a/sys/contrib/openzfs/cmd/ztest.c b/sys/contrib/openzfs/cmd/ztest.c
index 89752dcb0f0f..89b1f68606ea 100644
--- a/sys/contrib/openzfs/cmd/ztest.c
+++ b/sys/contrib/openzfs/cmd/ztest.c
@@ -1228,10 +1228,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 +1246,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 +2306,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 +3689,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 +3976,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 +5244,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 +5260,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 +5516,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 +6123,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 +7427,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
@@ -8541,11 +8546,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
diff --git a/sys/contrib/openzfs/config/deb.am b/sys/contrib/openzfs/config/deb.am
index 9e58e1905b73..3e9a9379712e 100644
--- a/sys/contrib/openzfs/config/deb.am
+++ b/sys/contrib/openzfs/config/deb.am
@@ -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,
diff --git a/sys/contrib/openzfs/contrib/debian/Makefile.am b/sys/contrib/openzfs/contrib/debian/Makefile.am
index 99d512312df6..3c219856005e 100644
--- a/sys/contrib/openzfs/contrib/debian/Makefile.am
+++ b/sys/contrib/openzfs/contrib/debian/Makefile.am
@@ -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
diff --git a/sys/contrib/openzfs/contrib/debian/clean b/sys/contrib/openzfs/contrib/debian/clean
index 4f52d01b8108..caabcd30c62a 100644
--- a/sys/contrib/openzfs/contrib/debian/clean
+++ b/sys/contrib/openzfs/contrib/debian/clean
@@ -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
diff --git a/sys/contrib/openzfs/contrib/debian/control b/sys/contrib/openzfs/contrib/debian/control
index c5358dedc0fd..a886c2e86cc5 100644
--- a/sys/contrib/openzfs/contrib/debian/control
+++ b/sys/contrib/openzfs/contrib/debian/control
@@ -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}
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.docs
index 4302f1b2ab6a..4302f1b2ab6a 100644
--- a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.docs
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.docs
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.install.in
index a9054c14cc73..a9054c14cc73 100644
--- a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.install.in
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.install.in
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.docs
index 4302f1b2ab6a..4302f1b2ab6a 100644
--- a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.docs
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.docs
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.install.in
index 0e087a2709b3..0e087a2709b3 100644
--- a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.install.in
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.install.in
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod.h
index 4214189c32df..2aa66bbe19b7 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod.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"
diff --git a/sys/contrib/openzfs/include/sys/brt.h b/sys/contrib/openzfs/include/sys/brt.h
index d7c1814b084f..2a23a6a7f75d 100644
--- a/sys/contrib/openzfs/include/sys/brt.h
+++ b/sys/contrib/openzfs/include/sys/brt.h
@@ -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
}
diff --git a/sys/contrib/openzfs/include/sys/brt_impl.h b/sys/contrib/openzfs/include/sys/brt_impl.h
index 1805d21b16b2..1843e6d988cd 100644
--- a/sys/contrib/openzfs/include/sys/brt_impl.h
+++ b/sys/contrib/openzfs/include/sys/brt_impl.h
@@ -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
diff --git a/sys/contrib/openzfs/include/sys/dmu.h b/sys/contrib/openzfs/include/sys/dmu.h
index aa5035862def..aae99d71ba7c 100644
--- a/sys/contrib/openzfs/include/sys/dmu.h
+++ b/sys/contrib/openzfs/include/sys/dmu.h
@@ -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,
diff --git a/sys/contrib/openzfs/include/sys/fs/zfs.h b/sys/contrib/openzfs/include/sys/fs/zfs.h
index 662fd81c5ee1..830c8455bb1a 100644
--- a/sys/contrib/openzfs/include/sys/fs/zfs.h
+++ b/sys/contrib/openzfs/include/sys/fs/zfs.h
@@ -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 {
diff --git a/sys/contrib/openzfs/include/sys/spa.h b/sys/contrib/openzfs/include/sys/spa.h
index f172f2af6f07..2a4cc60c4aa8 100644
--- a/sys/contrib/openzfs/include/sys/spa.h
+++ b/sys/contrib/openzfs/include/sys/spa.h
@@ -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
diff --git a/sys/contrib/openzfs/include/sys/vdev_impl.h b/sys/contrib/openzfs/include/sys/vdev_impl.h
index 5a8c2f846be2..afaa401343d9 100644
--- a/sys/contrib/openzfs/include/sys/vdev_impl.h
+++ b/sys/contrib/openzfs/include/sys/vdev_impl.h
@@ -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;
};
diff --git a/sys/contrib/openzfs/include/sys/zfs_project.h b/sys/contrib/openzfs/include/sys/zfs_project.h
index 714c87a0d441..a368f49e14f5 100644
--- a/sys/contrib/openzfs/include/sys/zfs_project.h
+++ b/sys/contrib/openzfs/include/sys/zfs_project.h
@@ -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) */
diff --git a/sys/contrib/openzfs/lib/libnvpair/Makefile.am b/sys/contrib/openzfs/lib/libnvpair/Makefile.am
index 87b8d32aa175..0b3f964781b0 100644
--- a/sys/contrib/openzfs/lib/libnvpair/Makefile.am
+++ b/sys/contrib/openzfs/lib/libnvpair/Makefile.am
@@ -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
diff --git a/sys/contrib/openzfs/lib/libspl/include/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/Makefile.am
index 21f0c70db9e7..746cb12bf637 100644
--- a/sys/contrib/openzfs/lib/libspl/include/Makefile.am
+++ b/sys/contrib/openzfs/lib/libspl/include/Makefile.am
@@ -78,6 +78,7 @@ libspl_sys_HEADERS += \
%D%/os/linux/sys/param.h \
%D%/os/linux/sys/stat.h \
%D%/os/linux/sys/sysmacros.h \
+ %D%/os/linux/sys/vfs.h \
%D%/os/linux/sys/zfs_context_os.h
libspl_ia32_HEADERS = \
diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h
new file mode 100644
index 000000000000..c7b567ff44a4
--- /dev/null
+++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or https://opensource.org/licenses/CDDL-1.0.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* Copyright 2025 by Lawrence Livermore National Security, LLC. */
+
+/* This is the Linux userspace version of include/os/linux/spl/sys/vfs.h */
+
+#ifndef _LIBSPL_SYS_VFS_H
+#define _LIBSPL_SYS_VFS_H
+
+#include <linux/fs.h>
+#include <sys/statfs.h>
+
+#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h b/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h
index 5d9bb3d71a4a..c85400f6fd28 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/tunables.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
diff --git a/sys/contrib/openzfs/lib/libuutil/libuutil.abi b/sys/contrib/openzfs/lib/libuutil/libuutil.abi
index 2a740afa07ca..52a00d9830b1 100644
--- a/sys/contrib/openzfs/lib/libuutil/libuutil.abi
+++ b/sys/contrib/openzfs/lib/libuutil/libuutil.abi
@@ -244,10 +244,6 @@
<elf-symbol name='uu_strerror' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='uu_strndup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='uu_zalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
</elf-function-symbols>
<abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'>
<typedef-decl name='__pid_t' type-id='95e97e5e' id='3629bad8'/>
@@ -1310,52 +1306,12 @@
</function-decl>
</abi-instr>
<abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'>
- <enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/>
- <enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/>
- <enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/>
- <enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/>
- <enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/>
- </enum-decl>
- <typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/>
- <enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/>
- <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/>
- </enum-decl>
- <typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/>
- <class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zt_name' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='zt_type' type-id='f50b1525' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='zt_perm' type-id='ada7336b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='zt_desc' type-id='80f4b756' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/>
- <typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/>
<typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/>
<typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/>
<typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/>
<typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/>
<pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
<qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
- <qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/>
- <pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/>
- <pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/>
<function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'>
<parameter type-id='9d26089a'/>
<parameter type-id='8c85230f'/>
@@ -1368,31 +1324,6 @@
<parameter type-id='95e97e5e'/>
<return type-id='f8b828c9'/>
</function-decl>
- <function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'>
- <parameter type-id='80f4b756' name='name'/>
- <return type-id='a27af98c'/>
- </function-decl>
- <function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
- <parameter type-id='d8d5f4ab' name='cb'/>
- <parameter type-id='eaa32e2f' name='arg'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
- <parameter type-id='a27af98c' name='zt'/>
- <parameter type-id='80f4b756' name='val'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'>
- <parameter type-id='a27af98c' name='zt'/>
- <parameter type-id='26a90f95' name='val'/>
- <parameter type-id='b59d7dce' name='valsz'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-type size-in-bits='64' id='92f86508'>
- <parameter type-id='a27af98c'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
</abi-instr>
<abi-instr address-size='64' path='lib/libuutil/uu_alloc.c' language='LANG_C99'>
<type-decl name='char' size-in-bits='8' id='a84c031d'/>
diff --git a/sys/contrib/openzfs/lib/libzfs/Makefile.am b/sys/contrib/openzfs/lib/libzfs/Makefile.am
index 5f8963dccd1a..e2cbca47b9a3 100644
--- a/sys/contrib/openzfs/lib/libzfs/Makefile.am
+++ b/sys/contrib/openzfs/lib/libzfs/Makefile.am
@@ -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
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs.abi b/sys/contrib/openzfs/lib/libzfs/libzfs.abi
index f988d27a286a..9ce2ffa55df9 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs.abi
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs.abi
@@ -1,4 +1,4 @@
-<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfs.so.6'>
+<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfs.so.7'>
<elf-needed>
<dependency name='libzfs_core.so.3'/>
<dependency name='libnvpair.so.3'/>
@@ -451,10 +451,6 @@
<elf-symbol name='zfs_strip_partition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_strip_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_truncate_shares' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_type_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_unmount' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_unmountall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -1497,50 +1493,10 @@
</function-decl>
</abi-instr>
<abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'>
- <enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/>
- <enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/>
- <enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/>
- <enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/>
- <enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/>
- </enum-decl>
- <typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/>
- <enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/>
- <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/>
- </enum-decl>
- <typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/>
- <class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zt_name' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='zt_type' type-id='f50b1525' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='zt_perm' type-id='ada7336b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='zt_desc' type-id='80f4b756' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/>
- <typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/>
<typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/>
<typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/>
<typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/>
<typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/>
- <qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/>
- <pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/>
- <pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/>
<function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'>
<parameter type-id='9d26089a'/>
<parameter type-id='8c85230f'/>
@@ -1553,31 +1509,6 @@
<parameter type-id='95e97e5e'/>
<return type-id='f8b828c9'/>
</function-decl>
- <function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'>
- <parameter type-id='80f4b756' name='name'/>
- <return type-id='a27af98c'/>
- </function-decl>
- <function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
- <parameter type-id='d8d5f4ab' name='cb'/>
- <parameter type-id='eaa32e2f' name='arg'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
- <parameter type-id='a27af98c' name='zt'/>
- <parameter type-id='80f4b756' name='val'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'>
- <parameter type-id='a27af98c' name='zt'/>
- <parameter type-id='26a90f95' name='val'/>
- <parameter type-id='b59d7dce' name='valsz'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-type size-in-bits='64' id='92f86508'>
- <parameter type-id='a27af98c'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
</abi-instr>
<abi-instr address-size='64' path='lib/libtpool/thread_pool.c' language='LANG_C99'>
<array-type-def dimensions='1' type-id='49ef3ffd' size-in-bits='1024' id='a14403f5'>
@@ -1808,10 +1739,6 @@
<parameter type-id='7292109c'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='__pthread_unregister_cancel' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='ba7c727c'/>
- <return type-id='48b5725f'/>
- </function-decl>
<function-decl name='pthread_cond_init' visibility='default' binding='global' size-in-bits='64'>
<parameter type-id='2a468b41'/>
<parameter type-id='4c428e67'/>
@@ -6026,7 +5953,8 @@
<enumerator name='VDEV_PROP_SLOW_IOS' value='51'/>
<enumerator name='VDEV_PROP_SIT_OUT' value='52'/>
<enumerator name='VDEV_PROP_AUTOSIT' value='53'/>
- <enumerator name='VDEV_NUM_PROPS' value='54'/>
+ <enumerator name='VDEV_PROP_SLOW_IO_EVENTS' value='54'/>
+ <enumerator name='VDEV_NUM_PROPS' value='55'/>
</enum-decl>
<typedef-decl name='vdev_prop_t' type-id='1573bec8' id='5aa5c90c'/>
<class-decl name='zpool_load_policy' size-in-bits='256' is-struct='yes' visibility='default' id='2f65b36f'>
@@ -6250,6 +6178,7 @@
<underlying-type type-id='9cac1fee'/>
<enumerator name='ZPOOL_PREFETCH_NONE' value='0'/>
<enumerator name='ZPOOL_PREFETCH_DDT' value='1'/>
+ <enumerator name='ZPOOL_PREFETCH_BRT' value='2'/>
</enum-decl>
<typedef-decl name='zpool_prefetch_type_t' type-id='0299ab50' id='e55ff6bc'/>
<enum-decl name='zpool_ddt_prune_unit_t' naming-typedef-id='02e25ab0' id='509ae11c'>
@@ -7988,6 +7917,10 @@
<parameter type-id='ba7c727c'/>
<return type-id='48b5725f'/>
</function-decl>
+ <function-decl name='__pthread_unregister_cancel' visibility='default' binding='global' size-in-bits='64'>
+ <parameter type-id='ba7c727c'/>
+ <return type-id='48b5725f'/>
+ </function-decl>
<function-decl name='__pthread_unwind_next' visibility='default' binding='global' size-in-bits='64'>
<parameter type-id='ba7c727c'/>
<return type-id='48b5725f'/>
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c b/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c
index b34a44c30eb4..f7cc1e84f804 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c
@@ -613,7 +613,9 @@ get_key_material_https(libzfs_handle_t *hdl, const char *uri,
(void) unlink(path);
free(path);
+#ifdef O_TMPFILE
kfdok:
+#endif
if ((key = fdopen(kfd, "r+")) == NULL) {
ret = errno;
(void) close(kfd);
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c
index ce154ae1a4cd..756d701e2d97 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c
@@ -1745,9 +1745,13 @@ zpool_prefetch(zpool_handle_t *zhp, zpool_prefetch_type_t type)
error = lzc_pool_prefetch(zhp->zpool_name, type);
if (error != 0) {
+ const char *typename = "unknown";
+ if (type == ZPOOL_PREFETCH_DDT)
+ typename = "ddt";
+ else if (type == ZPOOL_PREFETCH_BRT)
+ typename = "brt";
(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
- "cannot prefetch %s in '%s'"),
- type == ZPOOL_PREFETCH_DDT ? "ddt" : "", zhp->zpool_name);
+ "cannot prefetch %s in '%s'"), typename, zhp->zpool_name);
(void) zpool_standard_error(hdl, error, msg);
return (-1);
}
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
index 77134d197904..0e5cecc6cca9 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
@@ -1013,7 +1013,8 @@ send_progress_thread(void *arg)
&blocks)) != 0) {
if (err == EINTR || err == ENOENT)
err = 0;
- pthread_exit(((void *)(uintptr_t)err));
+ /* Use break to reach pthread_cleanup_pop() below. */
+ break;
}
(void) time(&t);
@@ -1055,7 +1056,7 @@ send_progress_thread(void *arg)
}
}
pthread_cleanup_pop(B_TRUE);
- return (NULL);
+ pthread_exit(((void *)(uintptr_t)err));
}
static boolean_t
diff --git a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c
index 55dfdf3723bd..651d407b1884 100644
--- a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c
+++ b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c
@@ -78,6 +78,38 @@ libzfs_error_init(int error)
}
}
+static int
+in_container(void)
+{
+ char buffer[4096];
+ ssize_t count;
+ int fd;
+
+ if (access("/run/systemd/container", R_OK) == 0)
+ return (1);
+
+ fd = open("/proc/1/cgroup", O_RDONLY);
+ if (fd == -1)
+ return (0);
+
+ count = read(fd, buffer, sizeof (buffer) - 1);
+ close(fd);
+
+ if (count <= 0)
+ return (0);
+
+ buffer[count] = '\0';
+
+ if (strstr(buffer, "docker") ||
+ strstr(buffer, "containerd") ||
+ strstr(buffer, "kubepods") ||
+ strstr(buffer, "lxc")) {
+ return (1);
+ }
+
+ return (0);
+}
+
/*
* zfs(4) is loaded by udev if there's a fstype=zfs device present,
* but if there isn't, load them automatically;
@@ -104,6 +136,11 @@ libzfs_load_module(void)
const char *timeout_str = getenv("ZFS_MODULE_TIMEOUT");
int seconds = 10;
+
+ /* Set timeout to zero if inside of a container */
+ if (in_container())
+ seconds = 0;
+
if (timeout_str)
seconds = MIN(strtol(timeout_str, NULL, 0), 600);
struct itimerspec timeout = {.it_value.tv_sec = MAX(seconds, 0)};
diff --git a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi
index 263cad045f7a..7f3c8f2ff0d7 100644
--- a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi
+++ b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi
@@ -222,10 +222,6 @@
<elf-symbol name='spl_pagesize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='strlcat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='strlcpy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
</elf-function-symbols>
<abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'>
<class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='d5027220'>
@@ -1256,52 +1252,12 @@
</function-decl>
</abi-instr>
<abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'>
- <enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/>
- <enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/>
- <enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/>
- <enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/>
- <enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/>
- </enum-decl>
- <typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/>
- <enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/>
- <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/>
- </enum-decl>
- <typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/>
- <class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zt_name' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='zt_type' type-id='f50b1525' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='zt_perm' type-id='ada7336b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='zt_desc' type-id='80f4b756' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/>
- <typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/>
<typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/>
<typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/>
<typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/>
<typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/>
<pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
<qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
- <qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/>
- <pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/>
- <pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/>
<function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'>
<parameter type-id='9d26089a'/>
<parameter type-id='8c85230f'/>
@@ -1319,31 +1275,6 @@
<parameter type-id='80f4b756'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'>
- <parameter type-id='80f4b756' name='name'/>
- <return type-id='a27af98c'/>
- </function-decl>
- <function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
- <parameter type-id='d8d5f4ab' name='cb'/>
- <parameter type-id='eaa32e2f' name='arg'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
- <parameter type-id='a27af98c' name='zt'/>
- <parameter type-id='80f4b756' name='val'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'>
- <parameter type-id='a27af98c' name='zt'/>
- <parameter type-id='26a90f95' name='val'/>
- <parameter type-id='b59d7dce' name='valsz'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-type size-in-bits='64' id='92f86508'>
- <parameter type-id='a27af98c'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
</abi-instr>
<abi-instr address-size='64' path='lib/libzfs_core/libzfs_core.c' language='LANG_C99'>
<array-type-def dimensions='1' type-id='03085adc' size-in-bits='192' id='083f8d58'>
@@ -1709,6 +1640,7 @@
<underlying-type type-id='9cac1fee'/>
<enumerator name='ZPOOL_PREFETCH_NONE' value='0'/>
<enumerator name='ZPOOL_PREFETCH_DDT' value='1'/>
+ <enumerator name='ZPOOL_PREFETCH_BRT' value='2'/>
</enum-decl>
<typedef-decl name='zpool_prefetch_type_t' type-id='0299ab50' id='e55ff6bc'/>
<enum-decl name='zpool_ddt_prune_unit_t' naming-typedef-id='02e25ab0' id='509ae11c'>
diff --git a/sys/contrib/openzfs/lib/libzfsbootenv/libzfsbootenv.abi b/sys/contrib/openzfs/lib/libzfsbootenv/libzfsbootenv.abi
index bf866b0fa61b..e2b492a0780d 100644
--- a/sys/contrib/openzfs/lib/libzfsbootenv/libzfsbootenv.abi
+++ b/sys/contrib/openzfs/lib/libzfsbootenv/libzfsbootenv.abi
@@ -1,6 +1,6 @@
<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfsbootenv.so.1'>
<elf-needed>
- <dependency name='libzfs.so.6'/>
+ <dependency name='libzfs.so.7'/>
<dependency name='libnvpair.so.3'/>
<dependency name='libc.so.6'/>
</elf-needed>
diff --git a/sys/contrib/openzfs/lib/libzpool/Makefile.am b/sys/contrib/openzfs/lib/libzpool/Makefile.am
index aeacc595b363..4658e025ea53 100644
--- a/sys/contrib/openzfs/lib/libzpool/Makefile.am
+++ b/sys/contrib/openzfs/lib/libzpool/Makefile.am
@@ -212,7 +212,7 @@ if BUILD_FREEBSD
libzpool_la_LIBADD += -lgeom
endif
-libzpool_la_LDFLAGS += -version-info 6:0:0
+libzpool_la_LDFLAGS += -version-info 7:0:0
if TARGET_CPU_POWERPC
module/zfs/libzpool_la-vdev_raidz_math_powerpc_altivec.$(OBJEXT) : CFLAGS += -maltivec
diff --git a/sys/contrib/openzfs/lib/libzpool/kernel.c b/sys/contrib/openzfs/lib/libzpool/kernel.c
index 70eba5099119..452462a1700b 100644
--- a/sys/contrib/openzfs/lib/libzpool/kernel.c
+++ b/sys/contrib/openzfs/lib/libzpool/kernel.c
@@ -903,7 +903,7 @@ spa_config_load(void)
* Iterate over all elements in the nvlist, creating a new spa_t for
* each one with the specified configuration.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
nvpair = NULL;
while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) {
if (nvpair_type(nvpair) != DATA_TYPE_NVLIST)
@@ -915,7 +915,7 @@ spa_config_load(void)
continue;
(void) spa_add(nvpair_name(nvpair), child, NULL);
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
nvlist_free(nvlist);
diff --git a/sys/contrib/openzfs/man/man4/zfs.4 b/sys/contrib/openzfs/man/man4/zfs.4
index 11bcbf430210..60ec56b4d1f6 100644
--- a/sys/contrib/openzfs/man/man4/zfs.4
+++ b/sys/contrib/openzfs/man/man4/zfs.4
@@ -273,12 +273,12 @@ force this many of them to be gang blocks.
.It Sy brt_zap_prefetch Ns = Ns Sy 1 Ns | Ns 0 Pq int
Controls prefetching BRT records for blocks which are going to be cloned.
.
-.It Sy brt_zap_default_bs Ns = Ns Sy 12 Po 4 KiB Pc Pq int
+.It Sy brt_zap_default_bs Ns = Ns Sy 13 Po 8 KiB Pc Pq int
Default BRT ZAP data block size as a power of 2. Note that changing this after
creating a BRT on the pool will not affect existing BRTs, only newly created
ones.
.
-.It Sy brt_zap_default_ibs Ns = Ns Sy 12 Po 4 KiB Pc Pq int
+.It Sy brt_zap_default_ibs Ns = Ns Sy 13 Po 8 KiB Pc Pq int
Default BRT ZAP indirect block size as a power of 2. Note that changing this
after creating a BRT on the pool will not affect existing BRTs, only newly
created ones.
@@ -2660,12 +2660,50 @@ Set value only applies to pools imported/created after that.
Set the queue and thread configuration for the IO read queues.
This is an advanced debugging parameter.
Don't change this unless you understand what it does.
+Each of the four values corresponds to the issue, issue high-priority,
+interrupt, and interrupt high-priority queues.
+Valid values are
+.Sy fixed,N,M
+(M queues with N threads each),
+.Sy scale[,MIN]
+(scale with CPUs, minimum MIN total threads),
+.Sy sync ,
+and
+.Sy null .
Set values only apply to pools imported/created after that.
.
.It Sy zio_taskq_write Ns = Ns Sy sync null scale null Pq charp
Set the queue and thread configuration for the IO write queues.
This is an advanced debugging parameter.
Don't change this unless you understand what it does.
+Each of the four values corresponds to the issue, issue high-priority,
+interrupt, and interrupt high-priority queues.
+Valid values are
+.Sy fixed,N,M
+(M queues with N threads each),
+.Sy scale[,MIN]
+(scale with CPUs, minimum MIN total threads),
+.Sy sync ,
+and
+.Sy null .
+Set values only apply to pools imported/created after that.
+.
+.It Sy zio_taskq_free Ns = Ns Sy scale,32 null null null Pq charp
+Set the queue and thread configuration for the IO free queues.
+This is an advanced debugging parameter.
+Don't change this unless you understand what it does.
+Each of the four values corresponds to the issue, issue high-priority,
+interrupt, and interrupt high-priority queues.
+Valid values are
+.Sy fixed,N,M
+(M queues with N threads each),
+.Sy scale[,MIN]
+(scale with CPUs, minimum MIN total threads),
+.Sy sync ,
+and
+.Sy null .
+The default uses a minimum of 32 threads to improve parallelism for
+DDT and BRT metadata operations during frees.
Set values only apply to pools imported/created after that.
.
.It Sy zvol_inhibit_dev Ns = Ns Sy 0 Ns | Ns 1 Pq uint
diff --git a/sys/contrib/openzfs/man/man7/vdevprops.7 b/sys/contrib/openzfs/man/man7/vdevprops.7
index 0fb28d7db13c..b54abcd3ecc9 100644
--- a/sys/contrib/openzfs/man/man7/vdevprops.7
+++ b/sys/contrib/openzfs/man/man7/vdevprops.7
@@ -45,7 +45,7 @@ section, below.
Every vdev has a set of properties that export statistics about the vdev
as well as control various behaviors.
Properties are not inherited from top-level vdevs, with the exception of
-checksum_n, checksum_t, io_n, io_t, slow_io_n, and slow_io_t.
+checksum_n, checksum_t, io_n, io_t, slow_io_events, slow_io_n, and slow_io_t.
.Pp
The values of numeric properties can be specified using human-readable suffixes
.Po for example,
@@ -149,6 +149,12 @@ For
.Sy OpenZFS on FreeBSD
defaults see
.Xr zfsd 8 .
+The
+.It Sy slow_io_events
+property controls whether slow I/O events are generated.
+Even when disabled, slow I/Os will be included in the
+.Nm zpool Cm status Fl s
+output.
.It Sy comment
A text comment up to 8192 characters long
.It Sy bootsize
diff --git a/sys/contrib/openzfs/man/man7/zpoolconcepts.7 b/sys/contrib/openzfs/man/man7/zpoolconcepts.7
index b9c8926d835d..21bd72351209 100644
--- a/sys/contrib/openzfs/man/man7/zpoolconcepts.7
+++ b/sys/contrib/openzfs/man/man7/zpoolconcepts.7
@@ -469,6 +469,11 @@ then rewind it during import:
.Dl # Nm zpool Cm export Ar pool
.Dl # Nm zpool Cm import Fl -rewind-to-checkpoint Ar pool
.Pp
+Note that rewinding to a checkpoint will
+.Sy permanently discard it.
+Once the pool has been successfully imported with the above rewind command,
+you cannot rewind to the same checkpoint.
+.Pp
To discard the checkpoint from a pool:
.Dl # Nm zpool Cm checkpoint Fl d Ar pool
.Pp
diff --git a/sys/contrib/openzfs/man/man8/zfs-jail.8 b/sys/contrib/openzfs/man/man8/zfs-jail.8
index 569f5f57eab4..8f94a1bd4d81 100644
--- a/sys/contrib/openzfs/man/man8/zfs-jail.8
+++ b/sys/contrib/openzfs/man/man8/zfs-jail.8
@@ -37,7 +37,7 @@
.\" Copyright 2018 Nexenta Systems, Inc.
.\" Copyright 2019 Joyent, Inc.
.\"
-.Dd July 11, 2022
+.Dd November 4, 2025
.Dt ZFS-JAIL 8
.Os
.
@@ -53,9 +53,42 @@
.Ar filesystem
.
.Sh DESCRIPTION
-.Bl -tag -width ""
+The
+.Nm
+functionality can be used to assign a dataset onto a running
+.Fx
+system
+.Xr jail 4 ,
+allowing
+.Xr zfs 8
+management utilities to be run inside of the
+.Xr jail 4 .
+.Pp
+To allow management of the dataset from within a jail, the
+.Sy jailed
+property should be set and the required
+.Xr devfs.conf 5
+entries to expose
+.Pa /dev/zfs
+device within the jail must be present.
+The
+.Sy quota
+property cannot be changed from within a jail.
+.Pp
+To use this functionality, the jail needs the
+.Sy allow.mount
+and
+.Sy allow.mount.zfs
+parameters set to
+.Sy 1
+and the
+.Sy enforce_statfs
+parameter set to a value lower than
+.Sy 2 .
+.Pp
+The subcommands are as follows:
+.Bl -tag -width indent
.It Xo
-.Nm zfs
.Cm jail
.Ar jailid Ns | Ns Ar jailname
.Ar filesystem
@@ -69,16 +102,6 @@ or name
From now on this file system tree can be managed from within a jail if the
.Sy jailed
property has been set.
-To use this functionality, the jail needs the
-.Sy allow.mount
-and
-.Sy allow.mount.zfs
-parameters set to
-.Sy 1
-and the
-.Sy enforce_statfs
-parameter set to a value lower than
-.Sy 2 .
.Pp
You cannot attach a jailed dataset's children to another jail.
You can also not attach the root file system
@@ -86,29 +109,12 @@ of the jail or any dataset which needs to be mounted before the zfs rc script
is run inside the jail, as it would be attached unmounted until it is
mounted from the rc script inside the jail.
.Pp
-To allow management of the dataset from within a jail, the
-.Sy jailed
-property has to be set and the jail needs access to the
-.Pa /dev/zfs
-device.
-The
-.Sy quota
-property cannot be changed from within a jail.
-.Pp
After a dataset is attached to a jail and the
.Sy jailed
property is set, a jailed file system cannot be mounted outside the jail,
since the jail administrator might have set the mount point to an unacceptable
value.
-.Pp
-See
-.Xr jail 8
-for more information on managing jails.
-Jails are a
-.Fx
-feature and are not relevant on other platforms.
.It Xo
-.Nm zfs
.Cm unjail
.Ar jailid Ns | Ns Ar jailname
.Ar filesystem
@@ -121,5 +127,18 @@ or name
.Ar jailname .
.El
.Sh SEE ALSO
+.Xr devfs.conf 5 ,
.Xr zfsprops 7 ,
.Xr jail 8
+.Sh CAVEATS
+The root directory of jail can not be delegated to the jail with this
+utility because the jail must be running with a valid root directory.
+.Pp
+Jails are a
+.Fx
+feature and are not relevant on other platforms.
+See
+.Xr jail 8
+for more information on managing jails, or
+.Xr zfs-zone 8
+for the equivelant functionality on Linux.
diff --git a/sys/contrib/openzfs/man/man8/zfs-rewrite.8 b/sys/contrib/openzfs/man/man8/zfs-rewrite.8
index ca5340c7e5eb..ae0a1588293e 100644
--- a/sys/contrib/openzfs/man/man8/zfs-rewrite.8
+++ b/sys/contrib/openzfs/man/man8/zfs-rewrite.8
@@ -20,8 +20,9 @@
.\" CDDL HEADER END
.\"
.\" Copyright (c) 2025 iXsystems, Inc.
+.\" Copyright (c) 2025, Klara, Inc.
.\"
-.Dd July 23, 2025
+.Dd November 5, 2025
.Dt ZFS-REWRITE 8
.Os
.
@@ -39,9 +40,10 @@
.Sh DESCRIPTION
Rewrite blocks of specified
.Ar file
-as is without modification at a new location and possibly with new
-properties, such as checksum, compression, dedup, copies, etc,
+as is without modification at a new location and possibly with new properties,
as if they were atomically read and written back.
+.No See Sx NOTES .
+for more information about property changes that may be applied during rewrite.
.Bl -tag -width "-r"
.It Fl P
Perform physical rewrite, preserving logical birth time of blocks.
@@ -64,6 +66,20 @@ Print names of all successfully rewritten files.
Don't cross file system mount points when recursing.
.El
.Sh NOTES
+Rewrite works by replacing an existing block with a new block of the same
+logical size.
+Changed dataset properties that operate on the data or metadata without
+changing the logical size will be applied.
+These include
+.Sy checksum ,
+.Sy compression ,
+.Sy dedup
+and
+.Sy copies .
+Changes to properties that affect the size of a logical block, like
+.Sy recordsize ,
+will have no effect.
+.Pp
Rewrite of cloned blocks and blocks that are part of any snapshots,
same as some property changes may increase pool space usage.
Holes that were never written or were previously zero-compressed are
diff --git a/sys/contrib/openzfs/man/man8/zpool-events.8 b/sys/contrib/openzfs/man/man8/zpool-events.8
index 36a9864dc73b..3753139bdfe7 100644
--- a/sys/contrib/openzfs/man/man8/zpool-events.8
+++ b/sys/contrib/openzfs/man/man8/zpool-events.8
@@ -113,17 +113,19 @@ See
for more details on the
.Sy zfs_vdev_direct_write_verify
module parameter.
-.It Sy config
+.It Sy config_sync
Issued every time a vdev change have been done to the pool.
.It Sy zpool
Issued when a pool cannot be imported.
-.It Sy zpool.destroy
+.It Sy pool_create
+Issued when a pool is created.
+.It Sy pool_destroy
Issued when a pool is destroyed.
-.It Sy zpool.export
+.It Sy pool_export
Issued when a pool is exported.
-.It Sy zpool.import
+.It Sy pool_import
Issued when a pool is imported.
-.It Sy zpool.reguid
+.It Sy pool_reguid
Issued when a REGUID (new unique identifier for the pool have been regenerated)
have been detected.
.It Sy vdev.unknown
@@ -150,21 +152,31 @@ event.
Issued when the label is OK but invalid.
.It Sy vdev.bad_ashift
Issued when the ashift alignment requirement has increased.
-.It Sy vdev.remove
+.It Sy vdev_remove
Issued when a vdev is detached from a mirror (or a spare detached from a
vdev where it have been used to replace a failed drive - only works if
the original drive have been re-added).
-.It Sy vdev.clear
+.It Sy vdev_remove_aux
+Issued when an auxiliary vdev is removed.
+.It Sy vdev_remove_dev
+Issued when a specific device is removed from a vdev.
+.It Sy vdev_clear
Issued when clearing device errors in a pool.
Such as running
.Nm zpool Cm clear
on a device in the pool.
-.It Sy vdev.check
+.It Sy vdev_check
Issued when a check to see if a given vdev could be opened is started.
-.It Sy vdev.spare
+.It Sy vdev_spare
Issued when a spare have kicked in to replace a failed device.
-.It Sy vdev.autoexpand
+.It Sy vdev_autoexpand
Issued when a vdev can be automatically expanded.
+.It Sy vdev_add
+Issued when a vdev is added to a pool.
+.It Sy vdev_attach
+Issued when a vdev is attached to a mirror or raidz vdev type.
+.It Sy vdev_online
+Issued when an offline vdev is brought online
.It Sy io_failure
Issued when there is an I/O failure in a vdev in the pool.
.It Sy probe_failure
@@ -175,21 +187,46 @@ have removed the device).
.It Sy log_replay
Issued when the intent log cannot be replayed.
The can occur in the case of a missing or damaged log device.
-.It Sy resilver.start
+.It Sy resilver_start
Issued when a resilver is started.
-.It Sy resilver.finish
+.It Sy resilver_finish
Issued when the running resilver have finished.
-.It Sy scrub.start
+.It Sy scrub_start
Issued when a scrub is started on a pool.
-.It Sy scrub.finish
+.It Sy scrub_finish
Issued when a pool has finished scrubbing.
-.It Sy scrub.abort
+.It Sy scrub_abort
Issued when a scrub is aborted on a pool.
-.It Sy scrub.resume
+.It Sy scrub_resume
Issued when a scrub is resumed on a pool.
-.It Sy scrub.paused
+.It Sy scrub_paused
Issued when a scrub is paused on a pool.
-.It Sy bootfs.vdev.attach
+.It Sy errorscrub_start
+Issued when a errorscrub is started on a pool.
+.It Sy errorscrub_finish
+Issued when a pool has finished errorscrubbing.
+.It Sy errorscrub_abort
+Issued when a errorscrub is aborted on a pool.
+.It Sy errorscrub_resume
+Issued when a errorscrub is resumed on a pool.
+.It Sy errorscrub_paused
+Issued when a errorscrub is paused on a pool.
+.It Sy trim_start
+Issued when a trim is started on a pool.
+.It Sy trim_finish
+Issued when a pool has finished trimbing.
+.It Sy trim_cancel
+Issued when a trim is canceled on a pool.
+.It Sy trim_resume
+Issued when a trim is resumed on a pool.
+.It Sy trim_suspend
+Issued when a trim is suspend on a pool.
+.It Sy authentication
+Issued when there is a decryption / authentication error.
+.It Sy config_cache_write
+Issued when the config cache file cannot be written.
+.It Sy bootfs_vdev_attach
+Issued when a vdev is attached to a root pool with the bootfs property set.
.It Sy sitout
Issued when a
.Sy RAIDZ
diff --git a/sys/contrib/openzfs/man/man8/zpool-prefetch.8 b/sys/contrib/openzfs/man/man8/zpool-prefetch.8
index a36ad52e681e..6f4c3b129040 100644
--- a/sys/contrib/openzfs/man/man8/zpool-prefetch.8
+++ b/sys/contrib/openzfs/man/man8/zpool-prefetch.8
@@ -28,20 +28,25 @@
.
.Sh NAME
.Nm zpool-prefetch
-.Nd Loads specific types of data for the given pool
+.Nd Prefetches pool metadata into ARC
.Sh SYNOPSIS
.Nm zpool
.Cm prefetch
-.Fl t Ar type
+.Op Fl t Ar type
.Ar pool
.Sh DESCRIPTION
-.Bl -tag -width Ds
-.It Xo
-.Nm zpool
-.Cm prefetch
-.Fl t Li ddt
-.Ar pool
-.Xc
-Prefetch data of a specific type for the given pool; specifically the DDT,
-which will improve write I/O performance when the DDT is resident in the ARC.
+Massively prefetch metadata of a specific type for the given pool into the ARC
+to reduce latency of some operations later.
+If no type is specified, all types are prefetched.
+.Pp
+The following types are supported:
+.Bl -tag -width "brt"
+.It Sy brt
+Prefetch the BRT (block reference table).
+This may improve performance for block cloning operations,
+and frees for earlier cloned blocks.
+.It Sy ddt
+Prefetch the DDT (deduplication table).
+This may improve performance of writes when deduplication is enabled,
+and frees for earlier deduplicated blocks.
.El
diff --git a/sys/contrib/openzfs/module/Kbuild.in b/sys/contrib/openzfs/module/Kbuild.in
index 58a80dc4402c..95313c984178 100644
--- a/sys/contrib/openzfs/module/Kbuild.in
+++ b/sys/contrib/openzfs/module/Kbuild.in
@@ -293,10 +293,9 @@ ZSTD_UPSTREAM_OBJS := \
zfs-objs += $(addprefix zstd/,$(ZSTD_OBJS) $(ZSTD_UPSTREAM_OBJS))
-# Disable aarch64 neon SIMD instructions for kernel mode
$(addprefix $(obj)/zstd/,$(ZSTD_OBJS) $(ZSTD_UPSTREAM_OBJS)) : ccflags-y += -I$(zstd_include) $(ZFS_ZSTD_FLAGS)
$(addprefix $(obj)/zstd/,$(ZSTD_OBJS) $(ZSTD_UPSTREAM_OBJS)) : asflags-y += -I$(zstd_include)
-$(addprefix $(obj)/zstd/,$(ZSTD_UPSTREAM_OBJS)) : ccflags-y += -include $(zstd_include)/aarch64_compat.h -include $(zstd_include)/zstd_compat_wrapper.h -Wp,-w
+$(addprefix $(obj)/zstd/,$(ZSTD_UPSTREAM_OBJS)) : ccflags-y += -include $(zstd_include)/zstd_compat_wrapper.h -Wp,-w
$(obj)/zstd/zfs_zstd.o : ccflags-y += -include $(zstd_include)/zstd_compat_wrapper.h
diff --git a/sys/contrib/openzfs/module/Makefile.bsd b/sys/contrib/openzfs/module/Makefile.bsd
index 3ba38c43f25b..c20fdc0c483b 100644
--- a/sys/contrib/openzfs/module/Makefile.bsd
+++ b/sys/contrib/openzfs/module/Makefile.bsd
@@ -521,30 +521,6 @@ CFLAGS.zstd_ldm.c= -U__BMI__ -fno-tree-vectorize ${NO_WBITWISE_INSTEAD_OF_LOGICA
CFLAGS.zstd_opt.c= -U__BMI__ -fno-tree-vectorize ${NO_WBITWISE_INSTEAD_OF_LOGICAL}
.if ${MACHINE_ARCH} == "aarch64"
-__ZFS_ZSTD_AARCH64_FLAGS= -include ${SRCDIR}/zstd/include/aarch64_compat.h
-CFLAGS.zstd.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.entropy_common.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.error_private.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.fse_compress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.fse_decompress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.hist.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.huf_compress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.huf_decompress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.pool.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.xxhash.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_common.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_compress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_compress_literals.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_compress_sequences.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_compress_superblock.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_ddict.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_decompress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_decompress_block.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_double_fast.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_fast.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_lazy.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_ldm.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
-CFLAGS.zstd_opt.c+= ${__ZFS_ZSTD_AARCH64_FLAGS}
sha256-armv8.o: sha256-armv8.S
${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC} \
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c
index 26cc7981bfcd..1990ec677d37 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c
@@ -76,7 +76,7 @@ dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
return (0);
err = dmu_buf_hold_array(os, object, offset, size,
- FALSE, FTAG, &numbufs, &dbp);
+ FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH);
if (err)
return (err);
@@ -147,7 +147,8 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
ASSERT3S(last_size, <=, PAGE_SIZE);
err = dmu_buf_hold_array(os, object, IDX_TO_OFF(ma[0]->pindex),
- IDX_TO_OFF(count - 1) + last_size, TRUE, FTAG, &numbufs, &dbp);
+ IDX_TO_OFF(count - 1) + last_size, TRUE, FTAG, &numbufs, &dbp,
+ DMU_READ_PREFETCH);
if (err != 0)
return (err);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c
index 2d04ccf95fbf..d918b26521a7 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c
@@ -193,7 +193,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind)
*/
config = spa_generate_rootconf(name);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if (config != NULL) {
pname = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
VERIFY0(strcmp(name, pname));
@@ -204,7 +204,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind)
* e.g., after reboot -r.
*/
if (spa->spa_state == POOL_STATE_ACTIVE) {
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
fnvlist_free(config);
return (0);
}
@@ -226,7 +226,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind)
&spa->spa_ubsync.ub_version) != 0)
spa->spa_ubsync.ub_version = SPA_VERSION_INITIAL;
} else if ((spa = spa_lookup(name)) == NULL) {
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
fnvlist_free(config);
cmn_err(CE_NOTE, "Cannot find the pool label for '%s'",
name);
@@ -249,7 +249,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind)
VDEV_ALLOC_ROOTPOOL);
spa_config_exit(spa, SCL_ALL, FTAG);
if (error) {
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
fnvlist_free(config);
cmn_err(CE_NOTE, "Can not parse the config for pool '%s'",
name);
@@ -259,7 +259,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind)
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
vdev_free(rvd);
spa_config_exit(spa, SCL_ALL, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
fnvlist_free(config);
return (0);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c
index 11e93b800a54..9663f05cb354 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c
@@ -42,7 +42,8 @@ vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size)
spa_t *spa = vd->vdev_spa;
zio_t *zio;
abd_t *pad2;
- int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL;
+ int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL |
+ ZIO_FLAG_TRYHARD;
int error;
if (size > VDEV_PAD_SIZE)
@@ -59,16 +60,11 @@ vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size)
abd_copy_from_buf(pad2, buf, size);
abd_zero_off(pad2, size, VDEV_PAD_SIZE - size);
-retry:
zio = zio_root(spa, NULL, NULL, flags);
vdev_label_write(zio, vd, 0, pad2,
offsetof(vdev_label_t, vl_be),
VDEV_PAD_SIZE, NULL, NULL, flags);
error = zio_wait(zio);
- if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) {
- flags |= ZIO_FLAG_TRYHARD;
- goto retry;
- }
abd_free(pad2);
return (error);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c
index cb5787269db2..c98ccd756405 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c
@@ -1262,7 +1262,8 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
if (aclnode->z_ace_count == 0)
continue;
dmu_write(zfsvfs->z_os, aoid, off,
- aclnode->z_size, aclnode->z_acldata, tx);
+ aclnode->z_size, aclnode->z_acldata, tx,
+ DMU_READ_NO_PREFETCH);
off += aclnode->z_size;
}
} else {
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c
index dcdefae56639..29711fcf5d2c 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c
@@ -108,11 +108,11 @@ zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl)
"command", &command) != 0)
return (EINVAL);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa = spa_by_guid(pool_guid, vdev_guid);
if (spa != NULL)
strcpy(name, spa_name(spa));
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
if (spa == NULL)
return (ENOENT);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
index f34a2fd37a77..8a9d23d0d554 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
@@ -278,7 +278,7 @@ zfs_ioctl_getxattr(vnode_t *vp, zfsxattr_t *fsx)
memset(fsx, 0, sizeof (*fsx));
fsx->fsx_xflags = (zp->z_pflags & ZFS_PROJINHERIT) ?
- ZFS_PROJINHERIT_FL : 0;
+ FS_PROJINHERIT_FL : 0;
fsx->fsx_projid = zp->z_projid;
return (0);
@@ -290,7 +290,7 @@ zfs_ioctl_setflags(vnode_t *vp, uint32_t ioctl_flags, xvattr_t *xva)
uint64_t zfs_flags = VTOZ(vp)->z_pflags;
xoptattr_t *xoap;
- if (ioctl_flags & ~(ZFS_PROJINHERIT_FL))
+ if (ioctl_flags & ~(FS_PROJINHERIT_FL))
return (SET_ERROR(EOPNOTSUPP));
xva_init(xva);
@@ -304,7 +304,7 @@ zfs_ioctl_setflags(vnode_t *vp, uint32_t ioctl_flags, xvattr_t *xva)
} \
} while (0)
- FLAG_CHANGE(ZFS_PROJINHERIT_FL, ZFS_PROJINHERIT, XAT_PROJINHERIT,
+ FLAG_CHANGE(FS_PROJINHERIT_FL, ZFS_PROJINHERIT, XAT_PROJINHERIT,
xoap->xoa_projinherit);
#undef FLAG_CHANGE
@@ -4479,7 +4479,8 @@ zfs_putpages(struct vnode *vp, vm_page_t *ma, size_t len, int flags,
for (i = 0; wlen > 0; woff += tocopy, wlen -= tocopy, i++) {
tocopy = MIN(PAGE_SIZE, wlen);
va = zfs_map_page(ma[i], &sf);
- dmu_write(zfsvfs->z_os, zp->z_id, woff, tocopy, va, tx);
+ dmu_write(zfsvfs->z_os, zp->z_id, woff, tocopy, va, tx,
+ DMU_READ_PREFETCH);
zfs_unmap_page(sf);
}
} else {
@@ -5757,7 +5758,7 @@ zfs_freebsd_pathconf(struct vop_pathconf_args *ap)
{
ulong_t val;
int error;
-#ifdef _PC_CLONE_BLKSIZE
+#if defined(_PC_CLONE_BLKSIZE) || defined(_PC_CASE_INSENSITIVE)
zfsvfs_t *zfsvfs;
#endif
@@ -5821,6 +5822,15 @@ zfs_freebsd_pathconf(struct vop_pathconf_args *ap)
*ap->a_retval = 0;
return (0);
#endif
+#ifdef _PC_CASE_INSENSITIVE
+ case _PC_CASE_INSENSITIVE:
+ zfsvfs = (zfsvfs_t *)ap->a_vp->v_mount->mnt_data;
+ if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE)
+ *ap->a_retval = 1;
+ else
+ *ap->a_retval = 0;
+ return (0);
+#endif
default:
return (vop_stdpathconf(ap));
}
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c
index 91cf38016e00..8562c42b3220 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c
@@ -437,6 +437,7 @@ zio_crypt_key_wrap(crypto_key_t *cwkey, zio_crypt_key_t *key, uint8_t *iv,
ASSERT3U(crypt, <, ZIO_CRYPT_FUNCTIONS);
+ memset(&cuio_s, 0, sizeof (cuio_s));
zfs_uio_init(&cuio, &cuio_s);
keydata_len = zio_crypt_table[crypt].ci_keylen;
@@ -519,6 +520,7 @@ zio_crypt_key_unwrap(crypto_key_t *cwkey, uint64_t crypt, uint64_t version,
keydata_len = zio_crypt_table[crypt].ci_keylen;
rw_init(&key->zk_salt_lock, NULL, RW_DEFAULT, NULL);
+ memset(&cuio_s, 0, sizeof (cuio_s));
zfs_uio_init(&cuio, &cuio_s);
/*
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
index 0dd2ecd7fd8d..4efcea9419ed 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
@@ -282,8 +282,8 @@ retry:
* Take spa_namespace_lock to prevent lock inversion when
* zvols from one pool are opened as vdevs in another.
*/
- if (!mutex_owned(&spa_namespace_lock)) {
- if (!mutex_tryenter(&spa_namespace_lock)) {
+ if (!spa_namespace_held()) {
+ if (!spa_namespace_tryenter(FTAG)) {
mutex_exit(&zv->zv_state_lock);
rw_exit(&zv->zv_suspend_lock);
drop_suspend = B_FALSE;
@@ -295,7 +295,7 @@ retry:
}
err = zvol_first_open(zv, !(flag & FWRITE));
if (drop_namespace)
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
if (err)
goto out_locked;
pp->mediasize = zv->zv_volsize;
@@ -962,8 +962,8 @@ retry:
* Take spa_namespace_lock to prevent lock inversion when
* zvols from one pool are opened as vdevs in another.
*/
- if (!mutex_owned(&spa_namespace_lock)) {
- if (!mutex_tryenter(&spa_namespace_lock)) {
+ if (!spa_namespace_held()) {
+ if (!spa_namespace_tryenter(FTAG)) {
mutex_exit(&zv->zv_state_lock);
rw_exit(&zv->zv_suspend_lock);
drop_suspend = B_FALSE;
@@ -975,7 +975,7 @@ retry:
}
err = zvol_first_open(zv, !(flags & FWRITE));
if (drop_namespace)
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
if (err)
goto out_locked;
}
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c
index 934d74a112fd..4c929a4642b1 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c
@@ -1447,7 +1447,8 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
if (aclnode->z_ace_count == 0)
continue;
dmu_write(zfsvfs->z_os, aoid, off,
- aclnode->z_size, aclnode->z_acldata, tx);
+ aclnode->z_size, aclnode->z_acldata, tx,
+ DMU_READ_NO_PREFETCH);
off += aclnode->z_size;
}
} else {
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c
index e845ad69ad78..02465adf36d5 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c
@@ -3892,7 +3892,8 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
va = kmap(pp);
ASSERT3U(pglen, <=, PAGE_SIZE);
- dmu_write(zfsvfs->z_os, zp->z_id, pgoff, pglen, va, tx);
+ dmu_write(zfsvfs->z_os, zp->z_id, pgoff, pglen, va, tx,
+ DMU_READ_PREFETCH);
kunmap(pp);
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
index 02965ac8cbee..f7691c02d163 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
@@ -811,28 +811,44 @@ zpl_fadvise(struct file *filp, loff_t offset, loff_t len, int advice)
return (error);
}
-#define ZFS_FL_USER_VISIBLE (FS_FL_USER_VISIBLE | ZFS_PROJINHERIT_FL)
-#define ZFS_FL_USER_MODIFIABLE (FS_FL_USER_MODIFIABLE | ZFS_PROJINHERIT_FL)
+#define ZFS_FL_USER_VISIBLE (FS_FL_USER_VISIBLE | FS_PROJINHERIT_FL)
+#define ZFS_FL_USER_MODIFIABLE (FS_FL_USER_MODIFIABLE | FS_PROJINHERIT_FL)
+
+
+static struct {
+ uint64_t zfs_flag;
+ uint32_t fs_flag;
+ uint32_t xflag;
+} flags_lookup[] = {
+ {ZFS_IMMUTABLE, FS_IMMUTABLE_FL, FS_XFLAG_IMMUTABLE},
+ {ZFS_APPENDONLY, FS_APPEND_FL, FS_XFLAG_APPEND},
+ {ZFS_NODUMP, FS_NODUMP_FL, FS_XFLAG_NODUMP},
+ {ZFS_PROJINHERIT, FS_PROJINHERIT_FL, FS_XFLAG_PROJINHERIT}
+};
static uint32_t
__zpl_ioctl_getflags(struct inode *ip)
{
uint64_t zfs_flags = ITOZ(ip)->z_pflags;
uint32_t ioctl_flags = 0;
+ for (int i = 0; i < ARRAY_SIZE(flags_lookup); i++)
+ if (zfs_flags & flags_lookup[i].zfs_flag)
+ ioctl_flags |= flags_lookup[i].fs_flag;
- if (zfs_flags & ZFS_IMMUTABLE)
- ioctl_flags |= FS_IMMUTABLE_FL;
-
- if (zfs_flags & ZFS_APPENDONLY)
- ioctl_flags |= FS_APPEND_FL;
+ return (ioctl_flags);
+}
- if (zfs_flags & ZFS_NODUMP)
- ioctl_flags |= FS_NODUMP_FL;
+static uint32_t
+__zpl_ioctl_getxflags(struct inode *ip)
+{
+ uint64_t zfs_flags = ITOZ(ip)->z_pflags;
+ uint32_t ioctl_flags = 0;
- if (zfs_flags & ZFS_PROJINHERIT)
- ioctl_flags |= ZFS_PROJINHERIT_FL;
+ for (int i = 0; i < ARRAY_SIZE(flags_lookup); i++)
+ if (zfs_flags & flags_lookup[i].zfs_flag)
+ ioctl_flags |= flags_lookup[i].xflag;
- return (ioctl_flags & ZFS_FL_USER_VISIBLE);
+ return (ioctl_flags);
}
/*
@@ -846,6 +862,7 @@ zpl_ioctl_getflags(struct file *filp, void __user *arg)
int err;
flags = __zpl_ioctl_getflags(file_inode(filp));
+ flags = flags & ZFS_FL_USER_VISIBLE;
err = copy_to_user(arg, &flags, sizeof (flags));
return (err);
@@ -869,7 +886,7 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
xoptattr_t *xoap;
if (ioctl_flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NODUMP_FL |
- ZFS_PROJINHERIT_FL))
+ FS_PROJINHERIT_FL))
return (-EOPNOTSUPP);
if (ioctl_flags & ~ZFS_FL_USER_MODIFIABLE)
@@ -900,7 +917,51 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
xoap->xoa_appendonly);
FLAG_CHANGE(FS_NODUMP_FL, ZFS_NODUMP, XAT_NODUMP,
xoap->xoa_nodump);
- FLAG_CHANGE(ZFS_PROJINHERIT_FL, ZFS_PROJINHERIT, XAT_PROJINHERIT,
+ FLAG_CHANGE(FS_PROJINHERIT_FL, ZFS_PROJINHERIT, XAT_PROJINHERIT,
+ xoap->xoa_projinherit);
+
+#undef FLAG_CHANGE
+
+ return (0);
+}
+
+static int
+__zpl_ioctl_setxflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
+{
+ uint64_t zfs_flags = ITOZ(ip)->z_pflags;
+ xoptattr_t *xoap;
+
+ if (ioctl_flags & ~(FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND |
+ FS_XFLAG_NODUMP | FS_XFLAG_PROJINHERIT))
+ return (-EOPNOTSUPP);
+
+ if ((fchange(ioctl_flags, zfs_flags, FS_XFLAG_IMMUTABLE,
+ ZFS_IMMUTABLE) ||
+ fchange(ioctl_flags, zfs_flags, FS_XFLAG_APPEND, ZFS_APPENDONLY)) &&
+ !capable(CAP_LINUX_IMMUTABLE))
+ return (-EPERM);
+
+ if (!zpl_inode_owner_or_capable(zfs_init_idmap, ip))
+ return (-EACCES);
+
+ xva_init(xva);
+ xoap = xva_getxoptattr(xva);
+
+#define FLAG_CHANGE(iflag, zflag, xflag, xfield) do { \
+ if (((ioctl_flags & (iflag)) && !(zfs_flags & (zflag))) || \
+ ((zfs_flags & (zflag)) && !(ioctl_flags & (iflag)))) { \
+ XVA_SET_REQ(xva, (xflag)); \
+ (xfield) = ((ioctl_flags & (iflag)) != 0); \
+ } \
+} while (0)
+
+ FLAG_CHANGE(FS_XFLAG_IMMUTABLE, ZFS_IMMUTABLE, XAT_IMMUTABLE,
+ xoap->xoa_immutable);
+ FLAG_CHANGE(FS_XFLAG_APPEND, ZFS_APPENDONLY, XAT_APPENDONLY,
+ xoap->xoa_appendonly);
+ FLAG_CHANGE(FS_XFLAG_NODUMP, ZFS_NODUMP, XAT_NODUMP,
+ xoap->xoa_nodump);
+ FLAG_CHANGE(FS_XFLAG_PROJINHERIT, ZFS_PROJINHERIT, XAT_PROJINHERIT,
xoap->xoa_projinherit);
#undef FLAG_CHANGE
@@ -941,7 +1002,7 @@ zpl_ioctl_getxattr(struct file *filp, void __user *arg)
struct inode *ip = file_inode(filp);
int err;
- fsx.fsx_xflags = __zpl_ioctl_getflags(ip);
+ fsx.fsx_xflags = __zpl_ioctl_getxflags(ip);
fsx.fsx_projid = ITOZ(ip)->z_projid;
err = copy_to_user(arg, &fsx, sizeof (fsx));
@@ -965,7 +1026,7 @@ zpl_ioctl_setxattr(struct file *filp, void __user *arg)
if (!zpl_is_valid_projid(fsx.fsx_projid))
return (-EINVAL);
- err = __zpl_ioctl_setflags(ip, fsx.fsx_xflags, &xva);
+ err = __zpl_ioctl_setxflags(ip, fsx.fsx_xflags, &xva);
if (err)
return (err);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
index fe939150b641..89f9bc555fcf 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
@@ -809,8 +809,8 @@ retry:
* the kernel so the only option is to return the error for
* the caller to handle it.
*/
- if (!mutex_owned(&spa_namespace_lock)) {
- if (!mutex_tryenter(&spa_namespace_lock)) {
+ if (!spa_namespace_held()) {
+ if (!spa_namespace_tryenter(FTAG)) {
mutex_exit(&zv->zv_state_lock);
rw_exit(&zv->zv_suspend_lock);
drop_suspend = B_FALSE;
@@ -834,7 +834,7 @@ retry:
error = -zvol_first_open(zv, !(blk_mode_is_open_write(flag)));
if (drop_namespace)
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
if (error == 0) {
diff --git a/sys/contrib/openzfs/module/zcommon/zpool_prop.c b/sys/contrib/openzfs/module/zcommon/zpool_prop.c
index 07819ba2be8b..4826237b23e8 100644
--- a/sys/contrib/openzfs/module/zcommon/zpool_prop.c
+++ b/sys/contrib/openzfs/module/zcommon/zpool_prop.c
@@ -481,6 +481,9 @@ vdev_prop_init(void)
zprop_register_index(VDEV_PROP_FAILFAST, "failfast", B_TRUE,
PROP_DEFAULT, ZFS_TYPE_VDEV, "on | off", "FAILFAST", boolean_table,
sfeatures);
+ zprop_register_index(VDEV_PROP_SLOW_IO_EVENTS, "slow_io_events",
+ B_TRUE, PROP_DEFAULT, ZFS_TYPE_VDEV, "on | off",
+ "SLOW_IO_EVENTS", boolean_table, sfeatures);
/* hidden properties */
zprop_register_hidden(VDEV_PROP_NAME, "name", PROP_TYPE_STRING,
diff --git a/sys/contrib/openzfs/module/zfs/arc.c b/sys/contrib/openzfs/module/zfs/arc.c
index dbb5e942e2e6..48bf99f1aeb7 100644
--- a/sys/contrib/openzfs/module/zfs/arc.c
+++ b/sys/contrib/openzfs/module/zfs/arc.c
@@ -8548,7 +8548,7 @@ l2arc_dev_get_next(void)
* of cache devices (l2arc_dev_mtx). Once a device has been selected,
* both locks will be dropped and a spa config lock held instead.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
mutex_enter(&l2arc_dev_mtx);
/* if there are no vdevs, there is nothing to do */
@@ -8591,7 +8591,7 @@ out:
*/
if (next != NULL)
spa_config_enter(next->l2ad_spa, SCL_L2ARC, next, RW_READER);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (next);
}
@@ -10231,7 +10231,7 @@ l2arc_stop(void)
void
l2arc_spa_rebuild_start(spa_t *spa)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
/*
* Locate the spa's l2arc devices and kick off rebuild threads.
@@ -10256,7 +10256,7 @@ l2arc_spa_rebuild_start(spa_t *spa)
void
l2arc_spa_rebuild_stop(spa_t *spa)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_export_thread == curthread);
for (int i = 0; i < spa->spa_l2cache.sav_count; i++) {
diff --git a/sys/contrib/openzfs/module/zfs/bpobj.c b/sys/contrib/openzfs/module/zfs/bpobj.c
index ea9fbd036c6e..afcb2374f824 100644
--- a/sys/contrib/openzfs/module/zfs/bpobj.c
+++ b/sys/contrib/openzfs/module/zfs/bpobj.c
@@ -752,7 +752,8 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx)
}
dmu_write(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs,
bpo->bpo_phys->bpo_num_subobjs * sizeof (subobj),
- numsubsub * sizeof (subobj), subdb->db_data, tx);
+ numsubsub * sizeof (subobj), subdb->db_data, tx,
+ DMU_READ_NO_PREFETCH);
dmu_buf_rele(subdb, FTAG);
bpo->bpo_phys->bpo_num_subobjs += numsubsub;
@@ -777,7 +778,7 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx)
dmu_write(bpo->bpo_os, bpo->bpo_object,
bpo->bpo_phys->bpo_num_blkptrs * sizeof (blkptr_t),
numbps * sizeof (blkptr_t),
- bps->db_data, tx);
+ bps->db_data, tx, DMU_READ_NO_PREFETCH);
dmu_buf_rele(bps, FTAG);
bpo->bpo_phys->bpo_num_blkptrs += numbps;
@@ -794,7 +795,7 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx)
dmu_write(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs,
bpo->bpo_phys->bpo_num_subobjs * sizeof (subobj),
- sizeof (subobj), &subobj, tx);
+ sizeof (subobj), &subobj, tx, DMU_READ_NO_PREFETCH);
bpo->bpo_phys->bpo_num_subobjs++;
}
diff --git a/sys/contrib/openzfs/module/zfs/bptree.c b/sys/contrib/openzfs/module/zfs/bptree.c
index a98bba3eb259..1274278e8e91 100644
--- a/sys/contrib/openzfs/module/zfs/bptree.c
+++ b/sys/contrib/openzfs/module/zfs/bptree.c
@@ -137,7 +137,8 @@ bptree_add(objset_t *os, uint64_t obj, blkptr_t *bp, uint64_t birth_txg,
bte = kmem_zalloc(sizeof (*bte), KM_SLEEP);
bte->be_birth_txg = birth_txg;
bte->be_bp = *bp;
- dmu_write(os, obj, bt->bt_end * sizeof (*bte), sizeof (*bte), bte, tx);
+ dmu_write(os, obj, bt->bt_end * sizeof (*bte), sizeof (*bte), bte, tx,
+ DMU_READ_NO_PREFETCH);
kmem_free(bte, sizeof (*bte));
dmu_buf_will_dirty(db, tx);
@@ -247,7 +248,8 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
ZB_DESTROYED_OBJSET);
ASSERT0(bte.be_zb.zb_level);
dmu_write(os, obj, i * sizeof (bte),
- sizeof (bte), &bte, tx);
+ sizeof (bte), &bte, tx,
+ DMU_READ_NO_PREFETCH);
if (err == EIO || err == ECKSUM ||
err == ENXIO) {
/*
@@ -269,7 +271,8 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
*/
bte.be_birth_txg = UINT64_MAX;
dmu_write(os, obj, i * sizeof (bte),
- sizeof (bte), &bte, tx);
+ sizeof (bte), &bte, tx,
+ DMU_READ_NO_PREFETCH);
}
if (!ioerr) {
diff --git a/sys/contrib/openzfs/module/zfs/brt.c b/sys/contrib/openzfs/module/zfs/brt.c
index 40664354aa73..08a6bd52ab31 100644
--- a/sys/contrib/openzfs/module/zfs/brt.c
+++ b/sys/contrib/openzfs/module/zfs/brt.c
@@ -260,8 +260,8 @@ static int brt_zap_prefetch = 1;
#define BRT_DEBUG(...) do { } while (0)
#endif
-static int brt_zap_default_bs = 12;
-static int brt_zap_default_ibs = 12;
+static int brt_zap_default_bs = 13;
+static int brt_zap_default_ibs = 13;
static kstat_t *brt_ksp;
@@ -454,6 +454,7 @@ brt_vdev_create(spa_t *spa, brt_vdev_t *brtvd, dmu_tx_t *tx)
VERIFY(mos_entries != 0);
VERIFY0(dnode_hold(spa->spa_meta_objset, mos_entries, brtvd,
&brtvd->bv_mos_entries_dnode));
+ dnode_set_storage_type(brtvd->bv_mos_entries_dnode, DMU_OT_DDT_ZAP);
rw_enter(&brtvd->bv_mos_entries_lock, RW_WRITER);
brtvd->bv_mos_entries = mos_entries;
rw_exit(&brtvd->bv_mos_entries_lock);
@@ -508,8 +509,8 @@ brt_vdev_realloc(spa_t *spa, brt_vdev_t *brtvd)
size = (vdev_get_min_asize(vd) - 1) / spa->spa_brt_rangesize + 1;
spa_config_exit(spa, SCL_VDEV, FTAG);
- entcount = vmem_zalloc(sizeof (entcount[0]) * size, KM_SLEEP);
nblocks = BRT_RANGESIZE_TO_NBLOCKS(size);
+ entcount = vmem_zalloc(nblocks * BRT_BLOCKSIZE, KM_SLEEP);
bitmap = kmem_zalloc(BT_SIZEOFMAP(nblocks), KM_SLEEP);
if (!brtvd->bv_initiated) {
@@ -530,9 +531,8 @@ brt_vdev_realloc(spa_t *spa, brt_vdev_t *brtvd)
memcpy(entcount, brtvd->bv_entcount,
sizeof (entcount[0]) * MIN(size, brtvd->bv_size));
- vmem_free(brtvd->bv_entcount,
- sizeof (entcount[0]) * brtvd->bv_size);
onblocks = BRT_RANGESIZE_TO_NBLOCKS(brtvd->bv_size);
+ vmem_free(brtvd->bv_entcount, onblocks * BRT_BLOCKSIZE);
memcpy(bitmap, brtvd->bv_bitmap, MIN(BT_SIZEOFMAP(nblocks),
BT_SIZEOFMAP(onblocks)));
kmem_free(brtvd->bv_bitmap, BT_SIZEOFMAP(onblocks));
@@ -581,13 +581,14 @@ brt_vdev_load(spa_t *spa, brt_vdev_t *brtvd)
*/
error = dmu_read(spa->spa_meta_objset, brtvd->bv_mos_brtvdev, 0,
MIN(brtvd->bv_size, bvphys->bvp_size) * sizeof (uint16_t),
- brtvd->bv_entcount, DMU_READ_NO_PREFETCH);
+ brtvd->bv_entcount, DMU_READ_NO_PREFETCH | DMU_UNCACHEDIO);
if (error != 0)
return (error);
ASSERT(bvphys->bvp_mos_entries != 0);
VERIFY0(dnode_hold(spa->spa_meta_objset, bvphys->bvp_mos_entries, brtvd,
&brtvd->bv_mos_entries_dnode));
+ dnode_set_storage_type(brtvd->bv_mos_entries_dnode, DMU_OT_DDT_ZAP);
rw_enter(&brtvd->bv_mos_entries_lock, RW_WRITER);
brtvd->bv_mos_entries = bvphys->bvp_mos_entries;
rw_exit(&brtvd->bv_mos_entries_lock);
@@ -613,9 +614,9 @@ brt_vdev_dealloc(brt_vdev_t *brtvd)
ASSERT(brtvd->bv_initiated);
ASSERT0(avl_numnodes(&brtvd->bv_tree));
- vmem_free(brtvd->bv_entcount, sizeof (uint16_t) * brtvd->bv_size);
- brtvd->bv_entcount = NULL;
uint64_t nblocks = BRT_RANGESIZE_TO_NBLOCKS(brtvd->bv_size);
+ vmem_free(brtvd->bv_entcount, nblocks * BRT_BLOCKSIZE);
+ brtvd->bv_entcount = NULL;
kmem_free(brtvd->bv_bitmap, BT_SIZEOFMAP(nblocks));
brtvd->bv_bitmap = NULL;
@@ -807,10 +808,10 @@ brt_vdev_sync(spa_t *spa, brt_vdev_t *brtvd, dmu_tx_t *tx)
/*
* TODO: Walk brtvd->bv_bitmap and write only the dirty blocks.
*/
- dmu_write(spa->spa_meta_objset, brtvd->bv_mos_brtvdev, 0,
- brtvd->bv_size * sizeof (brtvd->bv_entcount[0]),
- brtvd->bv_entcount, tx);
uint64_t nblocks = BRT_RANGESIZE_TO_NBLOCKS(brtvd->bv_size);
+ dmu_write(spa->spa_meta_objset, brtvd->bv_mos_brtvdev, 0,
+ nblocks * BRT_BLOCKSIZE, brtvd->bv_entcount, tx,
+ DMU_READ_NO_PREFETCH | DMU_UNCACHEDIO);
memset(brtvd->bv_bitmap, 0, BT_SIZEOFMAP(nblocks));
brtvd->bv_entcount_dirty = FALSE;
}
@@ -1510,6 +1511,31 @@ brt_load(spa_t *spa)
}
void
+brt_prefetch_all(spa_t *spa)
+{
+ /*
+ * Load all BRT entries for each vdev. This is intended to perform
+ * a prefetch on all such blocks. For the same reason that brt_prefetch
+ * (called from brt_pending_add) isn't locked, this is also not locked.
+ */
+ brt_rlock(spa);
+ for (uint64_t vdevid = 0; vdevid < spa->spa_brt_nvdevs; vdevid++) {
+ brt_vdev_t *brtvd = spa->spa_brt_vdevs[vdevid];
+ brt_unlock(spa);
+
+ rw_enter(&brtvd->bv_mos_entries_lock, RW_READER);
+ if (brtvd->bv_mos_entries != 0) {
+ (void) zap_prefetch_object(spa->spa_meta_objset,
+ brtvd->bv_mos_entries);
+ }
+ rw_exit(&brtvd->bv_mos_entries_lock);
+
+ brt_rlock(spa);
+ }
+ brt_unlock(spa);
+}
+
+void
brt_unload(spa_t *spa)
{
if (spa->spa_brt_rangesize == 0)
diff --git a/sys/contrib/openzfs/module/zfs/dbuf.c b/sys/contrib/openzfs/module/zfs/dbuf.c
index fccc4c5b5b94..72c597609ade 100644
--- a/sys/contrib/openzfs/module/zfs/dbuf.c
+++ b/sys/contrib/openzfs/module/zfs/dbuf.c
@@ -446,7 +446,10 @@ static boolean_t
dbuf_include_in_metadata_cache(dmu_buf_impl_t *db)
{
DB_DNODE_ENTER(db);
- dmu_object_type_t type = DB_DNODE(db)->dn_type;
+ dnode_t *dn = DB_DNODE(db);
+ dmu_object_type_t type = dn->dn_storage_type;
+ if (type == DMU_OT_NONE)
+ type = dn->dn_type;
DB_DNODE_EXIT(db);
/* Check if this dbuf is one of the types we care about */
diff --git a/sys/contrib/openzfs/module/zfs/ddt_log.c b/sys/contrib/openzfs/module/zfs/ddt_log.c
index c7a2426f3a77..3d42c51365a8 100644
--- a/sys/contrib/openzfs/module/zfs/ddt_log.c
+++ b/sys/contrib/openzfs/module/zfs/ddt_log.c
@@ -222,7 +222,7 @@ ddt_log_begin(ddt_t *ddt, size_t nentries, dmu_tx_t *tx, ddt_log_update_t *dlu)
VERIFY0(dmu_buf_hold_array_by_dnode(dlu->dlu_dn, offset, length,
B_FALSE, FTAG, &dlu->dlu_ndbp, &dlu->dlu_dbp,
- DMU_READ_NO_PREFETCH));
+ DMU_READ_NO_PREFETCH | DMU_UNCACHEDIO));
dlu->dlu_tx = tx;
dlu->dlu_block = dlu->dlu_offset = 0;
@@ -298,7 +298,8 @@ ddt_log_entry(ddt_t *ddt, ddt_lightweight_entry_t *ddlwe, ddt_log_update_t *dlu)
* we will fill it, and zero it out.
*/
if (dlu->dlu_offset == 0) {
- dmu_buf_will_fill(db, dlu->dlu_tx, B_FALSE);
+ dmu_buf_will_fill_flags(db, dlu->dlu_tx, B_FALSE,
+ DMU_UNCACHEDIO);
memset(db->db_data, 0, db->db_size);
}
@@ -597,7 +598,7 @@ ddt_log_load_one(ddt_t *ddt, uint_t n)
for (uint64_t offset = 0; offset < hdr.dlh_length;
offset += dn->dn_datablksz) {
err = dmu_buf_hold_by_dnode(dn, offset, FTAG, &db,
- DMU_READ_PREFETCH);
+ DMU_READ_PREFETCH | DMU_UNCACHEDIO);
if (err != 0) {
dnode_rele(dn, FTAG);
ddt_log_empty(ddt, ddl);
diff --git a/sys/contrib/openzfs/module/zfs/dmu.c b/sys/contrib/openzfs/module/zfs/dmu.c
index a7a5c89bdafb..5690f8afad00 100644
--- a/sys/contrib/openzfs/module/zfs/dmu.c
+++ b/sys/contrib/openzfs/module/zfs/dmu.c
@@ -635,7 +635,7 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length,
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)
{
dnode_t *dn;
int err;
@@ -645,7 +645,7 @@ dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset,
return (err);
err = dmu_buf_hold_array_by_dnode(dn, offset, length, read, tag,
- numbufsp, dbpp, DMU_READ_PREFETCH);
+ numbufsp, dbpp, flags);
dnode_rele(dn, FTAG);
@@ -655,14 +655,14 @@ dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset,
int
dmu_buf_hold_array_by_bonus(dmu_buf_t *db_fake, uint64_t offset,
uint64_t length, boolean_t read, const void *tag, int *numbufsp,
- dmu_buf_t ***dbpp)
+ dmu_buf_t ***dbpp, dmu_flags_t flags)
{
dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
int err;
DB_DNODE_ENTER(db);
err = dmu_buf_hold_array_by_dnode(DB_DNODE(db), offset, length, read,
- tag, numbufsp, dbpp, DMU_READ_PREFETCH);
+ tag, numbufsp, dbpp, flags);
DB_DNODE_EXIT(db);
return (err);
@@ -850,12 +850,15 @@ dmu_prefetch_wait(objset_t *os, uint64_t object, uint64_t offset, uint64_t size)
return (err);
/*
- * Chunk the requests (16 indirects worth) so that we can be interrupted
+ * Chunk the requests (16 indirects worth) so that we can be
+ * interrupted. Prefetch at least SPA_MAXBLOCKSIZE at a time
+ * to better utilize pools with smaller block sizes.
*/
uint64_t chunksize;
if (dn->dn_indblkshift) {
uint64_t nbps = bp_span_in_blocks(dn->dn_indblkshift, 1);
chunksize = (nbps * 16) << dn->dn_datablkshift;
+ chunksize = MAX(chunksize, SPA_MAXBLOCKSIZE);
} else {
chunksize = dn->dn_datablksz;
}
@@ -1293,7 +1296,7 @@ dmu_write_impl(dmu_buf_t **dbp, int numbufs, uint64_t offset, uint64_t size,
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)
{
dmu_buf_t **dbp;
int numbufs;
@@ -1302,8 +1305,8 @@ dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
return;
VERIFY0(dmu_buf_hold_array(os, object, offset, size,
- FALSE, FTAG, &numbufs, &dbp));
- dmu_write_impl(dbp, numbufs, offset, size, buf, tx, DMU_READ_PREFETCH);
+ FALSE, FTAG, &numbufs, &dbp, flags));
+ dmu_write_impl(dbp, numbufs, offset, size, buf, tx, flags);
dmu_buf_rele_array(dbp, numbufs, FTAG);
}
@@ -1346,7 +1349,7 @@ dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
return;
VERIFY0(dmu_buf_hold_array(os, object, offset, size,
- FALSE, FTAG, &numbufs, &dbp));
+ FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH));
for (i = 0; i < numbufs; i++) {
dmu_buf_t *db = dbp[i];
@@ -1383,7 +1386,7 @@ dmu_redact(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
dmu_buf_t **dbp;
VERIFY0(dmu_buf_hold_array(os, object, offset, size, FALSE, FTAG,
- &numbufs, &dbp));
+ &numbufs, &dbp, DMU_READ_PREFETCH));
for (i = 0; i < numbufs; i++)
dmu_buf_redact(dbp[i], tx);
dmu_buf_rele_array(dbp, numbufs, FTAG);
@@ -2592,7 +2595,7 @@ dmu_read_l0_bps(objset_t *os, uint64_t object, uint64_t offset, uint64_t length,
int error, numbufs;
error = dmu_buf_hold_array(os, object, offset, length, FALSE, FTAG,
- &numbufs, &dbp);
+ &numbufs, &dbp, DMU_READ_PREFETCH);
if (error != 0) {
if (error == ESRCH) {
error = SET_ERROR(ENXIO);
@@ -2693,7 +2696,7 @@ dmu_brt_clone(objset_t *os, uint64_t object, uint64_t offset, uint64_t length,
spa = os->os_spa;
VERIFY0(dmu_buf_hold_array(os, object, offset, length, FALSE, FTAG,
- &numbufs, &dbp));
+ &numbufs, &dbp, DMU_READ_PREFETCH));
ASSERT3U(nbps, ==, numbufs);
/*
diff --git a/sys/contrib/openzfs/module/zfs/dmu_redact.c b/sys/contrib/openzfs/module/zfs/dmu_redact.c
index 5a22ed71a5fe..c087be4c811d 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_redact.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_redact.c
@@ -544,7 +544,8 @@ redaction_list_update_sync(void *arg, dmu_tx_t *tx)
if (index == bufsize) {
dmu_write(mos, rl->rl_object,
rl->rl_phys->rlp_num_entries * sizeof (*buf),
- bufsize * sizeof (*buf), buf, tx);
+ bufsize * sizeof (*buf), buf, tx,
+ DMU_READ_NO_PREFETCH);
rl->rl_phys->rlp_num_entries += bufsize;
index = 0;
}
@@ -552,7 +553,8 @@ redaction_list_update_sync(void *arg, dmu_tx_t *tx)
}
if (index > 0) {
dmu_write(mos, rl->rl_object, rl->rl_phys->rlp_num_entries *
- sizeof (*buf), index * sizeof (*buf), buf, tx);
+ sizeof (*buf), index * sizeof (*buf), buf, tx,
+ DMU_READ_NO_PREFETCH);
rl->rl_phys->rlp_num_entries += index;
}
kmem_free(buf, bufsize * sizeof (*buf));
diff --git a/sys/contrib/openzfs/module/zfs/dnode.c b/sys/contrib/openzfs/module/zfs/dnode.c
index e88d394b5229..e0cc4a7e13e0 100644
--- a/sys/contrib/openzfs/module/zfs/dnode.c
+++ b/sys/contrib/openzfs/module/zfs/dnode.c
@@ -2496,26 +2496,27 @@ dnode_diduse_space(dnode_t *dn, int64_t delta)
}
/*
- * Scans a block at the indicated "level" looking for a hole or data,
- * depending on 'flags'.
+ * Scans the block at the indicated "level" looking for a hole or data,
+ * depending on 'flags' starting from array position given by *index.
*
- * If level > 0, then we are scanning an indirect block looking at its
- * pointers. If level == 0, then we are looking at a block of dnodes.
+ * If lvl > 0, then we are scanning an indirect block looking at its
+ * pointers. If lvl == 0, then we are looking at a block of dnodes.
*
* If we don't find what we are looking for in the block, we return ESRCH.
- * Otherwise, return with *offset pointing to the beginning (if searching
- * forwards) or end (if searching backwards) of the range covered by the
- * block pointer we matched on (or dnode).
+ * Otherwise, return with *index set to the matching array position.
*
- * The basic search algorithm used below by dnode_next_offset() is to
- * use this function to search up the block tree (widen the search) until
- * we find something (i.e., we don't return ESRCH) and then search back
- * down the tree (narrow the search) until we reach our original search
- * level.
+ * In both cases, *offset is updated to point at the matched BP/dnode or
+ * the next offset to search (unless at the limit of possible offsets).
+ *
+ * The basic search algorithm used below by dnode_next_offset() uses this
+ * function to perform a block-order tree traversal. We search up the block
+ * tree (widen the search) until we find something (i.e., we don't return
+ * ESRCH) and then search back down the tree (narrow the search) until we
+ * reach our original search level or backtrack up because nothing matches.
*/
static int
-dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
- int lvl, uint64_t blkfill, uint64_t txg)
+dnode_next_offset_level(dnode_t *dn, int flags, int lvl, uint64_t blkid,
+ int *index, uint64_t blkfill, uint64_t txg, uint64_t *offset)
{
dmu_buf_impl_t *db = NULL;
void *data = NULL;
@@ -2541,20 +2542,12 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
rrw_enter(&dmu_objset_ds(dn->dn_objset)->ds_bp_rwlock,
RW_READER, FTAG);
} else {
- uint64_t blkid = dbuf_whichblock(dn, lvl, *offset);
error = dbuf_hold_impl(dn, lvl, blkid, TRUE, FALSE, FTAG, &db);
if (error) {
if (error != ENOENT)
return (error);
if (hole)
return (0);
- /*
- * This can only happen when we are searching up
- * the block tree for data. We don't really need to
- * adjust the offset, as we will just end up looking
- * at the pointer to this block in its parent, and its
- * going to be unallocated, so we will skip over it.
- */
return (SET_ERROR(ESRCH));
}
error = dbuf_read(db, NULL,
@@ -2582,8 +2575,7 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
ASSERT(dn->dn_type == DMU_OT_DNODE);
ASSERT(!(flags & DNODE_FIND_BACKWARDS));
- for (i = (*offset >> DNODE_SHIFT) & (blkfill - 1);
- i < blkfill; i += dnp[i].dn_extra_slots + 1) {
+ for (i = *index; i < blkfill; i += dnp[i].dn_extra_slots + 1) {
if ((dnp[i].dn_type == DMU_OT_NONE) == hole)
break;
}
@@ -2591,11 +2583,11 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
if (i == blkfill)
error = SET_ERROR(ESRCH);
+ *index = i;
*offset = (*offset & ~(DNODE_BLOCK_SIZE - 1)) +
(i << DNODE_SHIFT);
} else {
blkptr_t *bp = data;
- uint64_t start = *offset;
span = (lvl - 1) * epbs + dn->dn_datablkshift;
minfill = 0;
maxfill = blkfill << ((lvl - 1) * epbs);
@@ -2605,40 +2597,27 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
else
minfill++;
- if (span >= 8 * sizeof (*offset)) {
- /* This only happens on the highest indirection level */
- ASSERT3U((lvl - 1), ==, dn->dn_phys->dn_nlevels - 1);
- *offset = 0;
- } else {
- *offset = *offset >> span;
- }
-
- for (i = BF64_GET(*offset, 0, epbs);
- i >= 0 && i < epb; i += inc) {
+ for (i = *index; i >= 0 && i < epb; i += inc) {
if (BP_GET_FILL(&bp[i]) >= minfill &&
BP_GET_FILL(&bp[i]) <= maxfill &&
(hole || BP_GET_LOGICAL_BIRTH(&bp[i]) > txg))
break;
- if (inc > 0 || *offset > 0)
- *offset += inc;
}
- if (span >= 8 * sizeof (*offset)) {
- *offset = start;
- } else {
- *offset = *offset << span;
- }
-
- if (inc < 0) {
- /* traversing backwards; position offset at the end */
- if (span < 8 * sizeof (*offset))
- *offset = MIN(*offset + (1ULL << span) - 1,
- start);
- } else if (*offset < start) {
- *offset = start;
- }
if (i < 0 || i >= epb)
error = SET_ERROR(ESRCH);
+
+ *index = i;
+ if (span < 8 * sizeof (*offset)) {
+ uint64_t nblk = blkid << epbs;
+ if (i >= 0 || blkid != 0)
+ nblk += i;
+ if ((nblk >> (8 * sizeof (*offset) - span)) == 0)
+ *offset = (flags & DNODE_FIND_BACKWARDS) ?
+ /* backwards: position offset at the end */
+ MIN(*offset, ((nblk + 1) << span) - 1) :
+ MAX(*offset, nblk << span);
+ }
}
if (db != NULL) {
@@ -2656,38 +2635,24 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
}
/*
- * Adjust *offset to the next (or previous) block byte offset at lvl.
- * Returns FALSE if *offset would overflow or underflow.
- */
-static boolean_t
-dnode_next_block(dnode_t *dn, int flags, uint64_t *offset, int lvl)
-{
- int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
- int span = lvl * epbs + dn->dn_datablkshift;
- uint64_t blkid, maxblkid;
-
- if (span >= 8 * sizeof (uint64_t))
- return (B_FALSE);
-
- blkid = *offset >> span;
- maxblkid = 1ULL << (8 * sizeof (*offset) - span);
- if (!(flags & DNODE_FIND_BACKWARDS) && blkid + 1 < maxblkid)
- *offset = (blkid + 1) << span;
- else if ((flags & DNODE_FIND_BACKWARDS) && blkid > 0)
- *offset = (blkid << span) - 1;
- else
- return (B_FALSE);
-
- return (B_TRUE);
-}
-
-/*
* Find the next hole, data, or sparse region at or after *offset.
* The value 'blkfill' tells us how many items we expect to find
* in an L0 data block; this value is 1 for normal objects,
* DNODES_PER_BLOCK for the meta dnode, and some fraction of
* DNODES_PER_BLOCK when searching for sparse regions thereof.
*
+ * If minlvl == 0, this searches for dnodes or unallocated dnodes.
+ * If found, *offset points to the first offset of the matched dnode.
+ * Backwards search is not allowed for dnodes.
+ *
+ * If minlvl > 0, this searches for blocks at the given level.
+ * If found, *offset points to the first L0 offset of the block
+ * (or for backwards search, the last offset, inclusive).
+ *
+ * If not found, in both cases, *offset is set to the first (or last)
+ * offset of the unallocated indirect block where the search ended or
+ * the initial offset if no such block was encountered.
+ *
* Examples:
*
* dnode_next_offset(dn, flags, offset, 1, 1, 0);
@@ -2708,7 +2673,8 @@ int
dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset,
int minlvl, uint64_t blkfill, uint64_t txg)
{
- uint64_t matched = *offset;
+ uint64_t blkid;
+ int index, epbs;
int lvl, maxlvl;
int error = 0;
@@ -2730,18 +2696,31 @@ dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset,
goto out;
}
+ epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
maxlvl = dn->dn_phys->dn_nlevels;
+ if (minlvl > 0) {
+ uint64_t n = dbuf_whichblock(dn, minlvl - 1, *offset);
+ blkid = n >> epbs;
+ index = BF64_GET(n, 0, epbs);
+ } else {
+ blkid = dbuf_whichblock(dn, 0, *offset);
+ index = (*offset >> DNODE_SHIFT) & (blkfill - 1);
+ ASSERT3U(BF64_GET(*offset, 0, DNODE_SHIFT), ==, 0);
+ }
+
for (lvl = minlvl; lvl <= maxlvl; ) {
error = dnode_next_offset_level(dn,
- flags, offset, lvl, blkfill, txg);
+ flags, lvl, blkid, &index, blkfill, txg, offset);
+
if (error == 0 && lvl > minlvl) {
+ /* Continue search at matched block in lvl-1. */
+ blkid = (blkid << epbs) + index;
+ index = 0;
--lvl;
- matched = *offset;
- } else if (error == ESRCH && lvl < maxlvl &&
- dnode_next_block(dn, flags, &matched, lvl)) {
+ } else if (error == ESRCH && lvl < maxlvl) {
/*
- * Continue search at next/prev offset in lvl+1 block.
+ * Continue search at next/prev index in lvl+1 block.
*
* Usually we only search upwards at the start of the
* search as higher level blocks point at a matching
@@ -2752,13 +2731,14 @@ dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset,
* happens if we are still syncing out the tree, and
* some BP's at higher levels are not updated yet.
*
- * We must adjust offset to avoid coming back to the
- * same offset and getting stuck looping forever. This
- * also deals with the case where offset is already at
- * the beginning or end of the object.
+ * We must adjust index to avoid coming back to the
+ * same offset and getting stuck looping forever. The
+ * next loop goes up again if index is -1 or (1<<epbs).
*/
+ index = BF64_GET(blkid, 0, epbs) +
+ ((flags & DNODE_FIND_BACKWARDS) ? -1 : 1);
+ blkid = blkid >> epbs;
++lvl;
- *offset = matched;
} else {
break;
}
diff --git a/sys/contrib/openzfs/module/zfs/metaslab.c b/sys/contrib/openzfs/module/zfs/metaslab.c
index 9f4399af56bd..3f649ffb44e4 100644
--- a/sys/contrib/openzfs/module/zfs/metaslab.c
+++ b/sys/contrib/openzfs/module/zfs/metaslab.c
@@ -3966,7 +3966,8 @@ metaslab_condense(metaslab_t *msp, dmu_tx_t *tx)
object = space_map_object(msp->ms_sm);
dmu_write(spa->spa_meta_objset,
msp->ms_group->mg_vd->vdev_ms_array, sizeof (uint64_t) *
- msp->ms_id, sizeof (uint64_t), &object, tx);
+ msp->ms_id, sizeof (uint64_t), &object, tx,
+ DMU_READ_NO_PREFETCH);
}
/*
@@ -4292,7 +4293,8 @@ metaslab_sync(metaslab_t *msp, uint64_t txg)
VERIFY3U(new_object, !=, 0);
dmu_write(mos, vd->vdev_ms_array, sizeof (uint64_t) *
- msp->ms_id, sizeof (uint64_t), &new_object, tx);
+ msp->ms_id, sizeof (uint64_t), &new_object, tx,
+ DMU_READ_NO_PREFETCH);
VERIFY0(space_map_open(&msp->ms_sm, mos, new_object,
msp->ms_start, msp->ms_size, vd->vdev_ashift));
@@ -6328,7 +6330,7 @@ metaslab_update_ondisk_flush_data(metaslab_t *ms, dmu_tx_t *tx)
}
dmu_write(spa_meta_objset(spa), object, entry_offset, entry_size,
- &entry, tx);
+ &entry, tx, DMU_READ_NO_PREFETCH);
}
void
diff --git a/sys/contrib/openzfs/module/zfs/mmp.c b/sys/contrib/openzfs/module/zfs/mmp.c
index fd46127b6068..b8ba40ecdc9d 100644
--- a/sys/contrib/openzfs/module/zfs/mmp.c
+++ b/sys/contrib/openzfs/module/zfs/mmp.c
@@ -729,12 +729,12 @@ mmp_signal_all_threads(void)
{
spa_t *spa = NULL;
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
while ((spa = spa_next(spa))) {
if (spa->spa_state == POOL_STATE_ACTIVE)
mmp_signal_thread(spa);
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
ZFS_MODULE_PARAM_CALL(zfs_multihost, zfs_multihost_, interval,
diff --git a/sys/contrib/openzfs/module/zfs/spa.c b/sys/contrib/openzfs/module/zfs/spa.c
index b3bb46da263b..34de3f1d9525 100644
--- a/sys/contrib/openzfs/module/zfs/spa.c
+++ b/sys/contrib/openzfs/module/zfs/spa.c
@@ -141,7 +141,7 @@ typedef enum zti_modes {
#define ZTI_P(n, q) { ZTI_MODE_FIXED, (n), (q) }
#define ZTI_PCT(n) { ZTI_MODE_ONLINE_PERCENT, (n), 1 }
-#define ZTI_SCALE { ZTI_MODE_SCALE, 0, 1 }
+#define ZTI_SCALE(min) { ZTI_MODE_SCALE, (min), 1 }
#define ZTI_SYNC { ZTI_MODE_SYNC, 0, 1 }
#define ZTI_NULL { ZTI_MODE_NULL, 0, 0 }
@@ -180,13 +180,13 @@ static const char *const zio_taskq_types[ZIO_TASKQ_TYPES] = {
static zio_taskq_info_t zio_taskqs[ZIO_TYPES][ZIO_TASKQ_TYPES] = {
/* ISSUE ISSUE_HIGH INTR INTR_HIGH */
{ ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* NULL */
- { ZTI_N(8), ZTI_NULL, ZTI_SCALE, ZTI_NULL }, /* READ */
+ { ZTI_N(8), ZTI_NULL, ZTI_SCALE(0), ZTI_NULL }, /* READ */
#ifdef illumos
- { ZTI_SYNC, ZTI_N(5), ZTI_SCALE, ZTI_N(5) }, /* WRITE */
+ { ZTI_SYNC, ZTI_N(5), ZTI_SCALE(0), ZTI_N(5) }, /* WRITE */
#else
- { ZTI_SYNC, ZTI_NULL, ZTI_SCALE, ZTI_NULL }, /* WRITE */
+ { ZTI_SYNC, ZTI_NULL, ZTI_SCALE(0), ZTI_NULL }, /* WRITE */
#endif
- { ZTI_SCALE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* FREE */
+ { ZTI_SCALE(32), ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* FREE */
{ ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* CLAIM */
{ ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* FLUSH */
{ ZTI_N(4), ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* TRIM */
@@ -1082,7 +1082,7 @@ spa_change_guid(spa_t *spa, const uint64_t *guidp)
int error;
mutex_enter(&spa->spa_vdev_top_lock);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if (guidp != NULL) {
guid = *guidp;
@@ -1117,7 +1117,7 @@ spa_change_guid(spa_t *spa, const uint64_t *guidp)
}
out:
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
mutex_exit(&spa->spa_vdev_top_lock);
return (error);
@@ -1170,7 +1170,7 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
uint_t value = ztip->zti_value;
uint_t count = ztip->zti_count;
spa_taskqs_t *tqs = &spa->spa_zio_taskq[t][q];
- uint_t cpus, flags = TASKQ_DYNAMIC;
+ uint_t cpus, threads, flags = TASKQ_DYNAMIC;
switch (mode) {
case ZTI_MODE_FIXED:
@@ -1183,8 +1183,8 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
* Create one wr_iss taskq for every 'zio_taskq_write_tpq' CPUs,
* not to exceed the number of spa allocators, and align to it.
*/
- cpus = MAX(1, boot_ncpus * zio_taskq_batch_pct / 100);
- count = MAX(1, cpus / MAX(1, zio_taskq_write_tpq));
+ threads = MAX(1, boot_ncpus * zio_taskq_batch_pct / 100);
+ count = MAX(1, threads / MAX(1, zio_taskq_write_tpq));
count = MAX(count, (zio_taskq_batch_pct + 99) / 100);
count = MIN(count, spa->spa_alloc_count);
while (spa->spa_alloc_count % count != 0 &&
@@ -1201,14 +1201,14 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
break;
case ZTI_MODE_SCALE:
- flags |= TASKQ_THREADS_CPU_PCT;
/*
* We want more taskqs to reduce lock contention, but we want
* less for better request ordering and CPU utilization.
*/
- cpus = MAX(1, boot_ncpus * zio_taskq_batch_pct / 100);
+ threads = MAX(1, boot_ncpus * zio_taskq_batch_pct / 100);
+ threads = MAX(threads, value);
if (zio_taskq_batch_tpq > 0) {
- count = MAX(1, (cpus + zio_taskq_batch_tpq / 2) /
+ count = MAX(1, (threads + zio_taskq_batch_tpq / 2) /
zio_taskq_batch_tpq);
} else {
/*
@@ -1228,13 +1228,23 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
* 128 10 8% 10 100
* 256 14 6% 15 210
*/
- count = 1 + cpus / 6;
+ cpus = MIN(threads, boot_ncpus);
+ count = 1 + threads / 6;
while (count * count > cpus)
count--;
}
- /* Limit each taskq within 100% to not trigger assertion. */
- count = MAX(count, (zio_taskq_batch_pct + 99) / 100);
- value = (zio_taskq_batch_pct + count / 2) / count;
+
+ /*
+ * Try to represent the number of threads per taskq as percent
+ * of online CPUs to allow scaling with later online/offline.
+ * Fall back to absolute numbers if can't.
+ */
+ value = (threads * 100 + boot_ncpus * count / 2) /
+ (boot_ncpus * count);
+ if (value < 5 || value > 100)
+ value = MAX(1, (threads + count / 2) / count);
+ else
+ flags |= TASKQ_THREADS_CPU_PCT;
break;
case ZTI_MODE_NULL:
@@ -1433,8 +1443,30 @@ spa_taskq_param_set(zio_type_t t, char *cfg)
break;
}
+ /*
+ * SCALE is optionally parameterised by minimum number of
+ * threads.
+ */
case ZTI_MODE_SCALE: {
- const zio_taskq_info_t zti = ZTI_SCALE;
+ unsigned long long mint = 0;
+ if (c != NULL && *c != '\0') {
+ /* Need a number */
+ if (!(isdigit(*c)))
+ break;
+ tok = c;
+
+ /* Take digits */
+ err = ddi_strtoull(tok, &tok, 10, &mint);
+ /* Must succeed, and moved forward */
+ if (err != 0 || tok == c || *tok != '\0')
+ break;
+
+ /* Sanity check */
+ if (mint >= 16384)
+ break;
+ }
+
+ const zio_taskq_info_t zti = ZTI_SCALE(mint);
row[q] = zti;
break;
}
@@ -1501,6 +1533,9 @@ spa_taskq_param_get(zio_type_t t, char *buf, boolean_t add_newline)
pos += sprintf(&buf[pos], "%s%s,%u,%u", sep,
modes[zti->zti_mode], zti->zti_count,
zti->zti_value);
+ else if (zti->zti_mode == ZTI_MODE_SCALE && zti->zti_value > 0)
+ pos += sprintf(&buf[pos], "%s%s,%u", sep,
+ modes[zti->zti_mode], zti->zti_value);
else
pos += sprintf(&buf[pos], "%s%s", sep,
modes[zti->zti_mode]);
@@ -1520,9 +1555,10 @@ spa_taskq_read_param_set(const char *val, zfs_kernel_param_t *kp)
{
char *cfg = kmem_strdup(val);
int err = spa_taskq_param_set(ZIO_TYPE_READ, cfg);
- kmem_free(cfg, strlen(val)+1);
+ kmem_strfree(cfg);
return (-err);
}
+
static int
spa_taskq_read_param_get(char *buf, zfs_kernel_param_t *kp)
{
@@ -1534,14 +1570,30 @@ spa_taskq_write_param_set(const char *val, zfs_kernel_param_t *kp)
{
char *cfg = kmem_strdup(val);
int err = spa_taskq_param_set(ZIO_TYPE_WRITE, cfg);
- kmem_free(cfg, strlen(val)+1);
+ kmem_strfree(cfg);
return (-err);
}
+
static int
spa_taskq_write_param_get(char *buf, zfs_kernel_param_t *kp)
{
return (spa_taskq_param_get(ZIO_TYPE_WRITE, buf, TRUE));
}
+
+static int
+spa_taskq_free_param_set(const char *val, zfs_kernel_param_t *kp)
+{
+ char *cfg = kmem_strdup(val);
+ int err = spa_taskq_param_set(ZIO_TYPE_FREE, cfg);
+ kmem_strfree(cfg);
+ return (-err);
+}
+
+static int
+spa_taskq_free_param_get(char *buf, zfs_kernel_param_t *kp)
+{
+ return (spa_taskq_param_get(ZIO_TYPE_FREE, buf, TRUE));
+}
#else
/*
* On FreeBSD load-time parameters can be set up before malloc() is available,
@@ -1574,6 +1626,19 @@ spa_taskq_write_param(ZFS_MODULE_PARAM_ARGS)
return (err);
return (spa_taskq_param_set(ZIO_TYPE_WRITE, buf));
}
+
+static int
+spa_taskq_free_param(ZFS_MODULE_PARAM_ARGS)
+{
+ char buf[SPA_TASKQ_PARAM_MAX];
+ int err;
+
+ (void) spa_taskq_param_get(ZIO_TYPE_FREE, buf, FALSE);
+ err = sysctl_handle_string(oidp, buf, sizeof (buf), req);
+ if (err || req->newptr == NULL)
+ return (err);
+ return (spa_taskq_param_set(ZIO_TYPE_FREE, buf));
+}
#endif
#endif /* _KERNEL */
@@ -2187,7 +2252,7 @@ spa_should_sync_time_logger_on_unload(spa_t *spa)
static void
spa_unload(spa_t *spa)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_export_thread == curthread);
ASSERT(spa_state(spa) != POOL_STATE_UNINITIALIZED);
@@ -5260,7 +5325,7 @@ spa_ld_read_checkpoint_txg(spa_t *spa)
int error = 0;
ASSERT0(spa->spa_checkpoint_txg);
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_load_thread == curthread);
error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
@@ -5287,7 +5352,7 @@ spa_ld_mos_init(spa_t *spa, spa_import_type_t type)
{
int error = 0;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
ASSERT(spa->spa_config_source != SPA_CONFIG_SRC_NONE);
/*
@@ -5363,7 +5428,7 @@ spa_ld_checkpoint_rewind(spa_t *spa)
uberblock_t checkpoint;
int error = 0;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
ASSERT(spa->spa_import_flags & ZFS_IMPORT_CHECKPOINT);
error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
@@ -5510,7 +5575,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
boolean_t update_config_cache = B_FALSE;
hrtime_t load_start = gethrtime();
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
ASSERT(spa->spa_config_source != SPA_CONFIG_SRC_NONE);
spa_load_note(spa, "LOADING");
@@ -5557,7 +5622,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
* Drop the namespace lock for the rest of the function.
*/
spa->spa_load_thread = curthread;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
/*
* Retrieve the checkpoint txg if the pool has a checkpoint.
@@ -5796,9 +5861,9 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
spa_load_note(spa, "LOADED");
fail:
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa->spa_load_thread = NULL;
- cv_broadcast(&spa_namespace_cv);
+ spa_namespace_broadcast();
return (error);
@@ -5960,14 +6025,14 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
* up calling spa_open() again. The real fix is to figure out how to
* avoid dsl_dir_open() calling this in the first place.
*/
- if (MUTEX_NOT_HELD(&spa_namespace_lock)) {
- mutex_enter(&spa_namespace_lock);
+ if (!spa_namespace_held()) {
+ spa_namespace_enter(FTAG);
locked = B_TRUE;
}
if ((spa = spa_lookup(pool)) == NULL) {
if (locked)
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (SET_ERROR(ENOENT));
}
@@ -6004,7 +6069,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
spa_write_cachefile(spa, B_TRUE, B_TRUE, B_FALSE);
spa_remove(spa);
if (locked)
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (SET_ERROR(ENOENT));
}
@@ -6024,7 +6089,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
spa_deactivate(spa);
spa->spa_last_open_failed = error;
if (locked)
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
*spapp = NULL;
return (error);
}
@@ -6048,7 +6113,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
spa->spa_last_open_failed = 0;
spa->spa_last_ubsync_txg = 0;
spa->spa_load_txg = 0;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
if (firstopen)
@@ -6081,13 +6146,13 @@ spa_inject_addref(char *name)
{
spa_t *spa;
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if ((spa = spa_lookup(name)) == NULL) {
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (NULL);
}
spa->spa_inject_ref++;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (spa);
}
@@ -6095,9 +6160,9 @@ spa_inject_addref(char *name)
void
spa_inject_delref(spa_t *spa)
{
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa->spa_inject_ref--;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
/*
@@ -6341,14 +6406,14 @@ spa_get_stats(const char *name, nvlist_t **config,
*/
if (altroot) {
if (spa == NULL) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa = spa_lookup(name);
if (spa)
spa_altroot(spa, altroot, buflen);
else
altroot[0] = '\0';
spa = NULL;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
} else {
spa_altroot(spa, altroot, buflen);
}
@@ -6568,9 +6633,9 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
/*
* If this pool already exists, return failure.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if (spa_lookup(poolname) != NULL) {
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (SET_ERROR(EEXIST));
}
@@ -6588,7 +6653,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
if (props && (error = spa_prop_validate(spa, props))) {
spa_deactivate(spa);
spa_remove(spa);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (error);
}
@@ -6621,14 +6686,14 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
if (error != 0) {
spa_deactivate(spa);
spa_remove(spa);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (error);
}
}
if (!has_allocclass && zfs_special_devs(nvroot, NULL)) {
spa_deactivate(spa);
spa_remove(spa);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (ENOTSUP);
}
@@ -6694,7 +6759,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
spa_unload(spa);
spa_deactivate(spa);
spa_remove(spa);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (error);
}
@@ -6847,7 +6912,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
spa_import_os(spa);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (0);
}
@@ -6872,9 +6937,9 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
/*
* If a pool with this name exists, return failure.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if (spa_lookup(pool) != NULL) {
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (SET_ERROR(EEXIST));
}
@@ -6901,7 +6966,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
spa_write_cachefile(spa, B_FALSE, B_TRUE, B_FALSE);
spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT);
zfs_dbgmsg("spa_import: verbatim import of %s", pool);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (0);
}
@@ -6960,7 +7025,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
spa_unload(spa);
spa_deactivate(spa);
spa_remove(spa);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (error);
}
@@ -7028,7 +7093,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
zvol_create_minors(pool);
@@ -7060,7 +7125,7 @@ spa_tryimport(nvlist_t *tryconfig)
(void) snprintf(name, MAXPATHLEN, "%s-%llx-%s",
TRYIMPORT_NAME, (u_longlong_t)(uintptr_t)curthread, poolname);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa = spa_add(name, tryconfig, NULL);
spa_activate(spa, SPA_MODE_READ);
kmem_free(name, MAXPATHLEN);
@@ -7158,7 +7223,7 @@ spa_tryimport(nvlist_t *tryconfig)
spa_unload(spa);
spa_deactivate(spa);
spa_remove(spa);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (config);
}
@@ -7186,15 +7251,15 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
if (!(spa_mode_global & SPA_MODE_WRITE))
return (SET_ERROR(EROFS));
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if ((spa = spa_lookup(pool)) == NULL) {
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (SET_ERROR(ENOENT));
}
if (spa->spa_is_exporting) {
/* the pool is being exported by another thread */
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (SET_ERROR(ZFS_ERR_EXPORT_IN_PROGRESS));
}
spa->spa_is_exporting = B_TRUE;
@@ -7204,18 +7269,18 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
* and see if we can export.
*/
spa_open_ref(spa, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
spa_async_suspend(spa);
if (spa->spa_zvol_taskq) {
zvol_remove_minors(spa, spa_name(spa), B_TRUE);
taskq_wait(spa->spa_zvol_taskq);
}
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa->spa_export_thread = curthread;
spa_close(spa, FTAG);
if (spa->spa_state == POOL_STATE_UNINITIALIZED) {
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
goto export_spa;
}
@@ -7239,7 +7304,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
goto fail;
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
/*
* At this point we no longer hold the spa_namespace_lock and
* there were no references on the spa. Future spa_lookups will
@@ -7258,7 +7323,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
if (!force && new_state == POOL_STATE_EXPORTED &&
spa_has_active_shared_spare(spa)) {
error = SET_ERROR(EXDEV);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
goto fail;
}
@@ -7333,7 +7398,7 @@ export_spa:
/*
* Take the namespace lock for the actual spa_t removal
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if (new_state != POOL_STATE_UNINITIALIZED) {
if (!hardforce)
spa_write_cachefile(spa, B_TRUE, B_TRUE, B_FALSE);
@@ -7351,8 +7416,8 @@ export_spa:
/*
* Wake up any waiters in spa_lookup()
*/
- cv_broadcast(&spa_namespace_cv);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_broadcast();
+ spa_namespace_exit(FTAG);
return (0);
fail:
@@ -7363,8 +7428,8 @@ fail:
/*
* Wake up any waiters in spa_lookup()
*/
- cv_broadcast(&spa_namespace_cv);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_broadcast();
+ spa_namespace_exit(FTAG);
return (error);
}
@@ -7574,10 +7639,10 @@ spa_vdev_add(spa_t *spa, nvlist_t *nvroot, boolean_t check_ashift)
*/
(void) spa_vdev_exit(spa, vd, txg, 0);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
spa_event_notify(spa, NULL, NULL, ESC_ZFS_VDEV_ADD);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (0);
}
@@ -7694,7 +7759,7 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing,
oldvd = spa_lookup_by_guid(spa, guid, B_FALSE);
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) {
error = (spa_has_checkpoint(spa)) ?
ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT;
@@ -8078,7 +8143,7 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done)
* as spa_vdev_resilver_done() calls this function everything
* should be fine as the resilver will return right away.
*/
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) {
error = (spa_has_checkpoint(spa)) ?
ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT;
@@ -8282,28 +8347,28 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done)
if (unspare) {
spa_t *altspa = NULL;
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
while ((altspa = spa_next(altspa)) != NULL) {
if (altspa->spa_state != POOL_STATE_ACTIVE ||
altspa == spa)
continue;
spa_open_ref(altspa, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
(void) spa_vdev_remove(altspa, unspare_guid, B_TRUE);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_close(altspa, FTAG);
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
/* search the rest of the vdevs for spares to remove */
spa_vdev_resilver_done(spa);
}
/* all done with the spa; OK to release */
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_close(spa, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (error);
}
@@ -8312,7 +8377,7 @@ static int
spa_vdev_initialize_impl(spa_t *spa, uint64_t guid, uint64_t cmd_type,
list_t *vd_list)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER);
@@ -8396,7 +8461,7 @@ spa_vdev_initialize(spa_t *spa, nvlist_t *nv, uint64_t cmd_type,
* we can properly assess the vdev state before we commit to
* the initializing operation.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
for (nvpair_t *pair = nvlist_next_nvpair(nv, NULL);
pair != NULL; pair = nvlist_next_nvpair(nv, pair)) {
@@ -8419,7 +8484,7 @@ spa_vdev_initialize(spa_t *spa, nvlist_t *nv, uint64_t cmd_type,
/* Sync out the initializing state */
txg_wait_synced(spa->spa_dsl_pool, 0);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
list_destroy(&vd_list);
@@ -8430,7 +8495,7 @@ static int
spa_vdev_trim_impl(spa_t *spa, uint64_t guid, uint64_t cmd_type,
uint64_t rate, boolean_t partial, boolean_t secure, list_t *vd_list)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER);
@@ -8517,7 +8582,7 @@ spa_vdev_trim(spa_t *spa, nvlist_t *nv, uint64_t cmd_type, uint64_t rate,
* we can properly assess the vdev state before we commit to
* the TRIM operation.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
for (nvpair_t *pair = nvlist_next_nvpair(nv, NULL);
pair != NULL; pair = nvlist_next_nvpair(nv, pair)) {
@@ -8540,7 +8605,7 @@ spa_vdev_trim(spa_t *spa, nvlist_t *nv, uint64_t cmd_type, uint64_t rate,
/* Sync out the TRIM state */
txg_wait_synced(spa->spa_dsl_pool, 0);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
list_destroy(&vd_list);
@@ -8568,7 +8633,7 @@ spa_vdev_split_mirror(spa_t *spa, const char *newname, nvlist_t *config,
txg = spa_vdev_enter(spa);
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) {
error = (spa_has_checkpoint(spa)) ?
ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT;
@@ -9242,7 +9307,7 @@ spa_async_thread(void *arg)
if (tasks & SPA_ASYNC_CONFIG_UPDATE) {
uint64_t old_space, new_space;
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
old_space = metaslab_class_get_space(spa_normal_class(spa));
old_space += metaslab_class_get_space(spa_special_class(spa));
old_space += metaslab_class_get_space(spa_dedup_class(spa));
@@ -9260,7 +9325,7 @@ spa_async_thread(void *arg)
spa_embedded_log_class(spa));
new_space += metaslab_class_get_space(
spa_special_embedded_log_class(spa));
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
/*
* If the pool grew as a result of the config update,
@@ -9329,49 +9394,49 @@ spa_async_thread(void *arg)
dsl_scan_restart_resilver(dp, 0);
if (tasks & SPA_ASYNC_INITIALIZE_RESTART) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
vdev_initialize_restart(spa->spa_root_vdev);
spa_config_exit(spa, SCL_CONFIG, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
if (tasks & SPA_ASYNC_TRIM_RESTART) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
vdev_trim_restart(spa->spa_root_vdev);
spa_config_exit(spa, SCL_CONFIG, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
if (tasks & SPA_ASYNC_AUTOTRIM_RESTART) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
vdev_autotrim_restart(spa);
spa_config_exit(spa, SCL_CONFIG, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
/*
* Kick off L2 cache whole device TRIM.
*/
if (tasks & SPA_ASYNC_L2CACHE_TRIM) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
vdev_trim_l2arc(spa);
spa_config_exit(spa, SCL_CONFIG, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
/*
* Kick off L2 cache rebuilding.
*/
if (tasks & SPA_ASYNC_L2CACHE_REBUILD) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_config_enter(spa, SCL_L2ARC, FTAG, RW_READER);
l2arc_spa_rebuild_start(spa);
spa_config_exit(spa, SCL_L2ARC, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
/*
@@ -9601,7 +9666,8 @@ spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx)
KM_SLEEP));
memset(packed + nvsize, 0, bufsize - nvsize);
- dmu_write(spa->spa_meta_objset, obj, 0, bufsize, packed, tx);
+ dmu_write(spa->spa_meta_objset, obj, 0, bufsize, packed, tx,
+ DMU_READ_NO_PREFETCH);
vmem_free(packed, bufsize);
@@ -10522,18 +10588,18 @@ void
spa_sync_allpools(void)
{
spa_t *spa = NULL;
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
while ((spa = spa_next(spa)) != NULL) {
if (spa_state(spa) != POOL_STATE_ACTIVE ||
!spa_writeable(spa) || spa_suspended(spa))
continue;
spa_open_ref(spa, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
txg_wait_synced(spa_get_dsl(spa), 0);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_close(spa, FTAG);
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
taskq_t *
@@ -10680,7 +10746,7 @@ spa_evict_all(void)
* Remove all cached state. All pools should be closed now,
* so every spa in the AVL tree should be unreferenced.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
while ((spa = spa_next(NULL)) != NULL) {
/*
* Stop async tasks. The async thread may need to detach
@@ -10688,9 +10754,9 @@ spa_evict_all(void)
* spa_namespace_lock, so we must drop it here.
*/
spa_open_ref(spa, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
spa_async_suspend(spa);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_close(spa, FTAG);
if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
@@ -10699,7 +10765,7 @@ spa_evict_all(void)
}
spa_remove(spa);
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
vdev_t *
@@ -11272,6 +11338,9 @@ ZFS_MODULE_VIRTUAL_PARAM_CALL(zfs_zio, zio_, taskq_read,
ZFS_MODULE_VIRTUAL_PARAM_CALL(zfs_zio, zio_, taskq_write,
spa_taskq_write_param_set, spa_taskq_write_param_get, ZMOD_RW,
"Configure IO queues for write IO");
+ZFS_MODULE_VIRTUAL_PARAM_CALL(zfs_zio, zio_, taskq_free,
+ spa_taskq_free_param_set, spa_taskq_free_param_get, ZMOD_RW,
+ "Configure IO queues for free IO");
#endif
ZFS_MODULE_PARAM(zfs_zio, zio_, taskq_write_tpq, UINT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/spa_checkpoint.c b/sys/contrib/openzfs/module/zfs/spa_checkpoint.c
index e07756c46748..a42aa62e6599 100644
--- a/sys/contrib/openzfs/module/zfs/spa_checkpoint.c
+++ b/sys/contrib/openzfs/module/zfs/spa_checkpoint.c
@@ -427,7 +427,7 @@ spa_checkpoint_discard_thread(void *arg, zthr_t *zthr)
*/
int error = dmu_buf_hold_array_by_bonus(
checkpoint_sm->sm_dbuf, offset, size,
- B_TRUE, FTAG, &numbufs, &dbp);
+ B_TRUE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH);
if (error != 0) {
zfs_panic_recover("zfs: error %d was returned "
"while prefetching checkpoint space map "
diff --git a/sys/contrib/openzfs/module/zfs/spa_config.c b/sys/contrib/openzfs/module/zfs/spa_config.c
index f615591e826b..31216e9a7ccc 100644
--- a/sys/contrib/openzfs/module/zfs/spa_config.c
+++ b/sys/contrib/openzfs/module/zfs/spa_config.c
@@ -161,7 +161,7 @@ spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent,
boolean_t ccw_failure;
int error = 0;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
if (!(spa_mode_global & SPA_MODE_WRITE))
return;
@@ -287,7 +287,7 @@ spa_all_configs(uint64_t *generation, nvlist_t **pools)
if (*generation == spa_config_generation)
return (SET_ERROR(EEXIST));
- int error = mutex_enter_interruptible(&spa_namespace_lock);
+ int error = spa_namespace_enter_interruptible(FTAG);
if (error)
return (SET_ERROR(EINTR));
@@ -302,7 +302,7 @@ spa_all_configs(uint64_t *generation, nvlist_t **pools)
}
}
*generation = spa_config_generation;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (0);
}
@@ -483,7 +483,7 @@ spa_config_update(spa_t *spa, int what)
uint64_t txg;
int c;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
txg = spa_last_synced_txg(spa) + 1;
diff --git a/sys/contrib/openzfs/module/zfs/spa_history.c b/sys/contrib/openzfs/module/zfs/spa_history.c
index 60ab07944d72..b9d0c9656726 100644
--- a/sys/contrib/openzfs/module/zfs/spa_history.c
+++ b/sys/contrib/openzfs/module/zfs/spa_history.c
@@ -169,13 +169,14 @@ spa_history_write(spa_t *spa, void *buf, uint64_t len, spa_history_phys_t *shpp,
phys_eof = spa_history_log_to_phys(shpp->sh_eof, shpp);
firstwrite = MIN(len, shpp->sh_phys_max_off - phys_eof);
shpp->sh_eof += len;
- dmu_write(mos, spa->spa_history, phys_eof, firstwrite, buf, tx);
+ dmu_write(mos, spa->spa_history, phys_eof, firstwrite, buf, tx,
+ DMU_READ_NO_PREFETCH);
len -= firstwrite;
if (len > 0) {
/* write out the rest at the beginning of physical file */
dmu_write(mos, spa->spa_history, shpp->sh_pool_create_len,
- len, (char *)buf + firstwrite, tx);
+ len, (char *)buf + firstwrite, tx, DMU_READ_NO_PREFETCH);
}
return (0);
diff --git a/sys/contrib/openzfs/module/zfs/spa_misc.c b/sys/contrib/openzfs/module/zfs/spa_misc.c
index 0bead6d49666..bf22d2eb68e7 100644
--- a/sys/contrib/openzfs/module/zfs/spa_misc.c
+++ b/sys/contrib/openzfs/module/zfs/spa_misc.c
@@ -28,7 +28,7 @@
* Copyright (c) 2017 Datto Inc.
* Copyright (c) 2017, Intel Corporation.
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
- * Copyright (c) 2023, 2024, Klara Inc.
+ * Copyright (c) 2023, 2024, 2025, Klara, Inc.
*/
#include <sys/zfs_context.h>
@@ -237,9 +237,10 @@
* locking is, always, based on spa_namespace_lock and spa_config_lock[].
*/
-avl_tree_t spa_namespace_avl;
-kmutex_t spa_namespace_lock;
-kcondvar_t spa_namespace_cv;
+static avl_tree_t spa_namespace_avl;
+static kmutex_t spa_namespace_lock;
+static kcondvar_t spa_namespace_cv;
+
static const int spa_max_replication_override = SPA_DVAS_PER_BP;
static kmutex_t spa_spare_lock;
@@ -608,6 +609,58 @@ spa_config_held(spa_t *spa, int locks, krw_t rw)
* ==========================================================================
*/
+void
+spa_namespace_enter(const void *tag)
+{
+ (void) tag;
+ ASSERT(!MUTEX_HELD(&spa_namespace_lock));
+ mutex_enter(&spa_namespace_lock);
+}
+
+boolean_t
+spa_namespace_tryenter(const void *tag)
+{
+ (void) tag;
+ ASSERT(!MUTEX_HELD(&spa_namespace_lock));
+ return (mutex_tryenter(&spa_namespace_lock));
+}
+
+int
+spa_namespace_enter_interruptible(const void *tag)
+{
+ (void) tag;
+ ASSERT(!MUTEX_HELD(&spa_namespace_lock));
+ return (mutex_enter_interruptible(&spa_namespace_lock));
+}
+
+void
+spa_namespace_exit(const void *tag)
+{
+ (void) tag;
+ ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ mutex_exit(&spa_namespace_lock);
+}
+
+boolean_t
+spa_namespace_held(void)
+{
+ return (MUTEX_HELD(&spa_namespace_lock));
+}
+
+void
+spa_namespace_wait(void)
+{
+ ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ cv_wait(&spa_namespace_cv, &spa_namespace_lock);
+}
+
+void
+spa_namespace_broadcast(void)
+{
+ ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ cv_broadcast(&spa_namespace_cv);
+}
+
/*
* Lookup the named spa_t in the AVL tree. The spa_namespace_lock must be held.
* Returns NULL if no matching spa_t is found.
@@ -620,7 +673,7 @@ spa_lookup(const char *name)
avl_index_t where;
char *cp;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
retry:
(void) strlcpy(search.spa_name, name, sizeof (search.spa_name));
@@ -645,7 +698,7 @@ retry:
spa->spa_load_thread != curthread) ||
(spa->spa_export_thread != NULL &&
spa->spa_export_thread != curthread)) {
- cv_wait(&spa_namespace_cv, &spa_namespace_lock);
+ spa_namespace_wait();
goto retry;
}
@@ -697,7 +750,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
spa_t *spa;
spa_config_dirent_t *dp;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
spa = kmem_zalloc(sizeof (spa_t), KM_SLEEP);
@@ -747,7 +800,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
spa_config_lock_init(spa);
spa_stats_init(spa);
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
avl_add(&spa_namespace_avl, spa);
/*
@@ -837,7 +890,7 @@ spa_remove(spa_t *spa)
{
spa_config_dirent_t *dp;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
ASSERT(spa_state(spa) == POOL_STATE_UNINITIALIZED);
ASSERT3U(zfs_refcount_count(&spa->spa_refcount), ==, 0);
ASSERT0(spa->spa_waiters);
@@ -916,7 +969,7 @@ spa_remove(spa_t *spa)
spa_t *
spa_next(spa_t *prev)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
if (prev)
return (AVL_NEXT(&spa_namespace_avl, prev));
@@ -938,7 +991,7 @@ void
spa_open_ref(spa_t *spa, const void *tag)
{
ASSERT(zfs_refcount_count(&spa->spa_refcount) >= spa->spa_minref ||
- MUTEX_HELD(&spa_namespace_lock) ||
+ spa_namespace_held() ||
spa->spa_load_thread == curthread);
(void) zfs_refcount_add(&spa->spa_refcount, tag);
}
@@ -951,7 +1004,7 @@ void
spa_close(spa_t *spa, const void *tag)
{
ASSERT(zfs_refcount_count(&spa->spa_refcount) > spa->spa_minref ||
- MUTEX_HELD(&spa_namespace_lock) ||
+ spa_namespace_held() ||
spa->spa_load_thread == curthread ||
spa->spa_export_thread == curthread);
(void) zfs_refcount_remove(&spa->spa_refcount, tag);
@@ -980,7 +1033,7 @@ spa_async_close(spa_t *spa, const void *tag)
boolean_t
spa_refcount_zero(spa_t *spa)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_export_thread == curthread);
return (zfs_refcount_count(&spa->spa_refcount) == spa->spa_minref);
@@ -1227,7 +1280,7 @@ uint64_t
spa_vdev_enter(spa_t *spa)
{
mutex_enter(&spa->spa_vdev_top_lock);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
ASSERT0(spa->spa_export_thread);
@@ -1246,7 +1299,7 @@ uint64_t
spa_vdev_detach_enter(spa_t *spa, uint64_t guid)
{
mutex_enter(&spa->spa_vdev_top_lock);
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
ASSERT0(spa->spa_export_thread);
@@ -1270,7 +1323,7 @@ spa_vdev_detach_enter(spa_t *spa, uint64_t guid)
uint64_t
spa_vdev_config_enter(spa_t *spa)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
spa_config_enter(spa, SCL_ALL, spa, RW_WRITER);
@@ -1285,7 +1338,7 @@ void
spa_vdev_config_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error,
const char *tag)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
int config_changed = B_FALSE;
@@ -1374,7 +1427,7 @@ spa_vdev_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error)
vdev_rebuild_restart(spa);
spa_vdev_config_exit(spa, vd, txg, error, FTAG);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
mutex_exit(&spa->spa_vdev_top_lock);
return (error);
@@ -1452,9 +1505,9 @@ spa_vdev_state_exit(spa_t *spa, vdev_t *vd, int error)
* If the config changed, update the config cache.
*/
if (config_changed) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa_write_cachefile(spa, B_FALSE, B_TRUE, B_FALSE);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
return (error);
@@ -1501,7 +1554,7 @@ spa_by_guid(uint64_t pool_guid, uint64_t device_guid)
spa_t *spa;
avl_tree_t *t = &spa_namespace_avl;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
for (spa = avl_first(t); spa != NULL; spa = AVL_NEXT(t, spa)) {
if (spa->spa_state == POOL_STATE_UNINITIALIZED)
@@ -1583,7 +1636,7 @@ spa_load_guid_exists(uint64_t guid)
{
avl_tree_t *t = &spa_namespace_avl;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
for (spa_t *spa = avl_first(t); spa != NULL; spa = AVL_NEXT(t, spa)) {
if (spa_load_guid(spa) == guid)
@@ -2200,10 +2253,10 @@ spa_set_deadman_ziotime(hrtime_t ns)
spa_t *spa = NULL;
if (spa_mode_global != SPA_MODE_UNINIT) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
while ((spa = spa_next(spa)) != NULL)
spa->spa_deadman_ziotime = ns;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
}
@@ -2213,10 +2266,10 @@ spa_set_deadman_synctime(hrtime_t ns)
spa_t *spa = NULL;
if (spa_mode_global != SPA_MODE_UNINIT) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
while ((spa = spa_next(spa)) != NULL)
spa->spa_deadman_synctime = ns;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
}
@@ -3048,10 +3101,10 @@ param_set_deadman_failmode_common(const char *val)
return (SET_ERROR(EINVAL));
if (spa_mode_global != SPA_MODE_UNINIT) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
while ((spa = spa_next(spa)) != NULL)
spa_set_deadman_failmode(spa, val);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
}
return (0);
@@ -3135,7 +3188,6 @@ EXPORT_SYMBOL(spa_has_slogs);
EXPORT_SYMBOL(spa_is_root);
EXPORT_SYMBOL(spa_writeable);
EXPORT_SYMBOL(spa_mode);
-EXPORT_SYMBOL(spa_namespace_lock);
EXPORT_SYMBOL(spa_trust_config);
EXPORT_SYMBOL(spa_missing_tvds_allowed);
EXPORT_SYMBOL(spa_set_missing_tvds);
diff --git a/sys/contrib/openzfs/module/zfs/space_map.c b/sys/contrib/openzfs/module/zfs/space_map.c
index 5f24963f2291..f20c49ebb6de 100644
--- a/sys/contrib/openzfs/module/zfs/space_map.c
+++ b/sys/contrib/openzfs/module/zfs/space_map.c
@@ -537,7 +537,7 @@ space_map_write_intro_debug(space_map_t *sm, maptype_t maptype, dmu_tx_t *tx)
SM_DEBUG_TXG_ENCODE(dmu_tx_get_txg(tx));
dmu_write(sm->sm_os, space_map_object(sm), sm->sm_phys->smp_length,
- sizeof (dentry), &dentry, tx);
+ sizeof (dentry), &dentry, tx, DMU_READ_NO_PREFETCH);
sm->sm_phys->smp_length += sizeof (dentry);
}
diff --git a/sys/contrib/openzfs/module/zfs/vdev.c b/sys/contrib/openzfs/module/zfs/vdev.c
index c8d7280387a2..2a4d1876251f 100644
--- a/sys/contrib/openzfs/module/zfs/vdev.c
+++ b/sys/contrib/openzfs/module/zfs/vdev.c
@@ -449,32 +449,53 @@ vdev_get_nparity(vdev_t *vd)
}
static int
-vdev_prop_get_int(vdev_t *vd, vdev_prop_t prop, uint64_t *value)
+vdev_prop_get_objid(vdev_t *vd, uint64_t *objid)
{
- spa_t *spa = vd->vdev_spa;
- objset_t *mos = spa->spa_meta_objset;
- uint64_t objid;
- int err;
if (vd->vdev_root_zap != 0) {
- objid = vd->vdev_root_zap;
+ *objid = vd->vdev_root_zap;
} else if (vd->vdev_top_zap != 0) {
- objid = vd->vdev_top_zap;
+ *objid = vd->vdev_top_zap;
} else if (vd->vdev_leaf_zap != 0) {
- objid = vd->vdev_leaf_zap;
+ *objid = vd->vdev_leaf_zap;
} else {
return (EINVAL);
}
+ return (0);
+}
+
+static int
+vdev_prop_get_int(vdev_t *vd, vdev_prop_t prop, uint64_t *value)
+{
+ spa_t *spa = vd->vdev_spa;
+ objset_t *mos = spa->spa_meta_objset;
+ uint64_t objid;
+ int err;
+
+ if (vdev_prop_get_objid(vd, &objid) != 0)
+ return (EINVAL);
+
err = zap_lookup(mos, objid, vdev_prop_to_name(prop),
sizeof (uint64_t), 1, value);
-
if (err == ENOENT)
*value = vdev_prop_default_numeric(prop);
return (err);
}
+static int
+vdev_prop_get_bool(vdev_t *vd, vdev_prop_t prop, boolean_t *bvalue)
+{
+ int err;
+ uint64_t ivalue;
+
+ err = vdev_prop_get_int(vd, prop, &ivalue);
+ *bvalue = ivalue != 0;
+
+ return (err);
+}
+
/*
* Get the number of data disks for a top-level vdev.
*/
@@ -737,8 +758,12 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops)
*/
vd->vdev_checksum_n = vdev_prop_default_numeric(VDEV_PROP_CHECKSUM_N);
vd->vdev_checksum_t = vdev_prop_default_numeric(VDEV_PROP_CHECKSUM_T);
+
vd->vdev_io_n = vdev_prop_default_numeric(VDEV_PROP_IO_N);
vd->vdev_io_t = vdev_prop_default_numeric(VDEV_PROP_IO_T);
+
+ vd->vdev_slow_io_events = vdev_prop_default_numeric(
+ VDEV_PROP_SLOW_IO_EVENTS);
vd->vdev_slow_io_n = vdev_prop_default_numeric(VDEV_PROP_SLOW_IO_N);
vd->vdev_slow_io_t = vdev_prop_default_numeric(VDEV_PROP_SLOW_IO_T);
@@ -3931,6 +3956,11 @@ vdev_load(vdev_t *vd)
vdev_dbgmsg(vd, "vdev_load: zap_lookup(zap=%llu) "
"failed [error=%d]", (u_longlong_t)zapobj, error);
+ error = vdev_prop_get_bool(vd, VDEV_PROP_SLOW_IO_EVENTS,
+ &vd->vdev_slow_io_events);
+ if (error && error != ENOENT)
+ vdev_dbgmsg(vd, "vdev_load: zap_lookup(zap=%llu) "
+ "failed [error=%d]", (u_longlong_t)zapobj, error);
error = vdev_prop_get_int(vd, VDEV_PROP_SLOW_IO_N,
&vd->vdev_slow_io_n);
if (error && error != ENOENT)
@@ -5980,15 +6010,8 @@ vdev_props_set_sync(void *arg, dmu_tx_t *tx)
/*
* Set vdev property values in the vdev props mos object.
*/
- if (vd->vdev_root_zap != 0) {
- objid = vd->vdev_root_zap;
- } else if (vd->vdev_top_zap != 0) {
- objid = vd->vdev_top_zap;
- } else if (vd->vdev_leaf_zap != 0) {
- objid = vd->vdev_leaf_zap;
- } else {
+ if (vdev_prop_get_objid(vd, &objid) != 0)
panic("unexpected vdev type");
- }
mutex_enter(&spa->spa_props_lock);
@@ -6215,6 +6238,13 @@ vdev_prop_set(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
}
vd->vdev_io_t = intval;
break;
+ case VDEV_PROP_SLOW_IO_EVENTS:
+ if (nvpair_value_uint64(elem, &intval) != 0) {
+ error = EINVAL;
+ break;
+ }
+ vd->vdev_slow_io_events = intval != 0;
+ break;
case VDEV_PROP_SLOW_IO_N:
if (nvpair_value_uint64(elem, &intval) != 0) {
error = EINVAL;
@@ -6256,6 +6286,7 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
nvpair_t *elem = NULL;
nvlist_t *nvprops = NULL;
uint64_t intval = 0;
+ boolean_t boolval = 0;
char *strval = NULL;
const char *propname = NULL;
vdev_prop_t prop;
@@ -6269,15 +6300,8 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
nvlist_lookup_nvlist(innvl, ZPOOL_VDEV_PROPS_GET_PROPS, &nvprops);
- if (vd->vdev_root_zap != 0) {
- objid = vd->vdev_root_zap;
- } else if (vd->vdev_top_zap != 0) {
- objid = vd->vdev_top_zap;
- } else if (vd->vdev_leaf_zap != 0) {
- objid = vd->vdev_leaf_zap;
- } else {
+ if (vdev_prop_get_objid(vd, &objid) != 0)
return (SET_ERROR(EINVAL));
- }
ASSERT(objid != 0);
mutex_enter(&spa->spa_props_lock);
@@ -6622,6 +6646,18 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
intval, src);
break;
+ case VDEV_PROP_SLOW_IO_EVENTS:
+ err = vdev_prop_get_bool(vd, prop, &boolval);
+ if (err && err != ENOENT)
+ break;
+
+ src = ZPROP_SRC_LOCAL;
+ if (boolval == vdev_prop_default_numeric(prop))
+ src = ZPROP_SRC_DEFAULT;
+
+ vdev_prop_add_list(outnvl, propname, NULL,
+ boolval, src);
+ break;
case VDEV_PROP_CHECKSUM_N:
case VDEV_PROP_CHECKSUM_T:
case VDEV_PROP_IO_N:
diff --git a/sys/contrib/openzfs/module/zfs/vdev_indirect_births.c b/sys/contrib/openzfs/module/zfs/vdev_indirect_births.c
index c0127829c26c..ab7069f44b37 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_indirect_births.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_indirect_births.c
@@ -147,7 +147,7 @@ vdev_indirect_births_add_entry(vdev_indirect_births_t *vib,
old_size = vdev_indirect_births_size_impl(vib);
dmu_write(vib->vib_objset, vib->vib_object, old_size, sizeof (vibe),
- &vibe, tx);
+ &vibe, tx, DMU_READ_NO_PREFETCH);
vib->vib_phys->vib_count++;
new_size = vdev_indirect_births_size_impl(vib);
diff --git a/sys/contrib/openzfs/module/zfs/vdev_indirect_mapping.c b/sys/contrib/openzfs/module/zfs/vdev_indirect_mapping.c
index 1515ddc1baa2..da90a8de016f 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_indirect_mapping.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_indirect_mapping.c
@@ -459,13 +459,14 @@ vdev_indirect_mapping_add_entries(vdev_indirect_mapping_t *vim,
dmu_write(vim->vim_objset, vim->vim_object,
vim->vim_phys->vimp_num_entries * sizeof (*mapbuf),
i * sizeof (*mapbuf),
- mapbuf, tx);
+ mapbuf, tx, DMU_READ_NO_PREFETCH);
if (vim->vim_havecounts) {
dmu_write(vim->vim_objset,
vim->vim_phys->vimp_counts_object,
vim->vim_phys->vimp_num_entries *
sizeof (*countbuf),
- i * sizeof (*countbuf), countbuf, tx);
+ i * sizeof (*countbuf), countbuf, tx,
+ DMU_READ_NO_PREFETCH);
}
vim->vim_phys->vimp_num_entries += i;
}
diff --git a/sys/contrib/openzfs/module/zfs/vdev_initialize.c b/sys/contrib/openzfs/module/zfs/vdev_initialize.c
index 27188c46e561..d13da1e5a663 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_initialize.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_initialize.c
@@ -685,7 +685,7 @@ vdev_initialize_stop_wait(spa_t *spa, list_t *vd_list)
(void) spa;
vdev_t *vd;
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_export_thread == curthread);
while ((vd = list_remove_head(vd_list)) != NULL) {
@@ -728,7 +728,7 @@ vdev_initialize_stop(vdev_t *vd, vdev_initializing_state_t tgt_state,
if (vd_list == NULL) {
vdev_initialize_stop_wait_impl(vd);
} else {
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
vd->vdev_spa->spa_export_thread == curthread);
list_insert_tail(vd_list, vd);
}
@@ -761,7 +761,7 @@ vdev_initialize_stop_all(vdev_t *vd, vdev_initializing_state_t tgt_state)
spa_t *spa = vd->vdev_spa;
list_t vd_list;
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_export_thread == curthread);
list_create(&vd_list, sizeof (vdev_t),
@@ -781,7 +781,7 @@ vdev_initialize_stop_all(vdev_t *vd, vdev_initializing_state_t tgt_state)
void
vdev_initialize_restart(vdev_t *vd)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
vd->vdev_spa->spa_load_thread == curthread);
ASSERT(!spa_config_held(vd->vdev_spa, SCL_ALL, RW_WRITER));
diff --git a/sys/contrib/openzfs/module/zfs/vdev_label.c b/sys/contrib/openzfs/module/zfs/vdev_label.c
index 0d4fdaa77ba0..7e222eac5edc 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_label.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_label.c
@@ -862,8 +862,8 @@ retry:
}
}
- if (config == NULL && !(flags & ZIO_FLAG_TRYHARD)) {
- flags |= ZIO_FLAG_TRYHARD;
+ if (config == NULL && !(flags & ZIO_FLAG_IO_RETRY)) {
+ flags |= ZIO_FLAG_IO_RETRY;
goto retry;
}
@@ -1079,7 +1079,8 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason)
size_t buflen;
int error;
uint64_t spare_guid = 0, l2cache_guid = 0;
- int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL;
+ int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL |
+ ZIO_FLAG_TRYHARD;
boolean_t reason_spare = (reason == VDEV_LABEL_SPARE || (reason ==
VDEV_LABEL_REMOVE && vd->vdev_isspare));
boolean_t reason_l2cache = (reason == VDEV_LABEL_L2CACHE || (reason ==
@@ -1223,7 +1224,6 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason)
/*
* Write everything in parallel.
*/
-retry:
zio = zio_root(spa, NULL, NULL, flags);
for (int l = 0; l < VDEV_LABELS; l++) {
@@ -1248,11 +1248,6 @@ retry:
error = zio_wait(zio);
- if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) {
- flags |= ZIO_FLAG_TRYHARD;
- goto retry;
- }
-
nvlist_free(label);
abd_free(bootenv);
abd_free(ub_abd);
@@ -1398,7 +1393,8 @@ vdev_label_write_bootenv(vdev_t *vd, nvlist_t *env)
zio_t *zio;
spa_t *spa = vd->vdev_spa;
vdev_boot_envblock_t *bootenv;
- int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL;
+ int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL |
+ ZIO_FLAG_TRYHARD;
int error;
size_t nvsize;
char *nvbuf;
@@ -1466,7 +1462,6 @@ vdev_label_write_bootenv(vdev_t *vd, nvlist_t *env)
return (SET_ERROR(error));
}
-retry:
zio = zio_root(spa, NULL, NULL, flags);
for (int l = 0; l < VDEV_LABELS; l++) {
vdev_label_write(zio, vd, l, abd,
@@ -1475,10 +1470,6 @@ retry:
}
error = zio_wait(zio);
- if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) {
- flags |= ZIO_FLAG_TRYHARD;
- goto retry;
- }
abd_free(abd);
return (error);
@@ -2056,13 +2047,13 @@ retry:
* Normally, we don't want to try too hard to write every label and
* uberblock. If there is a flaky disk, we don't want the rest of the
* sync process to block while we retry. But if we can't write a
- * single label out, we should retry with ZIO_FLAG_TRYHARD before
+ * single label out, we should retry with ZIO_FLAG_IO_RETRY before
* bailing out and declaring the pool faulted.
*/
if (error != 0) {
- if ((flags & ZIO_FLAG_TRYHARD) != 0)
+ if ((flags & ZIO_FLAG_IO_RETRY) != 0)
return (error);
- flags |= ZIO_FLAG_TRYHARD;
+ flags |= ZIO_FLAG_IO_RETRY;
}
ASSERT(ub->ub_txg <= txg);
@@ -2113,7 +2104,7 @@ retry:
* are committed to stable storage before the uberblock update.
*/
if ((error = vdev_label_sync_list(spa, 0, txg, flags)) != 0) {
- if ((flags & ZIO_FLAG_TRYHARD) != 0) {
+ if ((flags & ZIO_FLAG_IO_RETRY) != 0) {
zfs_dbgmsg("vdev_label_sync_list() returned error %d "
"for pool '%s' when syncing out the even labels "
"of dirty vdevs", error, spa_name(spa));
@@ -2137,7 +2128,7 @@ retry:
* to the new uberblocks.
*/
if ((error = vdev_uberblock_sync_list(svd, svdcount, ub, flags)) != 0) {
- if ((flags & ZIO_FLAG_TRYHARD) != 0) {
+ if ((flags & ZIO_FLAG_IO_RETRY) != 0) {
zfs_dbgmsg("vdev_uberblock_sync_list() returned error "
"%d for pool '%s'", error, spa_name(spa));
}
@@ -2158,7 +2149,7 @@ retry:
* stable storage before the next transaction group begins.
*/
if ((error = vdev_label_sync_list(spa, 1, txg, flags)) != 0) {
- if ((flags & ZIO_FLAG_TRYHARD) != 0) {
+ if ((flags & ZIO_FLAG_IO_RETRY) != 0) {
zfs_dbgmsg("vdev_label_sync_list() returned error %d "
"for pool '%s' when syncing out the odd labels of "
"dirty vdevs", error, spa_name(spa));
diff --git a/sys/contrib/openzfs/module/zfs/vdev_raidz.c b/sys/contrib/openzfs/module/zfs/vdev_raidz.c
index 56b8e3b60b22..5fe70ec2b1d5 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_raidz.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_raidz.c
@@ -4872,7 +4872,7 @@ spa_raidz_expand_thread(void *arg, zthr_t *zthr)
else
vre->vre_offset = RRSS_GET_OFFSET(&spa->spa_ubsync);
- /* Reflow the begining portion using the scratch area */
+ /* Reflow the beginning portion using the scratch area */
if (vre->vre_offset == 0) {
VERIFY0(dsl_sync_task(spa_name(spa),
NULL, raidz_reflow_scratch_sync,
diff --git a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
index 47b3b9921abe..30be1f851eb3 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
@@ -1079,7 +1079,7 @@ vdev_rebuild_restart_impl(vdev_t *vd)
void
vdev_rebuild_restart(spa_t *spa)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_load_thread == curthread);
vdev_rebuild_restart_impl(spa->spa_root_vdev);
@@ -1094,7 +1094,7 @@ vdev_rebuild_stop_wait(vdev_t *vd)
{
spa_t *spa = vd->vdev_spa;
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_export_thread == curthread);
if (vd == spa->spa_root_vdev) {
diff --git a/sys/contrib/openzfs/module/zfs/vdev_removal.c b/sys/contrib/openzfs/module/zfs/vdev_removal.c
index abb71543e3ab..81e6ecb68ff1 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_removal.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_removal.c
@@ -309,12 +309,12 @@ spa_vdev_noalloc(spa_t *spa, uint64_t guid)
uint64_t txg;
int error = 0;
- ASSERT(!MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(!spa_namespace_held());
ASSERT(spa_writeable(spa));
txg = spa_vdev_enter(spa);
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
vd = spa_lookup_by_guid(spa, guid, B_FALSE);
@@ -342,12 +342,12 @@ spa_vdev_alloc(spa_t *spa, uint64_t guid)
uint64_t txg;
int error = 0;
- ASSERT(!MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(!spa_namespace_held());
ASSERT(spa_writeable(spa));
txg = spa_vdev_enter(spa);
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
vd = spa_lookup_by_guid(spa, guid, B_FALSE);
@@ -2085,7 +2085,7 @@ vdev_remove_make_hole_and_free(vdev_t *vd)
spa_t *spa = vd->vdev_spa;
vdev_t *rvd = spa->spa_root_vdev;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
vdev_free(vd);
@@ -2113,7 +2113,7 @@ spa_vdev_remove_log(vdev_t *vd, uint64_t *txg)
ASSERT(vd->vdev_islog);
ASSERT(vd == vd->vdev_top);
ASSERT0P(vd->vdev_log_mg);
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
/*
* Stop allocating from this vdev.
@@ -2140,7 +2140,7 @@ spa_vdev_remove_log(vdev_t *vd, uint64_t *txg)
* spa_namespace_lock held. Once this completes the device
* should no longer have any blocks allocated on it.
*/
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
if (vd->vdev_stat.vs_alloc != 0)
error = spa_reset_logs(spa);
@@ -2189,7 +2189,7 @@ spa_vdev_remove_log(vdev_t *vd, uint64_t *txg)
sysevent_t *ev = spa_event_create(spa, vd, NULL,
ESC_ZFS_VDEV_REMOVE_DEV);
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
/* The top ZAP should have been destroyed by vdev_remove_empty. */
@@ -2433,7 +2433,7 @@ spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare)
uint64_t txg = 0;
uint_t nspares, nl2cache;
int error = 0, error_log;
- boolean_t locked = MUTEX_HELD(&spa_namespace_lock);
+ boolean_t locked = spa_namespace_held();
sysevent_t *ev = NULL;
const char *vd_type = NULL;
char *vd_path = NULL;
@@ -2443,7 +2443,7 @@ spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare)
if (!locked)
txg = spa_vdev_enter(spa);
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) {
error = (spa_has_checkpoint(spa)) ?
ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT;
diff --git a/sys/contrib/openzfs/module/zfs/vdev_trim.c b/sys/contrib/openzfs/module/zfs/vdev_trim.c
index eee18b367909..a97f6650a81c 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_trim.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_trim.c
@@ -1045,7 +1045,7 @@ vdev_trim_stop_wait(spa_t *spa, list_t *vd_list)
(void) spa;
vdev_t *vd;
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_export_thread == curthread);
while ((vd = list_remove_head(vd_list)) != NULL) {
@@ -1085,7 +1085,7 @@ vdev_trim_stop(vdev_t *vd, vdev_trim_state_t tgt_state, list_t *vd_list)
if (vd_list == NULL) {
vdev_trim_stop_wait_impl(vd);
} else {
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
vd->vdev_spa->spa_export_thread == curthread);
list_insert_tail(vd_list, vd);
}
@@ -1122,7 +1122,7 @@ vdev_trim_stop_all(vdev_t *vd, vdev_trim_state_t tgt_state)
list_t vd_list;
vdev_t *vd_l2cache;
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_export_thread == curthread);
list_create(&vd_list, sizeof (vdev_t),
@@ -1156,7 +1156,7 @@ vdev_trim_stop_all(vdev_t *vd, vdev_trim_state_t tgt_state)
void
vdev_trim_restart(vdev_t *vd)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
vd->vdev_spa->spa_load_thread == curthread);
ASSERT(!spa_config_held(vd->vdev_spa, SCL_ALL, RW_WRITER));
@@ -1582,7 +1582,7 @@ vdev_autotrim_stop_all(spa_t *spa)
void
vdev_autotrim_restart(spa_t *spa)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
+ ASSERT(spa_namespace_held() ||
spa->spa_load_thread == curthread);
if (spa->spa_autotrim)
vdev_autotrim(spa);
@@ -1689,7 +1689,7 @@ vdev_trim_l2arc_thread(void *arg)
void
vdev_trim_l2arc(spa_t *spa)
{
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
/*
* Locate the spa's l2arc devices and kick off TRIM threads.
diff --git a/sys/contrib/openzfs/module/zfs/zap_micro.c b/sys/contrib/openzfs/module/zfs/zap_micro.c
index ea4e3117a8b9..7e9e625a193e 100644
--- a/sys/contrib/openzfs/module/zfs/zap_micro.c
+++ b/sys/contrib/openzfs/module/zfs/zap_micro.c
@@ -625,12 +625,10 @@ zap_lockdir_impl(dnode_t *dn, dmu_buf_t *db, const void *tag, dmu_tx_t *tx,
ASSERT0(db->db_offset);
objset_t *os = dmu_buf_get_objset(db);
uint64_t obj = db->db_object;
- dmu_object_info_t doi;
*zapp = NULL;
- dmu_object_info_from_dnode(dn, &doi);
- if (DMU_OT_BYTESWAP(doi.doi_type) != DMU_BSWAP_ZAP)
+ if (DMU_OT_BYTESWAP(dn->dn_type) != DMU_BSWAP_ZAP)
return (SET_ERROR(EINVAL));
zap_t *zap = dmu_buf_get_user(db);
diff --git a/sys/contrib/openzfs/module/zfs/zfs_fm.c b/sys/contrib/openzfs/module/zfs/zfs_fm.c
index 221f24e381dc..4a0d41c24eed 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_fm.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_fm.c
@@ -223,6 +223,9 @@ vdev_prop_get_inherited(vdev_t *vd, vdev_prop_t prop)
case VDEV_PROP_IO_T:
propval = vd->vdev_io_t;
break;
+ case VDEV_PROP_SLOW_IO_EVENTS:
+ propval = vd->vdev_slow_io_events;
+ break;
case VDEV_PROP_SLOW_IO_N:
propval = vd->vdev_slow_io_n;
break;
@@ -1580,10 +1583,10 @@ zfs_ereport_zvol_post(const char *subclass, const char *name,
nvlist_t *aux;
char *r;
- boolean_t locked = mutex_owned(&spa_namespace_lock);
- if (!locked) mutex_enter(&spa_namespace_lock);
+ boolean_t locked = spa_namespace_held();
+ if (!locked) spa_namespace_enter(FTAG);
spa_t *spa = spa_lookup(name);
- if (!locked) mutex_exit(&spa_namespace_lock);
+ if (!locked) spa_namespace_exit(FTAG);
if (spa == NULL)
return;
diff --git a/sys/contrib/openzfs/module/zfs/zfs_fuid.c b/sys/contrib/openzfs/module/zfs/zfs_fuid.c
index 2af1efe82e62..7f786c00b93a 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_fuid.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_fuid.c
@@ -268,7 +268,7 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
nvlist_free(nvp);
zfsvfs->z_fuid_size = nvsize;
dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0,
- zfsvfs->z_fuid_size, packed, tx);
+ zfsvfs->z_fuid_size, packed, tx, DMU_READ_NO_PREFETCH);
kmem_free(packed, zfsvfs->z_fuid_size);
VERIFY0(dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj, FTAG, &db));
dmu_buf_will_dirty(db, tx);
diff --git a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
index 5ca7c2320c4e..1b2392aeaa85 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
@@ -212,6 +212,8 @@
#include <sys/vdev_impl.h>
#include <sys/vdev_initialize.h>
#include <sys/vdev_trim.h>
+#include <sys/brt.h>
+#include <sys/ddt.h>
#include "zfs_namecheck.h"
#include "zfs_prop.h"
@@ -3122,12 +3124,12 @@ zfs_ioc_pool_set_props(zfs_cmd_t *zc)
if (pair != NULL && strcmp(nvpair_name(pair),
zpool_prop_to_name(ZPOOL_PROP_CACHEFILE)) == 0 &&
nvlist_next_nvpair(props, pair) == NULL) {
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if ((spa = spa_lookup(zc->zc_name)) != NULL) {
spa_configfile_set(spa, props, B_FALSE);
spa_write_cachefile(spa, B_FALSE, B_TRUE, B_FALSE);
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
if (spa != NULL) {
nvlist_free(props);
return (0);
@@ -3176,14 +3178,14 @@ zfs_ioc_pool_get_props(const char *pool, nvlist_t *innvl, nvlist_t *outnvl)
* get (such as altroot and cachefile), so attempt to get them
* anyway.
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
if ((spa = spa_lookup(pool)) != NULL) {
error = spa_prop_get(spa, outnvl);
if (error == 0 && props != NULL)
error = spa_prop_get_nvlist(spa, props, n_props,
outnvl);
}
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
} else {
error = spa_prop_get(spa, outnvl);
if (error == 0 && props != NULL)
@@ -4276,13 +4278,11 @@ zfs_ioc_pool_prefetch(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
spa_t *spa;
int32_t type;
- /*
- * Currently, only ZPOOL_PREFETCH_DDT is supported
- */
- if (nvlist_lookup_int32(innvl, ZPOOL_PREFETCH_TYPE, &type) != 0 ||
- type != ZPOOL_PREFETCH_DDT) {
+ if (nvlist_lookup_int32(innvl, ZPOOL_PREFETCH_TYPE, &type) != 0)
+ return (EINVAL);
+
+ if (type != ZPOOL_PREFETCH_DDT && type != ZPOOL_PREFETCH_BRT)
return (EINVAL);
- }
error = spa_open(poolname, &spa, FTAG);
if (error != 0)
@@ -4290,10 +4290,17 @@ zfs_ioc_pool_prefetch(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
hrtime_t start_time = gethrtime();
- ddt_prefetch_all(spa);
-
- zfs_dbgmsg("pool '%s': loaded ddt into ARC in %llu ms", spa->spa_name,
- (u_longlong_t)NSEC2MSEC(gethrtime() - start_time));
+ if (type == ZPOOL_PREFETCH_DDT) {
+ ddt_prefetch_all(spa);
+ zfs_dbgmsg("pool '%s': loaded ddt into ARC in %llu ms",
+ spa->spa_name,
+ (u_longlong_t)NSEC2MSEC(gethrtime() - start_time));
+ } else {
+ brt_prefetch_all(spa);
+ zfs_dbgmsg("pool '%s': loaded brt into ARC in %llu ms",
+ spa->spa_name,
+ (u_longlong_t)NSEC2MSEC(gethrtime() - start_time));
+ }
spa_close(spa, FTAG);
@@ -6121,10 +6128,10 @@ zfs_ioc_clear(zfs_cmd_t *zc)
/*
* On zpool clear we also fix up missing slogs
*/
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
spa = spa_lookup(zc->zc_name);
if (spa == NULL) {
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (SET_ERROR(EIO));
}
if (spa_get_log_state(spa) == SPA_LOG_MISSING) {
@@ -6132,7 +6139,7 @@ zfs_ioc_clear(zfs_cmd_t *zc)
spa_set_log_state(spa, SPA_LOG_CLEAR);
}
spa->spa_last_open_failed = 0;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
if (zc->zc_cookie & ZPOOL_NO_REWIND) {
error = spa_open(zc->zc_name, &spa, FTAG);
diff --git a/sys/contrib/openzfs/module/zfs/zio.c b/sys/contrib/openzfs/module/zfs/zio.c
index aeea58bedfe4..74373f759cec 100644
--- a/sys/contrib/openzfs/module/zfs/zio.c
+++ b/sys/contrib/openzfs/module/zfs/zio.c
@@ -3318,8 +3318,8 @@ zio_write_gang_block(zio_t *pio, metaslab_class_t *mc)
} else if (any_failed && candidate > SPA_OLD_GANGBLOCKSIZE &&
spa_feature_is_enabled(spa, SPA_FEATURE_DYNAMIC_GANG_HEADER) &&
!spa_feature_is_active(spa, SPA_FEATURE_DYNAMIC_GANG_HEADER)) {
- dmu_tx_t *tx =
- dmu_tx_create_assigned(spa->spa_dsl_pool, txg + 1);
+ dmu_tx_t *tx = dmu_tx_create_assigned(spa->spa_dsl_pool,
+ MAX(txg, spa_syncing_txg(spa) + 1));
dsl_sync_task_nowait(spa->spa_dsl_pool,
zio_update_feature,
(void *)SPA_FEATURE_DYNAMIC_GANG_HEADER, tx);
@@ -5569,9 +5569,12 @@ zio_done(zio_t *zio)
zio->io_vd->vdev_stat.vs_slow_ios++;
mutex_exit(&zio->io_vd->vdev_stat_lock);
- (void) zfs_ereport_post(FM_EREPORT_ZFS_DELAY,
- zio->io_spa, zio->io_vd, &zio->io_bookmark,
- zio, 0);
+ if (zio->io_vd->vdev_slow_io_events) {
+ (void) zfs_ereport_post(
+ FM_EREPORT_ZFS_DELAY,
+ zio->io_spa, zio->io_vd,
+ &zio->io_bookmark, zio, 0);
+ }
}
}
}
diff --git a/sys/contrib/openzfs/module/zfs/zio_inject.c b/sys/contrib/openzfs/module/zfs/zio_inject.c
index 287577018ed1..c3adfdab54ce 100644
--- a/sys/contrib/openzfs/module/zfs/zio_inject.c
+++ b/sys/contrib/openzfs/module/zfs/zio_inject.c
@@ -1008,9 +1008,9 @@ zio_inject_fault(char *name, int flags, int *id, zinject_record_t *record)
if (zio_pool_handler_exists(name, record->zi_cmd))
return (SET_ERROR(EEXIST));
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
boolean_t has_spa = spa_lookup(name) != NULL;
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
if (record->zi_cmd == ZINJECT_DELAY_IMPORT && has_spa)
return (SET_ERROR(EEXIST));
@@ -1095,7 +1095,7 @@ zio_inject_list_next(int *id, char *name, size_t buflen,
inject_handler_t *handler;
int ret;
- mutex_enter(&spa_namespace_lock);
+ spa_namespace_enter(FTAG);
rw_enter(&inject_lock, RW_READER);
for (handler = list_head(&inject_handlers); handler != NULL;
@@ -1117,7 +1117,7 @@ zio_inject_list_next(int *id, char *name, size_t buflen,
}
rw_exit(&inject_lock);
- mutex_exit(&spa_namespace_lock);
+ spa_namespace_exit(FTAG);
return (ret);
}
diff --git a/sys/contrib/openzfs/module/zfs/zvol.c b/sys/contrib/openzfs/module/zfs/zvol.c
index 00f98168d3d8..407758641580 100644
--- a/sys/contrib/openzfs/module/zfs/zvol.c
+++ b/sys/contrib/openzfs/module/zfs/zvol.c
@@ -547,7 +547,8 @@ zvol_replay_write(void *arg1, void *arg2, boolean_t byteswap)
if (error) {
dmu_tx_abort(tx);
} else {
- dmu_write(os, ZVOL_OBJ, offset, length, data, tx);
+ dmu_write(os, ZVOL_OBJ, offset, length, data, tx,
+ DMU_READ_PREFETCH);
(void) zil_replaying(zv->zv_zilog, tx);
dmu_tx_commit(tx);
}
@@ -1232,7 +1233,7 @@ zvol_first_open(zvol_state_t *zv, boolean_t readonly)
ASSERT(RW_READ_HELD(&zv->zv_suspend_lock));
ASSERT(MUTEX_HELD(&zv->zv_state_lock));
- ASSERT(mutex_owned(&spa_namespace_lock));
+ ASSERT(spa_namespace_held());
boolean_t ro = (readonly || (strchr(zv->zv_name, '@') != NULL));
error = dmu_objset_own(zv->zv_name, DMU_OST_ZVOL, ro, B_TRUE, zv, &os);
@@ -1302,7 +1303,7 @@ zvol_create_snap_minor_cb(const char *dsname, void *arg)
list_t *minors_list = j->list;
const char *name = j->name;
- ASSERT0(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT0(spa_namespace_held());
/* skip the designated dataset */
if (name && strcmp(dsname, name) == 0)
@@ -1402,7 +1403,7 @@ zvol_create_minors_cb(const char *dsname, void *arg)
int error;
list_t *minors_list = arg;
- ASSERT0(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT0(spa_namespace_held());
error = dsl_prop_get_integer(dsname, "snapdev", &snapdev, NULL);
if (error)
diff --git a/sys/contrib/openzfs/module/zstd/include/aarch64_compat.h b/sys/contrib/openzfs/module/zstd/include/aarch64_compat.h
deleted file mode 100644
index 9500a832b81c..000000000000
--- a/sys/contrib/openzfs/module/zstd/include/aarch64_compat.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-/*
- * BSD 3-Clause New License (https://spdx.org/licenses/BSD-3-Clause.html)
- *
- * 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.
- *
- * 3. Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
- */
-
-/*
- * Copyright (c) 2018-2020, Sebastian Gottschall
- */
-
-#ifdef _KERNEL
-#undef __aarch64__
-#endif
diff --git a/sys/contrib/openzfs/module/zstd/lib/common/compiler.h b/sys/contrib/openzfs/module/zstd/lib/common/compiler.h
index d0f588e2ec3c..c8d65a201212 100644
--- a/sys/contrib/openzfs/module/zstd/lib/common/compiler.h
+++ b/sys/contrib/openzfs/module/zstd/lib/common/compiler.h
@@ -115,9 +115,6 @@
# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
-# elif defined(__aarch64__)
-# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
-# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr)))
# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
diff --git a/sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h b/sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h
index 6b1fc44cf9f6..9650af77bcea 100644
--- a/sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h
+++ b/sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h
@@ -12,6 +12,15 @@
#ifndef ZSTD_CCOMMON_H_MODULE
#define ZSTD_CCOMMON_H_MODULE
+/*
+ * Disable the aarch64 NEON SIMD intrinsics for kernel builds. Safely
+ * using them in the kernel context requires saving/restoring the FPU
+ * registers which is not currently done.
+ */
+#ifdef _KERNEL
+#define ZSTD_NO_INTRINSICS
+#endif
+
/* this module contains definitions which must be identical
* across compression, decompression and dictBuilder.
* It also contains a few functions useful to at least 2 of them
diff --git a/sys/contrib/openzfs/rpm/generic/zfs.spec.in b/sys/contrib/openzfs/rpm/generic/zfs.spec.in
index 8986e29eb7fb..9ae479aeb96b 100644
--- a/sys/contrib/openzfs/rpm/generic/zfs.spec.in
+++ b/sys/contrib/openzfs/rpm/generic/zfs.spec.in
@@ -111,10 +111,10 @@ License: @ZFS_META_LICENSE@
URL: https://github.com/openzfs/zfs
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-Requires: libzpool6%{?_isa} = %{version}-%{release}
+Requires: libzpool7%{?_isa} = %{version}-%{release}
Requires: libnvpair3%{?_isa} = %{version}-%{release}
Requires: libuutil3%{?_isa} = %{version}-%{release}
-Requires: libzfs6%{?_isa} = %{version}-%{release}
+Requires: libzfs7%{?_isa} = %{version}-%{release}
Requires: %{name}-kmod = %{version}
Provides: %{name}-kmod-common = %{version}-%{release}
Obsoletes: spl <= %{version}
@@ -162,22 +162,23 @@ Requires: sysstat
%description
This package contains the core ZFS command line utilities.
-%package -n libzpool6
+%package -n libzpool7
Summary: Native ZFS pool library for Linux
Group: System Environment/Kernel
Obsoletes: libzpool2 <= %{version}
Obsoletes: libzpool4 <= %{version}
Obsoletes: libzpool5 <= %{version}
+Obsoletes: libzpool6 <= %{version}
-%description -n libzpool6
+%description -n libzpool7
This package contains the zpool library, which provides support
for managing zpools
%if %{defined ldconfig_scriptlets}
-%ldconfig_scriptlets -n libzpool6
+%ldconfig_scriptlets -n libzpool7
%else
-%post -n libzpool6 -p /sbin/ldconfig
-%postun -n libzpool6 -p /sbin/ldconfig
+%post -n libzpool7 -p /sbin/ldconfig
+%postun -n libzpool7 -p /sbin/ldconfig
%endif
%package -n libnvpair3
@@ -224,31 +225,32 @@ This library provides a variety of compatibility functions for OpenZFS:
# The library version is encoded in the package name. When updating the
# version information it is important to add an obsoletes line below for
# the previous version of the package.
-%package -n libzfs6
+%package -n libzfs7
Summary: Native ZFS filesystem library for Linux
Group: System Environment/Kernel
Obsoletes: libzfs2 <= %{version}
Obsoletes: libzfs4 <= %{version}
Obsoletes: libzfs5 <= %{version}
+Obsoletes: libzfs6 <= %{version}
-%description -n libzfs6
+%description -n libzfs7
This package provides support for managing ZFS filesystems
%if %{defined ldconfig_scriptlets}
-%ldconfig_scriptlets -n libzfs6
+%ldconfig_scriptlets -n libzfs7
%else
-%post -n libzfs6 -p /sbin/ldconfig
-%postun -n libzfs6 -p /sbin/ldconfig
+%post -n libzfs7 -p /sbin/ldconfig
+%postun -n libzfs7 -p /sbin/ldconfig
%endif
-%package -n libzfs6-devel
+%package -n libzfs7-devel
Summary: Development headers
Group: System Environment/Kernel
-Requires: libzfs6%{?_isa} = %{version}-%{release}
-Requires: libzpool6%{?_isa} = %{version}-%{release}
+Requires: libzfs7%{?_isa} = %{version}-%{release}
+Requires: libzpool7%{?_isa} = %{version}-%{release}
Requires: libnvpair3%{?_isa} = %{version}-%{release}
Requires: libuutil3%{?_isa} = %{version}-%{release}
-Provides: libzpool6-devel = %{version}-%{release}
+Provides: libzpool7-devel = %{version}-%{release}
Provides: libnvpair3-devel = %{version}-%{release}
Provides: libuutil3-devel = %{version}-%{release}
Obsoletes: zfs-devel <= %{version}
@@ -256,7 +258,7 @@ Obsoletes: libzfs2-devel <= %{version}
Obsoletes: libzfs4-devel <= %{version}
Obsoletes: libzfs5-devel <= %{version}
-%description -n libzfs6-devel
+%description -n libzfs7-devel
This package contains the header files needed for building additional
applications against the ZFS libraries.
@@ -305,7 +307,7 @@ Summary: Python %{python_version} wrapper for libzfs_core
Group: Development/Languages/Python
License: Apache-2.0
BuildArch: noarch
-Requires: libzfs6 = %{version}-%{release}
+Requires: libzfs7 = %{version}-%{release}
Requires: libnvpair3 = %{version}-%{release}
Requires: libffi
Requires: python%{__python_pkg_version}
@@ -548,7 +550,7 @@ systemctl --system daemon-reload >/dev/null || true
%config(noreplace) %{_bashcompletiondir}/zfs
%config(noreplace) %{_bashcompletiondir}/zpool
-%files -n libzpool6
+%files -n libzpool7
%{_libdir}/libzpool.so.*
%files -n libnvpair3
@@ -557,10 +559,10 @@ systemctl --system daemon-reload >/dev/null || true
%files -n libuutil3
%{_libdir}/libuutil.so.*
-%files -n libzfs6
+%files -n libzfs7
%{_libdir}/libzfs*.so.*
-%files -n libzfs6-devel
+%files -n libzfs7-devel
%{_pkgconfigdir}/libzfs.pc
%{_pkgconfigdir}/libzfsbootenv.pc
%{_pkgconfigdir}/libzfs_core.pc
diff --git a/sys/contrib/openzfs/scripts/Makefile.am b/sys/contrib/openzfs/scripts/Makefile.am
index f623526307b4..bff5f8b78a85 100644
--- a/sys/contrib/openzfs/scripts/Makefile.am
+++ b/sys/contrib/openzfs/scripts/Makefile.am
@@ -28,9 +28,7 @@ endif
dist_noinst_DATA += \
%D%/cstyle.pl \
- %D%/update_authors.pl \
- %D%/zfs2zol-patch.sed \
- %D%/zol2zfs-patch.sed
+ %D%/update_authors.pl
SHELLCHECKSCRIPTS += $(dist_scripts_SCRIPTS) $(dist_noinst_SCRIPTS)
diff --git a/sys/contrib/openzfs/scripts/zfs-tests.sh b/sys/contrib/openzfs/scripts/zfs-tests.sh
index 5a0a1a609448..09a15bafc27e 100755
--- a/sys/contrib/openzfs/scripts/zfs-tests.sh
+++ b/sys/contrib/openzfs/scripts/zfs-tests.sh
@@ -797,6 +797,10 @@ msg "${TEST_RUNNER}" \
2>&1; echo $? >"$REPORT_FILE"; } | tee "$RESULTS_FILE"
read -r RUNRESULT <"$REPORT_FILE"
+if [[ "$RUNRESULT" -eq "255" ]] ; then
+ fail "$TEST_RUNNER failed, test aborted."
+fi
+
#
# Analyze the results.
#
diff --git a/sys/contrib/openzfs/scripts/zfs2zol-patch.sed b/sys/contrib/openzfs/scripts/zfs2zol-patch.sed
deleted file mode 100755
index 2d744cd5de52..000000000000
--- a/sys/contrib/openzfs/scripts/zfs2zol-patch.sed
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sed -f
-
-s:usr/src/uts/common/fs/zfs/sys:include/sys:g
-s:usr/src/uts/common/fs/zfs:module/zfs:g
-s:usr/src/lib/libzpool:lib/libzpool:g
-s:usr/src/cmd:cmd:g
-s:usr/src/common/nvpair:module/nvpair:g
-s:usr/src/lib/libzfs/common/libzfs.h:include/libzfs.h:g
-s:usr/src/man/man1m/zfs.1m:man/man8/zfs.8:g
-s:usr/src/uts/common/sys:include/sys:g
-s:usr/src/lib/libzfs_core/common/libzfs_core.h:include/libzfs_core.h:g
-s:usr/src/lib/libzfs/common:lib/libzfs:g
-s:usr/src/lib/libzfs_core/common:lib/libzfs_core:g
-s:lib/libzpool/common/sys:include/sys:g
-s:lib/libzpool/common:lib/libzpool:g
-
-s:usr/src/test/zfs-tests/include:tests/zfs-tests/include:g
-s:usr/src/test/zfs-tests/runfiles:tests/runfiles:g
-s:usr/src/test/zfs-tests/tests/functional:tests/zfs-tests/tests/functional:g
-s:usr/src/test/zfs-tests/tests/perf:tests/zfs-tests/tests/perf:g
-s:usr/src/test/test-runner/cmd/run.py:tests/test-runner/cmd/test-runner.py:g
-s:usr/src/common/zfs/\(.*\)\.c:module/zcommon/\1.c:g
-
-# crypto framework
-s:usr/src/common/crypto:module/icp/algs:g
-s:usr/src/uts/common/crypto/io:module/icp/io:g
-
-# Headers
-s:usr/src/common/zfs/\(.*\)\.h:include/\1.h:g
-
-# Man pages
-s:usr/src/man:man:g
diff --git a/sys/contrib/openzfs/scripts/zol2zfs-patch.sed b/sys/contrib/openzfs/scripts/zol2zfs-patch.sed
deleted file mode 100755
index 0ca4b6cd6b7e..000000000000
--- a/sys/contrib/openzfs/scripts/zol2zfs-patch.sed
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sed -f
-
-s:cmd:usr/src/cmd:g
-s:include/libzfs.h:usr/src/lib/libzfs/common/libzfs.h:g
-s:include/libzfs_core.h:usr/src/lib/libzfs_core/common/libzfs_core.h:g
-s:include/sys:lib/libzpool/common/sys:g
-s:include/sys:usr/src/uts/common/fs/zfs/sys:g
-s:include/sys:usr/src/uts/common/sys:g
-s:include/zfs_fletcher.h:usr/src/common/zfs/zfs_fletcher.h:g
-s:include:usr/src/common/zfs:g
-s:lib/libzfs:usr/src/lib/libzfs/common:g
-s:lib/libzfs_core:usr/src/lib/libzfs_core/common:g
-s:lib/libzpool:lib/libzpool/common:g
-s:lib/libzpool:usr/src/lib/libzpool:g
-s:man/man7/zpool-features.7:usr/src/man/man5/zpool-features.5:g
-s:man/man8/zfs.8:usr/src/man/man1m/zfs.1m:g
-s:module/nvpair:usr/src/common/nvpair:g
-s:module/zcommon:usr/src/common/zfs/:g
-s:module/zfs:usr/src/uts/common/fs/zfs:g
-s:tests/zfs-tests:test/zfs-tests:g
diff --git a/sys/contrib/openzfs/tests/runfiles/common.run b/sys/contrib/openzfs/tests/runfiles/common.run
index 9f531411fbe1..a69c6e3c8dd7 100644
--- a/sys/contrib/openzfs/tests/runfiles/common.run
+++ b/sys/contrib/openzfs/tests/runfiles/common.run
@@ -215,7 +215,7 @@ tests = ['zfs_create_001_pos', 'zfs_create_002_pos', 'zfs_create_003_pos',
tags = ['functional', 'cli_root', 'zfs_create']
[tests/functional/cli_root/zpool_prefetch]
-tests = ['zpool_prefetch_001_pos']
+tests = ['zpool_prefetch_001_pos', 'zpool_prefetch_002_pos']
tags = ['functional', 'cli_root', 'zpool_prefetch']
[tests/functional/cli_root/zfs_destroy]
diff --git a/sys/contrib/openzfs/tests/test-runner/bin/test-runner.py.in b/sys/contrib/openzfs/tests/test-runner/bin/test-runner.py.in
index d2c1185e4a94..6688b6c4beb6 100755
--- a/sys/contrib/openzfs/tests/test-runner/bin/test-runner.py.in
+++ b/sys/contrib/openzfs/tests/test-runner/bin/test-runner.py.in
@@ -25,6 +25,7 @@ import sys
import ctypes
import re
import configparser
+import traceback
from datetime import datetime
from optparse import OptionParser
@@ -1138,7 +1139,7 @@ def filter_tests(testrun, options):
testrun.filter(failed)
-def fail(retstr, ret=1):
+def fail(retstr, ret=255):
print('%s: %s' % (sys.argv[0], retstr))
exit(ret)
@@ -1247,23 +1248,27 @@ def parse_args():
def main():
options = parse_args()
- testrun = TestRun(options)
+ try:
+ testrun = TestRun(options)
- if options.runfiles:
- testrun.read(options)
- else:
- find_tests(testrun, options)
+ if options.runfiles:
+ testrun.read(options)
+ else:
+ find_tests(testrun, options)
+
+ if options.logfile:
+ filter_tests(testrun, options)
- if options.logfile:
- filter_tests(testrun, options)
+ if options.template:
+ testrun.write(options)
+ exit(0)
- if options.template:
- testrun.write(options)
- exit(0)
+ testrun.complete_outputdirs()
+ testrun.run(options)
+ exit(testrun.summary())
- testrun.complete_outputdirs()
- testrun.run(options)
- exit(testrun.summary())
+ except Exception:
+ fail("Uncaught exception in test runner:\n" + traceback.format_exc())
if __name__ == '__main__':
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
index 678c01b58f94..23284234cdf7 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
@@ -1217,6 +1217,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/cli_root/zpool_prefetch/cleanup.ksh \
functional/cli_root/zpool_prefetch/setup.ksh \
functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh \
+ functional/cli_root/zpool_prefetch/zpool_prefetch_002_pos.ksh \
functional/cli_root/zpool_reguid/cleanup.ksh \
functional/cli_root/zpool_reguid/setup.ksh \
functional/cli_root/zpool_reguid/zpool_reguid_001_pos.ksh \
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_get/vdev_get.cfg b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_get/vdev_get.cfg
index ccb5e9c15809..6d9aa28681c7 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_get/vdev_get.cfg
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_get/vdev_get.cfg
@@ -71,6 +71,7 @@ typeset -a properties=(
checksum_t
io_n
io_t
+ slow_io_events
slow_io_n
slow_io_t
trim_support
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh
index 8ef3a66ad0d9..fd446e46e96c 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh
@@ -42,6 +42,15 @@ verify_runnable "both"
log_assert "'zpool prefetch -t ddt <pool>' can successfully load the DDT for a pool."
+DATASET=$TESTPOOL/ddt
+
+function cleanup
+{
+ datasetexists $DATASET && destroy_dataset $DATASET -f
+}
+
+log_onexit cleanup
+
function getddtstats
{
typeset -n gds=$1
@@ -75,9 +84,8 @@ log_must zpool prefetch -t ddt $TESTPOOL
# Build up the deduplicated dataset. This consists of creating enough files
# to generate a reasonable size DDT for testing purposes.
-DATASET=$TESTPOOL/ddt
log_must zfs create -o compression=off -o dedup=on $DATASET
-MNTPOINT=$(get_prop mountpoint $TESTPOOL/ddt)
+MNTPOINT=$(get_prop mountpoint $DATASET)
log_note "Generating dataset ..."
typeset -i i=0
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_002_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_002_pos.ksh
new file mode 100755
index 000000000000..f34f8c36e592
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_002_pos.ksh
@@ -0,0 +1,95 @@
+#!/bin/ksh -p
+# 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 http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025 by iXsystems, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# 'zpool prefetch -t brt <pool>' can successfully load a pool's BRT on demand.
+# 'zpool prefetch <pool>' without -t prefetches both DDT and BRT.
+#
+# STRATEGY:
+# 1. Create a dataset with block cloning enabled.
+# 2. Create files and clone them to populate the BRT.
+# 3. Export and import the pool to flush caches.
+# 4. Use zpool prefetch -t brt to load BRT.
+# 5. Test zpool prefetch without -t to prefetch all types.
+#
+
+verify_runnable "both"
+
+if ! command -v clonefile > /dev/null ; then
+ log_unsupported "clonefile program required to test block cloning"
+fi
+
+log_assert "'zpool prefetch' can successfully load BRT and prefetch all types"
+
+DATASET=$TESTPOOL/brt
+
+function cleanup
+{
+ datasetexists $DATASET && destroy_dataset $DATASET -f
+}
+
+log_onexit cleanup
+log_must zfs create $DATASET
+MNTPOINT=$(get_prop mountpoint $DATASET)
+
+log_note "Generating cloned blocks for BRT ..."
+
+# Create source file
+log_must dd if=/dev/urandom of=$MNTPOINT/source bs=1M count=100
+
+# Create clones using clonefile
+typeset -i i=0
+while (( i < 50 )); do
+ log_must clonefile -f $MNTPOINT/source $MNTPOINT/clone.$i
+ ((i += 1))
+done
+
+sync_pool $TESTPOOL
+
+# Verify BRT has entries (non-zero saved space)
+brt_saved=$(zpool get -Hp -o value bclone_saved $TESTPOOL)
+log_note "BRT saved space: $brt_saved"
+log_must test "$brt_saved" -gt "0"
+
+# Export/import to flush caches
+log_must zpool export $TESTPOOL
+log_must zpool import $TESTPOOL
+
+# Test BRT prefetch - verify command succeeds
+# Note: BRT does not expose cache statistics like DDT, so we can only
+# verify the prefetch command completes successfully
+log_must zpool prefetch -t brt $TESTPOOL
+
+# Test prefetch without -t (should prefetch all types including BRT)
+log_must zpool export $TESTPOOL
+log_must zpool import $TESTPOOL
+log_must zpool prefetch $TESTPOOL
+
+log_pass "'zpool prefetch' successfully loads BRT and all types"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_slow_io.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_slow_io.ksh
index 0c68530ee9ef..570c3b0c62b6 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_slow_io.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_slow_io.ksh
@@ -23,6 +23,7 @@
#
# Copyright (c) 2023, Klara Inc.
+# Copyright (c) 2025, Mariusz Zaborski <oshogbo@FreeBSD.org>
#
# DESCRIPTION:
@@ -140,8 +141,8 @@ function slow_io_degrade
{
do_setup
- zpool set slow_io_n=5 $TESTPOOL $VDEV
- zpool set slow_io_t=60 $TESTPOOL $VDEV
+ log_must zpool set slow_io_n=5 $TESTPOOL $VDEV
+ log_must zpool set slow_io_t=60 $TESTPOOL $VDEV
start_slow_io
for i in {1..16}; do
@@ -193,6 +194,44 @@ function slow_io_no_degrade
do_clean
}
+# Change slow_io_n, slow_io_t to 5 events in 60 seconds
+# fire more than 5 events. Disable slow io events.
+# Should not degrade.
+function slow_io_degrade_disabled
+{
+ do_setup
+
+ log_must zpool set slow_io_n=5 $TESTPOOL $VDEV
+ log_must zpool set slow_io_t=60 $TESTPOOL $VDEV
+ log_must zpool set slow_io_events=off $TESTPOOL $VDEV
+
+ start_slow_io
+ for i in {1..16}; do
+ dd if=${FILEPATH}$i of=/dev/null count=1 bs=512 2>/dev/null
+ sleep 0.5
+ done
+ stop_slow_io
+ zpool sync
+
+ #
+ # wait 60 seconds to confirm that zfs.delay was not generated.
+ #
+ typeset -i i=0
+ typeset -i events=0
+ while [[ $i -lt 60 ]]; do
+ events=$(zpool events | grep "ereport\.fs\.zfs.delay" | wc -l)
+ i=$((i+1))
+ sleep 1
+ done
+ log_note "$events delay events found"
+
+ [ $events -eq "0" ] || \
+ log_fail "expecting no delay events, found $events"
+
+ log_mustnot wait_vdev_state $TESTPOOL $VDEV "DEGRADED" 45
+ do_clean
+}
+
log_assert "Test ZED slow io configurability"
log_onexit cleanup
@@ -202,5 +241,6 @@ log_must zed_start
default_degrade
slow_io_degrade
slow_io_no_degrade
+slow_io_degrade_disabled
log_pass "Test ZED slow io configurability"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh
index 8d4340e47bf9..a8deedfb8c3c 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh
@@ -88,7 +88,7 @@ for type in "" "mirror" "raidz2" "draid"; do
fi
log_must truncate -s $((4 * MINVDEVSIZE)) $VDEVS
- log_must zpool create -f $TESTPOOL $VDEVS
+ log_must zpool create -f $TESTPOOL $type $VDEVS
log_must zpool set autotrim=on $TESTPOOL
typeset availspace=$(get_prop available $TESTPOOL)