From c3b6fd3d594f27827d69d972b41520ef0646bdea Mon Sep 17 00:00:00 2001 From: Damian Szuberski Date: Thu, 17 Nov 2022 03:27:53 +1000 Subject: [PATCH 01/45] Make autodetection disable pyzfs for kernel/srpm configurations Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Signed-off-by: szubersk Closes #13394 Closes #14178 --- config/always-pyzfs.m4 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/always-pyzfs.m4 b/config/always-pyzfs.m4 index 996a2a6e240..9b123b1b2db 100644 --- a/config/always-pyzfs.m4 +++ b/config/always-pyzfs.m4 @@ -46,6 +46,16 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [ ]) AC_SUBST(DEFINE_PYZFS) + dnl # + dnl # Autodetection disables pyzfs if kernel or srpm config + dnl # + AS_IF([test "x$enable_pyzfs" = xcheck], [ + AS_IF([test "x$ZFS_CONFIG" = xkernel -o "x$ZFS_CONFIG" = xsrpm ], [ + enable_pyzfs=no + AC_MSG_NOTICE([Disabling pyzfs for kernel/srpm config]) + ]) + ]) + dnl # dnl # Python "packaging" (or, failing that, "distlib") module is required to build and install pyzfs dnl # From a5087965fe2fbb8cae60232b9b41b7ce7464daf1 Mon Sep 17 00:00:00 2001 From: szubersk Date: Sat, 12 Nov 2022 22:22:49 +1000 Subject: [PATCH 02/45] Ubuntu 22.04 integration: ShellCheck - Add new SC2312 global exclude. ``` Consider invoking this command separately to avoid masking its return value (or use '|| true' to ignore). [SC2312] ``` - Correct errors detected by new ShellCheck version. Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Reviewed-by: George Melikov Signed-off-by: szubersk Closes #14148 --- autogen.sh | 2 +- config/Shellcheck.am | 3 +- contrib/bash_completion.d/zfs.in | 14 ++-- .../02zfsexpandknowledge/module-setup.sh.in | 18 ++--- contrib/dracut/90zfs/module-setup.sh.in | 6 +- contrib/initramfs/scripts/zfs | 4 +- scripts/common.sh.in | 20 ++--- scripts/kmodtool | 74 +++++++++---------- scripts/zimport.sh | 46 ++++++------ scripts/zloop.sh | 2 +- 10 files changed, 95 insertions(+), 94 deletions(-) diff --git a/autogen.sh b/autogen.sh index c817090183f..39eb82203d6 100755 --- a/autogen.sh +++ b/autogen.sh @@ -16,7 +16,7 @@ automake --version | awk '{print $NF; exit}' | ( dir="${dir%/Makefile.am}" grep -q '%[CD]%' "$dir/Makefile.am" || continue - reldir="${dir#$root}" + reldir="${dir#"$root"}" reldir="${reldir#/}" canon_reldir="$(printf '%s' "$reldir" | tr -C 'a-zA-Z0-9@_' '_')" diff --git a/config/Shellcheck.am b/config/Shellcheck.am index 87891957532..1cff81e04be 100644 --- a/config/Shellcheck.am +++ b/config/Shellcheck.am @@ -3,6 +3,7 @@ # ShellCheck can't follow non-constant source. Use a directive to specify location. [SC1090] # Not following: a was not specified as input (see shellcheck -x). [SC1091] # Prefer putting braces around variable references even when not strictly required. [SC2250] +# Consider invoking this command separately to avoid masking its return value (or use '|| true' to ignore). [SC2312] # In POSIX sh, 'local' is undefined. [SC2039] # older ShellCheck versions # In POSIX sh, 'local' is undefined. [SC3043] # newer ShellCheck versions @@ -17,7 +18,7 @@ PHONY += shellcheck _STGT = $(subst ^,/,$(subst shellcheck-here-,,$@)) shellcheck-here-%: if HAVE_SHELLCHECK - shellcheck --format=gcc --enable=all --exclude=SC1090,SC1091,SC2039,SC2250,SC3043 $$([ -n "$(SHELLCHECK_SHELL)" ] && echo "--shell=$(SHELLCHECK_SHELL)") "$$([ -e "$(_STGT)" ] || echo "$(srcdir)/")$(_STGT)" + shellcheck --format=gcc --enable=all --exclude=SC1090,SC1091,SC2039,SC2250,SC2312,SC3043 $$([ -n "$(SHELLCHECK_SHELL)" ] && echo "--shell=$(SHELLCHECK_SHELL)") "$$([ -e "$(_STGT)" ] || echo "$(srcdir)/")$(_STGT)" else @echo "skipping shellcheck of" $(_STGT) "because shellcheck is not installed" endif diff --git a/contrib/bash_completion.d/zfs.in b/contrib/bash_completion.d/zfs.in index 72e1092a039..c5cfd8e8efb 100644 --- a/contrib/bash_completion.d/zfs.in +++ b/contrib/bash_completion.d/zfs.in @@ -63,11 +63,11 @@ __zfs_list_filesystems() __zfs_match_snapshot() { local base_dataset="${cur%@*}" - if [ "$base_dataset" != "$cur" ] + if [[ "$base_dataset" != "$cur" ]] then $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset" else - if [ "$cur" != "" ] && __zfs_list_datasets "$cur" &> /dev/null + if [[ "$cur" != "" ]] && __zfs_list_datasets "$cur" &> /dev/null then $__ZFS_CMD list -H -o name -s name -t filesystem,volume -r "$cur" | tail -n +2 # We output the base dataset name even though we might be @@ -104,7 +104,7 @@ __zfs_match_snapshot() __zfs_match_snapshot_or_bookmark() { local base_dataset="${cur%[#@]*}" - if [ "$base_dataset" != "$cur" ] + if [[ "$base_dataset" != "$cur" ]] then if [[ $cur == *@* ]] then @@ -114,7 +114,7 @@ __zfs_match_snapshot_or_bookmark() fi else $__ZFS_CMD list -H -o name -s name -t filesystem,volume - if [ -e "$cur" ] && $__ZFS_CMD list -H -o name -s name -t filesystem,volume "$cur" &> /dev/null + if [[ -e "$cur" ]] && $__ZFS_CMD list -H -o name -s name -t filesystem,volume "$cur" &> /dev/null then echo "$cur@" echo "$cur#" @@ -126,10 +126,10 @@ __zfs_match_multiple_snapshots() { local existing_opts existing_opts="$(expr "$cur" : '\(.*\)[%,]')" - if [ -e "$existing_opts" ] + if [[ -e "$existing_opts" ]] then local base_dataset="${cur%@*}" - if [ "$base_dataset" != "$cur" ] + if [[ "$base_dataset" != "$cur" ]] then local cur="${cur##*,}" if [[ $cur =~ ^%|%.*% ]] @@ -199,7 +199,7 @@ __zfs_complete_multiple_options() mapfile -t COMPREPLY < <(compgen -W "$options" -- "${cur##*,}") existing_opts=$(expr "$cur" : '\(.*,\)') - if [ -n "$existing_opts" ] + if [[ -n "$existing_opts" ]] then COMPREPLY=( "${COMPREPLY[@]/#/${existing_opts}}" ) fi diff --git a/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in b/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in index df8df3181fc..b1f2d8f4c7b 100755 --- a/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in +++ b/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in @@ -3,7 +3,7 @@ get_devtype() { local typ typ=$(udevadm info --query=property --name="$1" | sed -n 's|^ID_FS_TYPE=||p') - if [ -z "$typ" ] ; then + if [[ -z "$typ" ]] ; then typ=$(blkid -c /dev/null "$1" -o value -s TYPE) fi echo "$typ" @@ -22,7 +22,7 @@ get_pool_devices() { else awk -F '\t' '/\t\/dev/ { print $2 }' "$poolconfigtemp" | \ while read -r pooldev ; do - if [ -e "$pooldev" ] ; then + if [[ -e "$pooldev" ]] ; then resolved="$(readlink -f "$pooldev")" dinfo "zfsexpandknowledge: pool $1 has device $pooldev (which resolves to $resolved)" echo "$resolved" @@ -38,15 +38,15 @@ find_zfs_block_devices() { local fstype local _ numfields="$(awk '{print NF; exit}' /proc/self/mountinfo)" - if [ "$numfields" = "10" ] ; then + if [[ "$numfields" = "10" ]] ; then fields="_ _ _ _ mp _ _ fstype dev _" else fields="_ _ _ _ mp _ _ _ fstype dev _" fi # shellcheck disable=SC2086 while read -r ${fields?} ; do - [ "$fstype" = "zfs" ] || continue - [ "$mp" = "$1" ] && get_pool_devices "${dev%%/*}" + [[ "$fstype" = "zfs" ]] || continue + [[ "$mp" = "$1" ]] && get_pool_devices "${dev%%/*}" done < /proc/self/mountinfo } @@ -73,7 +73,7 @@ check() { local _depdevtype # shellcheck disable=SC2154 -if [ -n "$hostonly" ]; then +if [[ -n "$hostonly" ]]; then for mp in \ "/" \ @@ -92,7 +92,7 @@ if [ -n "$hostonly" ]; then mp=$(readlink -f "$mp") mountpoint "$mp" >/dev/null 2>&1 || continue blockdevs=$(find_zfs_block_devices "$mp") - if [ -z "$blockdevs" ] ; then continue ; fi + if [[ -z "$blockdevs" ]] ; then continue ; fi dinfo "zfsexpandknowledge: block devices backing ZFS dataset $mp: ${blockdevs//$'\n'/ }" for dev in $blockdevs do @@ -100,9 +100,9 @@ if [ -n "$hostonly" ]; then fstype=$(get_devtype "$dev") host_fs_types["$dev"]="$fstype" majmin=$(get_maj_min "$dev") - if [ -d "/sys/dev/block/$majmin/slaves" ] ; then + if [[ -d "/sys/dev/block/$majmin/slaves" ]] ; then for _depdev in "/sys/dev/block/$majmin/slaves"/*; do - [ -f "$_depdev/dev" ] || continue + [[ -f "$_depdev/dev" ]] || continue _depdev="/dev/${_depdev##*/}" _depdevname=$(udevadm info --query=property --name="$_depdev" | sed -n 's|^DEVNAME=||p') _depdevtype=$(get_devtype "$_depdevname") diff --git a/contrib/dracut/90zfs/module-setup.sh.in b/contrib/dracut/90zfs/module-setup.sh.in index 528abe42957..78c74e7423b 100755 --- a/contrib/dracut/90zfs/module-setup.sh.in +++ b/contrib/dracut/90zfs/module-setup.sh.in @@ -3,7 +3,7 @@ check() { # We depend on udev-rules being loaded - [ "${1}" = "-d" ] && return 0 + [[ "${1}" = "-d" ]] && return 0 # Verify the zfs tool chain for tool in "zgenhostid" "zpool" "zfs" "mount.zfs"; do @@ -50,7 +50,7 @@ install() { fi inst_hook cmdline 95 "${moddir}/parse-zfs.sh" - if [ -n "${systemdutildir}" ]; then + if [[ -n "${systemdutildir}" ]]; then inst_script "${moddir}/zfs-generator.sh" "${systemdutildir}/system-generators/dracut-zfs-generator" fi inst_hook pre-mount 90 "${moddir}/zfs-load-key.sh" @@ -68,7 +68,7 @@ install() { # Synchronize initramfs and system hostid if ! inst_simple -H @sysconfdir@/hostid; then - if HOSTID="$(hostid 2>/dev/null)" && [ "${HOSTID}" != "00000000" ]; then + if HOSTID="$(hostid 2>/dev/null)" && [[ "${HOSTID}" != "00000000" ]]; then zgenhostid -o "${initdir}@sysconfdir@/hostid" "${HOSTID}" mark_hostonly @sysconfdir@/hostid fi diff --git a/contrib/initramfs/scripts/zfs b/contrib/initramfs/scripts/zfs index 1c8c496a7ff..587dd5eba9e 100644 --- a/contrib/initramfs/scripts/zfs +++ b/contrib/initramfs/scripts/zfs @@ -640,8 +640,8 @@ setup_snapshot_booting() # rpool/ROOT/debian/boot@snap2 => rpool/ROOT/debian_snap2/boot # rpool/ROOT/debian/usr@snap2 => rpool/ROOT/debian_snap2/usr # rpool/ROOT/debian/var@snap2 => rpool/ROOT/debian_snap2/var - subfs="${s##$rootfs}" - subfs="${subfs%%@$snapname}" + subfs="${s##"$rootfs"}" + subfs="${subfs%%@"$snapname"}" destfs="${rootfs}_${snapname}" # base fs. [ -n "$subfs" ] && destfs="${destfs}$subfs" # + sub fs. diff --git a/scripts/common.sh.in b/scripts/common.sh.in index 8268315b336..33669457f41 100644 --- a/scripts/common.sh.in +++ b/scripts/common.sh.in @@ -8,15 +8,15 @@ export ZTS_DIR= export SCRIPT_DIR= # General commands -export ZDB=${ZDB:-$SBIN_DIR/zdb} -export ZFS=${ZFS:-$SBIN_DIR/zfs} -export ZPOOL=${ZPOOL:-$SBIN_DIR/zpool} -export ZTEST=${ZTEST:-$SBIN_DIR/ztest} -export ZFS_SH=${ZFS_SH:-$SCRIPT_DIR/zfs.sh} +export ZDB="${ZDB:-$SBIN_DIR/zdb}" +export ZFS="${ZFS:-$SBIN_DIR/zfs}" +export ZPOOL="${ZPOOL:-$SBIN_DIR/zpool}" +export ZTEST="${ZTEST:-$SBIN_DIR/ztest}" +export ZFS_SH="${ZFS_SH:-$SCRIPT_DIR/zfs.sh}" # Test Suite -export RUNFILE_DIR=${RUNFILE_DIR:-$ZTS_DIR/runfiles} -export TEST_RUNNER=${TEST_RUNNER:-$ZTS_DIR/test-runner/bin/test-runner.py} -export ZTS_REPORT=${ZTS_REPORT:-$ZTS_DIR/test-runner/bin/zts-report.py} -export STF_TOOLS=${STF_TOOLS:-$ZTS_DIR/test-runner} -export STF_SUITE=${STF_SUITE:-$ZTS_DIR/zfs-tests} +export RUNFILE_DIR="${RUNFILE_DIR:-$ZTS_DIR/runfiles}" +export TEST_RUNNER="${TEST_RUNNER:-$ZTS_DIR/test-runner/bin/test-runner.py}" +export ZTS_REPORT="${ZTS_REPORT:-$ZTS_DIR/test-runner/bin/zts-report.py}" +export STF_TOOLS="${STF_TOOLS:-$ZTS_DIR/test-runner}" +export STF_SUITE="${STF_SUITE:-$ZTS_DIR/zfs-tests}" diff --git a/scripts/kmodtool b/scripts/kmodtool index a79ad0c7a0f..6eea8fe50f3 100755 --- a/scripts/kmodtool +++ b/scripts/kmodtool @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# shellcheck disable=SC2086 +# shellcheck disable=SC2086,SC2295 # kmodtool - Helper script for building kernel module RPMs # Copyright (c) 2003-2012 Ville Skyttä , @@ -125,10 +125,10 @@ EOF print_rpmtemplate_per_kmodpkg () { - if [ "${1}" = "--custom" ]; then + if [[ "${1}" = "--custom" ]]; then shift local customkernel=true - elif [ "${1}" = "--redhat" ]; then + elif [[ "${1}" = "--redhat" ]]; then # this is needed for akmods shift local redhatkernel=true @@ -139,7 +139,7 @@ print_rpmtemplate_per_kmodpkg () # Detect depmod install location local depmod_path=/sbin/depmod - if [ ! -f "${depmod_path}" ]; then + if [[ ! -f "${depmod_path}" ]]; then depmod_path=/usr/sbin/depmod fi @@ -163,24 +163,24 @@ Requires(postun): kmod EOF # second part - if [ -z "${customkernel}" ]; then + if [[ -z "${customkernel}" ]]; then cat < /dev/null || : -elif [ -f "/lib/modules/${kernel_uname_r}/System.map" ]; then +elif [[ -f "/lib/modules/${kernel_uname_r}/System.map" ]]; then ${prefix}${depmod_path} -aeF /lib/modules/${kernel_uname_r}/System.map ${kernel_uname_r} > /dev/null || : else ${prefix}${depmod_path} -ae ${kernel_uname_r} &> /dev/null || : fi %postun -n kmod-${kmodname}-${kernel_uname_r} -if [ -f "/boot/System.map-${kernel_uname_r}" ]; then +if [[ -f "/boot/System.map-${kernel_uname_r}" ]]; then ${prefix}${depmod_path} -aF /boot/System.map-${kernel_uname_r} ${kernel_uname_r} &> /dev/null || : -elif [ -f "/lib/modules/${kernel_uname_r}/System.map" ]; then +elif [[ -f "/lib/modules/${kernel_uname_r}/System.map" ]]; then ${prefix}${depmod_path} -aF /lib/modules/${kernel_uname_r}/System.map ${kernel_uname_r} &> /dev/null || : else ${prefix}${depmod_path} -a ${kernel_uname_r} &> /dev/null || : @@ -213,10 +213,10 @@ EOF print_rpmtemplate_kmoddevelpkg () { - if [ "${1}" = "--custom" ]; then + if [[ "${1}" = "--custom" ]]; then shift local customkernel=true - elif [ "${1}" = "--redhat" ]; then + elif [[ "${1}" = "--redhat" ]]; then shift local redhatkernel=true fi @@ -230,7 +230,7 @@ Group: System Environment/Kernel Provides: ${kmodname}-devel-kmod = %{?epoch:%{epoch}:}%{version}-%{release} EOF - if [ -z "${customkernel}" ] && [ -z "${redhatkernel}" ]; then + if [[ -z "${customkernel}" ]] && [[ -z "${redhatkernel}" ]]; then echo "Requires: kmod-${kmodname}-devel-${kernel_uname_r} >= %{?epoch:%{epoch}:}%{version}-%{release}" fi @@ -256,10 +256,10 @@ EOF print_rpmtemplate_per_kmoddevelpkg () { - if [ "${1}" = "--custom" ]; then + if [[ "${1}" = "--custom" ]]; then shift local customkernel=true - elif [ "${1}" = "--redhat" ]; then + elif [[ "${1}" = "--redhat" ]]; then # this is needed for akmods shift local redhatkernel=true @@ -279,7 +279,7 @@ Provides: kmod-${kmodname}-devel-uname-r = ${kernel_uname_r} EOF # second part - if [ -z "${customkernel}" ]; then + if [[ -z "${customkernel}" ]]; then cat < -- Build root (place to look for build files)" } -while [ -n "${1}" ] ; do +while [[ -n "${1}" ]] ; do case "${1}" in --filterfile) shift - if [ -z "${1}" ] ; then + if [[ -z "${1}" ]] ; then error_out 2 "Please provide path to a filter-file together with --filterfile" >&2 - elif [ ! -e "${1}" ]; then + elif [[ ! -e "${1}" ]]; then error_out 2 "Filterfile ${1} not found" >&2 fi filterfile="${1}" @@ -437,7 +437,7 @@ while [ -n "${1}" ] ; do ;; --kmodname) shift - if [ -z "${1}" ] ; then + if [[ -z "${1}" ]] ; then error_out 2 "Please provide the name of the kmod together with --kmodname" >&2 fi # strip pending -kmod @@ -450,7 +450,7 @@ while [ -n "${1}" ] ; do ;; --prefix) shift - if [ -z "${1}" ] ; then + if [[ -z "${1}" ]] ; then error_out 2 "Please provide a prefix with --prefix" >&2 fi prefix="${1}" @@ -458,7 +458,7 @@ while [ -n "${1}" ] ; do ;; --repo) shift - if [ -z "${1}" ] ; then + if [[ -z "${1}" ]] ; then error_out 2 "Please provide the name of the repo together with --repo" >&2 fi repo=${1} @@ -466,7 +466,7 @@ while [ -n "${1}" ] ; do ;; --for-kernels) shift - if [ -z "${1}" ] ; then + if [[ -z "${1}" ]] ; then error_out 2 "Please provide the name of the kmod together with --kmodname" >&2 fi for_kernels="${1}" @@ -514,28 +514,28 @@ while [ -n "${1}" ] ; do esac done -if [ -e ./kmodtool-kernel-variants ]; then +if [[ -e ./kmodtool-kernel-variants ]]; then kernels_known_variants="$(cat ./kmodtool-kernel-variants)" -elif [ -e /usr/share/kmodtool/kernel-variants ] ; then +elif [[ -e /usr/share/kmodtool/kernel-variants ]] ; then kernels_known_variants="$(cat /usr/share/kmodtool/kernel-variants)" else kernels_known_variants="@(smp?(-debug)|PAE?(-debug)|debug|kdump|xen|kirkwood|highbank|imx|omap|tegra)" fi # general sanity checks -if [ -z "${target}" ]; then +if [[ -z "${target}" ]]; then error_out 2 "please pass target arch with --target" -elif [ -z "${kmodname}" ]; then +elif [[ -z "${kmodname}" ]]; then error_out 2 "please pass kmodname with --kmodname" -elif [ -z "${kernels_known_variants}" ] ; then +elif [[ -z "${kernels_known_variants}" ]] ; then error_out 2 "could not determine known variants" fi # go -if [ -n "${for_kernels}" ]; then +if [[ -n "${for_kernels}" ]]; then # this is easy: print_customrpmtemplate "${for_kernels}" -elif [ "${build_kernels}" = "akmod" ]; then +elif [[ "${build_kernels}" = "akmod" ]]; then # do only a akmod package print_akmodtemplate print_akmodmeta @@ -543,7 +543,7 @@ else # seems we are on out own to decide for which kernels to build # we need more sanity checks in this case - if [ -z "${repo}" ]; then + if [[ -z "${repo}" ]]; then error_out 2 "please provide repo name with --repo" elif ! command -v "buildsys-build-${repo}-kerneldevpkgs" > /dev/null 2>&1; then error_out 2 "buildsys-build-${repo}-kerneldevpkgs not found" @@ -553,14 +553,14 @@ else cmdoptions="--target ${target}" # filterfile to filter list of kernels? - if [ -n "${filterfile}" ] ; then + if [[ -n "${filterfile}" ]] ; then cmdoptions="${cmdoptions} --filterfile ${filterfile}" fi kernel_versions_to_build_for=$(buildsys-build-${repo}-kerneldevpkgs "--${build_kernels}" ${cmdoptions}) || error_out 2 "buildsys-build-${repo}-kerneldevpkgs failed: ${kernel_versions_to_build_for}" - if [ "${build_kernels}" = "current" ] && [ -z "${noakmod}" ]; then + if [[ "${build_kernels}" = "current" ]] && [[ -z "${noakmod}" ]]; then print_akmodtemplate fi diff --git a/scripts/zimport.sh b/scripts/zimport.sh index 595de494e50..2549a483b14 100755 --- a/scripts/zimport.sh +++ b/scripts/zimport.sh @@ -54,7 +54,7 @@ BASE_DIR=$(dirname "$0") SCRIPT_COMMON=common.sh -if [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then +if [[ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]]; then . "${BASE_DIR}/${SCRIPT_COMMON}" else echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 @@ -188,7 +188,7 @@ populate "$SRC_DIR" 10 100 SRC_DIR="$TEST_DIR/src" SRC_DIR_ZFS="$SRC_DIR/zfs" -if [ "$COLOR" = "no" ]; then +if [[ "$COLOR" = "no" ]]; then COLOR_GREEN="" COLOR_BROWN="" COLOR_RED="" @@ -230,7 +230,7 @@ src_set_vars() { ZFS_DIR="$SRC_DIR_ZFS/$ZFS_TAG" ZFS_URL="$REPO/zfs/tarball/$ZFS_TAG" - if [ "$TAG" = "installed" ]; then + if [[ "$TAG" = "installed" ]]; then ZPOOL_CMD=$(command -v zpool) ZFS_CMD=$(command -v zfs) ZFS_SH="/usr/share/zfs/zfs.sh" @@ -273,7 +273,7 @@ pool_create() { pool_set_vars "$1" src_set_vars "$1" - if [ "$POOL_TAG" != "installed" ]; then + if [[ "$POOL_TAG" != "installed" ]]; then cd "$POOL_DIR_SRC" || fail "Failed 'cd $POOL_DIR_SRC'" fi @@ -319,7 +319,7 @@ pool_create() { # If the zfs-images directory doesn't exist fetch a copy from Github then # cache it in the $TEST_DIR and update $IMAGES_DIR. -if [ ! -d "$IMAGES_DIR" ]; then +if [[ ! -d "$IMAGES_DIR" ]]; then IMAGES_DIR="$TEST_DIR/zfs-images" mkdir -p "$IMAGES_DIR" curl -sL "$IMAGES_TAR" | \ @@ -331,7 +331,7 @@ fi # list of available images for the reserved keyword 'all'. for TAG in $POOL_TAGS; do - if [ "$TAG" = "all" ]; then + if [[ "$TAG" = "all" ]]; then ALL_TAGS=$(echo "$IMAGES_DIR"/*.tar.bz2 | \ sed "s|$IMAGES_DIR/||g;s|.tar.bz2||g") NEW_TAGS="$NEW_TAGS $ALL_TAGS" @@ -341,7 +341,7 @@ for TAG in $POOL_TAGS; do done POOL_TAGS="$NEW_TAGS" -if [ "$VERBOSE" = "yes" ]; then +if [[ "$VERBOSE" = "yes" ]]; then echo "---------------------------- Options ----------------------------" echo "VERBOSE=$VERBOSE" echo "KEEP=$KEEP" @@ -353,11 +353,11 @@ if [ "$VERBOSE" = "yes" ]; then echo fi -if [ ! -d "$TEST_DIR" ]; then +if [[ ! -d "$TEST_DIR" ]]; then mkdir -p "$TEST_DIR" fi -if [ ! -d "$SRC_DIR" ]; then +if [[ ! -d "$SRC_DIR" ]]; then mkdir -p "$SRC_DIR" fi @@ -367,9 +367,9 @@ printf "%-16s" " " for TAG in $SRC_TAGS; do src_set_vars "$TAG" - if [ "$TAG" = "installed" ]; then + if [[ "$TAG" = "installed" ]]; then ZFS_VERSION=$(modinfo zfs | awk '/version:/ { print $2; exit }') - if [ -n "$ZFS_VERSION" ]; then + if [[ -n "$ZFS_VERSION" ]]; then printf "%-16s" "$ZFS_VERSION" else fail "ZFS is not installed" @@ -388,21 +388,21 @@ printf "%-16s" "Clone ZFS" for TAG in $SRC_TAGS; do src_set_vars "$TAG" - if [ -d "$ZFS_DIR" ]; then + if [[ -d "$ZFS_DIR" ]]; then skip_nonewline - elif [ "$ZFS_TAG" = "installed" ]; then + elif [[ "$ZFS_TAG" = "installed" ]]; then skip_nonewline else cd "$SRC_DIR" || fail "Failed 'cd $SRC_DIR'" - if [ ! -d "$SRC_DIR_ZFS" ]; then + if [[ ! -d "$SRC_DIR_ZFS" ]]; then mkdir -p "$SRC_DIR_ZFS" fi git archive --format=tar --prefix="$ZFS_TAG/ $ZFS_TAG" \ -o "$SRC_DIR_ZFS/$ZFS_TAG.tar" &>/dev/null || \ rm "$SRC_DIR_ZFS/$ZFS_TAG.tar" - if [ -s "$SRC_DIR_ZFS/$ZFS_TAG.tar" ]; then + if [[ -s "$SRC_DIR_ZFS/$ZFS_TAG.tar" ]]; then tar -xf "$SRC_DIR_ZFS/$ZFS_TAG.tar" -C "$SRC_DIR_ZFS" rm "$SRC_DIR_ZFS/$ZFS_TAG.tar" echo -n -e "${COLOR_GREEN}Local${COLOR_RESET}\t\t" @@ -422,9 +422,9 @@ printf "%-16s" "Build ZFS" for TAG in $SRC_TAGS; do src_set_vars "$TAG" - if [ -f "$ZFS_DIR/module/zfs/zfs.ko" ]; then + if [[ -f "$ZFS_DIR/module/zfs/zfs.ko" ]]; then skip_nonewline - elif [ "$ZFS_TAG" = "installed" ]; then + elif [[ "$ZFS_TAG" = "installed" ]]; then skip_nonewline else cd "$ZFS_DIR" || fail "Failed 'cd $ZFS_DIR'" @@ -454,15 +454,15 @@ for TAG in $POOL_TAGS; do mkdir -p "$POOL_DIR_PRISTINE" # Use the existing compressed image if available. - if [ -f "$POOL_BZIP" ]; then + if [[ -f "$POOL_BZIP" ]]; then tar -xjf "$POOL_BZIP" -C "$POOL_DIR_PRISTINE" \ --strip-components=1 || \ fail "Failed 'tar -xjf $POOL_BZIP" # Use the installed version to create the pool. - elif [ "$TAG" = "installed" ]; then + elif [[ "$TAG" = "installed" ]]; then pool_create "$TAG" # A source build is available to create the pool. - elif [ -d "$POOL_DIR_SRC" ]; then + elif [[ -d "$POOL_DIR_SRC" ]]; then pool_create "$TAG" else SKIP=1 @@ -471,13 +471,13 @@ for TAG in $POOL_TAGS; do # Verify 'zpool import' works for all listed source versions. for SRC_TAG in $SRC_TAGS; do - if [ "$SKIP" -eq 1 ]; then + if [[ "$SKIP" -eq 1 ]]; then skip_nonewline continue fi src_set_vars "$SRC_TAG" - if [ "$SRC_TAG" != "installed" ]; then + if [[ "$SRC_TAG" != "installed" ]]; then cd "$ZFS_DIR" || fail "Failed 'cd $ZFS_DIR'" fi $ZFS_SH zfs="spa_config_path=$POOL_DIR_COPY" @@ -505,7 +505,7 @@ for TAG in $POOL_TAGS; do printf "\n" done -if [ "$KEEP" = "no" ]; then +if [[ "$KEEP" = "no" ]]; then rm -Rf "$TEST_DIR" fi diff --git a/scripts/zloop.sh b/scripts/zloop.sh index ade2c84c55b..83160c34ab9 100755 --- a/scripts/zloop.sh +++ b/scripts/zloop.sh @@ -23,7 +23,7 @@ BASE_DIR=${0%/*} SCRIPT_COMMON=common.sh -if [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then +if [[ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]]; then . "${BASE_DIR}/${SCRIPT_COMMON}" else echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 From b46be903fb45a1ff463518d8e6b92f05723427cf Mon Sep 17 00:00:00 2001 From: szubersk Date: Sat, 12 Nov 2022 22:23:30 +1000 Subject: [PATCH 03/45] Ubuntu 22.04 integration: mancheck Correct new mandoc errors. ``` STYLE: input text line longer than 80 bytes STYLE: no blank before trailing delimiter ``` Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Reviewed-by: George Melikov Signed-off-by: szubersk Closes #14148 --- man/man1/arcstat.1 | 6 ++- man/man1/test-runner.1 | 7 +-- man/man1/zhack.1 | 3 +- man/man1/ztest.1 | 11 ++-- man/man4/spl.4 | 3 +- man/man4/zfs.4 | 84 +++++++++++++++++++------------ man/man7/dracut.zfs.7 | 12 +++-- man/man7/zfsconcepts.7 | 3 +- man/man7/zfsprops.7 | 31 ++++++++---- man/man7/zpool-features.7 | 11 ++-- man/man7/zpoolconcepts.7 | 10 ++-- man/man7/zpoolprops.7 | 9 ++-- man/man8/fsck.zfs.8 | 3 +- man/man8/vdev_id.8 | 6 ++- man/man8/zdb.8 | 6 ++- man/man8/zed.8.in | 18 ++++--- man/man8/zfs-allow.8 | 2 +- man/man8/zfs-jail.8 | 3 +- man/man8/zfs-load-key.8 | 9 ++-- man/man8/zfs-mount-generator.8.in | 9 ++-- man/man8/zfs-mount.8 | 3 +- man/man8/zfs-project.8 | 3 +- man/man8/zfs-promote.8 | 3 +- man/man8/zfs-send.8 | 23 ++++++--- man/man8/zfs-userspace.8 | 3 +- man/man8/zinject.8 | 2 +- man/man8/zpool-create.8 | 3 +- man/man8/zpool-events.8 | 9 ++-- man/man8/zpool-export.8 | 3 +- man/man8/zpool-iostat.8 | 5 +- man/man8/zpool-remove.8 | 10 ++-- man/man8/zpool-resilver.8 | 3 +- man/man8/zpool-scrub.8 | 4 +- man/man8/zpool-split.8 | 3 +- man/man8/zpool-status.8 | 3 +- man/man8/zpool-upgrade.8 | 3 +- man/man8/zpool.8 | 13 +++-- 37 files changed, 217 insertions(+), 125 deletions(-) diff --git a/man/man1/arcstat.1 b/man/man1/arcstat.1 index a69cd8937bd..7c2caf69810 100644 --- a/man/man1/arcstat.1 +++ b/man/man1/arcstat.1 @@ -134,7 +134,8 @@ ARC grow disabled .It Sy need ARC reclaim needed .It Sy free -The ARC's idea of how much free memory there is, which includes evictable memory in the page cache. +The ARC's idea of how much free memory there is, which includes evictable memory +in the page cache. Since the ARC tries to keep .Sy avail above zero, @@ -142,7 +143,8 @@ above zero, is usually more instructive to observe than .Sy free . .It Sy avail -The ARC's idea of how much free memory is available to it, which is a bit less than +The ARC's idea of how much free memory is available to it, which is a bit less +than .Sy free . May temporarily be negative, in which case the ARC will reduce the target size .Sy c . diff --git a/man/man1/test-runner.1 b/man/man1/test-runner.1 index b823aaa3e1a..5bdb4d887e1 100644 --- a/man/man1/test-runner.1 +++ b/man/man1/test-runner.1 @@ -99,7 +99,8 @@ one directory. The options specified on the command line or in a .Ar runfile apply to individual tests in the group. -The exception is options pertaining to pre and post scripts, which act on all tests as a group. +The exception is options pertaining to pre and post scripts, which act on all +tests as a group. Rather than running before and after each test, these scripts are run only once each at the start and end of the test group. .Ss Test Execution @@ -254,7 +255,7 @@ Execute the post script as . .Sh EXAMPLES .Bl -tag -width "-h" -.It Sy Example 1 : No Running ad-hoc tests. +.It Sy Example 1 : No Running ad-hoc tests . This example demonstrates the simplest invocation of .Nm . .Bd -literal @@ -270,7 +271,7 @@ Running Time: 00:00:07 Percent passed: 100.0% Log directory: /var/tmp/test_results/20120923T180654 .Ed -.It Sy Example 2 : No Creating a Ar runfile No for future use. +.It Sy Example 2 : No Creating a Ar runfile No for future use . This example demonstrates creating a .Ar runfile with non-default options. diff --git a/man/man1/zhack.1 b/man/man1/zhack.1 index 42d4040d8be..26b8156b400 100644 --- a/man/man1/zhack.1 +++ b/man/man1/zhack.1 @@ -100,7 +100,8 @@ feature is now required to read the pool MOS. .Cm label repair .Ar device .Xc -Repair corrupted labels by rewriting the checksum using the presumed valid contents of the label. +Repair corrupted labels by rewriting the checksum using the presumed valid +contents of the label. .El . .Sh GLOBAL OPTIONS diff --git a/man/man1/ztest.1 b/man/man1/ztest.1 index 6b9ef9616ea..64514b31727 100644 --- a/man/man1/ztest.1 +++ b/man/man1/ztest.1 @@ -114,15 +114,15 @@ Print a help summary. Number of vdevs. .It Fl s , -vdev-size Ns = (default: Sy 64M ) Size of each vdev. -.It Fl a , -alignment-shift Ns = (default: Sy 9 ) No (use Sy 0 No for random) +.It Fl a , -alignment-shift Ns = (default: Sy 9 ) No (use Sy 0 No for random ) Alignment shift used in test. .It Fl m , -mirror-copies Ns = (default: Sy 2 ) Number of mirror copies. -.It Fl r , -raid-disks Ns = (default: Sy 4 No for raidz/ Ns Sy 16 No for draid) +.It Fl r , -raid-disks Ns = (default: Sy 4 No for raidz/ Ns Sy 16 No for draid ) Number of raidz/draid disks. .It Fl R , -raid-parity Ns = (default: Sy 1 ) Raid parity (raidz & draid). -.It Fl K , -raid-kind Ns = Ns Sy raidz Ns | Ns Sy draid Ns | Ns Sy random No (default: Sy random ) +.It Fl K , -raid-kind Ns = Ns Sy raidz Ns | Ns Sy draid Ns | Ns Sy random No (default : Sy random ) The kind of RAID config to use. With .Sy random @@ -159,7 +159,8 @@ Max loops in .It Fl B , -alt-ztest Ns = Path to alternate ("older") .Nm ztest -to drive, which will be used to initialise the pool, and, a stochastic half the time, to run the tests. +to drive, which will be used to initialise the pool, and, a stochastic half the +time, to run the tests. The parallel .Pa lib directory is prepended to @@ -168,7 +169,7 @@ i.e. given .Fl B Pa ./chroots/lenny/usr/bin/ Ns Nm , .Pa ./chroots/lenny/usr/lib will be loaded. -.It Fl C , -vdev-class-state Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Sy random No (default: Sy random ) +.It Fl C , -vdev-class-state Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Sy random No (default : Sy random ) The vdev allocation class state. .It Fl o , -option Ns = Ns Ar variable Ns = Ns Ar value Set global diff --git a/man/man4/spl.4 b/man/man4/spl.4 index 28a2583a0d5..02efaf16dc3 100644 --- a/man/man4/spl.4 +++ b/man/man4/spl.4 @@ -177,7 +177,8 @@ This is used to control how quickly taskqs ramp up the number of threads processing the queue. Because Linux thread creation and destruction are relatively inexpensive a small default value has been selected. -This means that normally threads will be created aggressively which is desirable. +This means that normally threads will be created aggressively which is +desirable. Increasing this value will result in a slower thread creation rate which may be preferable for some configurations. diff --git a/man/man4/zfs.4 b/man/man4/zfs.4 index 98539a6369e..3b3fbcabebc 100644 --- a/man/man4/zfs.4 +++ b/man/man4/zfs.4 @@ -354,7 +354,8 @@ When a vdev is added, target this number of metaslabs per top-level vdev. Default limit for metaslab size. . .It Sy zfs_vdev_max_auto_ashift Ns = Ns Sy 14 Pq uint -Maximum ashift used when optimizing for logical \[->] physical sector size on new +Maximum ashift used when optimizing for logical \[->] physical sector size on +new top-level vdevs. May be increased up to .Sy ASHIFT_MAX Po 16 Pc , @@ -397,7 +398,8 @@ Note, that both this many milliseconds and TXGs must pass before unloading will occur. . .It Sy reference_history Ns = Ns Sy 3 Pq uint -Maximum reference holders being tracked when reference_tracking_enable is active. +Maximum reference holders being tracked when reference_tracking_enable is +active. . .It Sy reference_tracking_enable Ns = Ns Sy 0 Ns | Ns 1 Pq int Track reference holders to @@ -425,7 +427,8 @@ may wish to specify a more realistic inflation factor, particularly if they operate close to quota or capacity limits. . .It Sy spa_load_print_vdev_tree Ns = Ns Sy 0 Ns | Ns 1 Pq int -Whether to print the vdev tree in the debugging message buffer during pool import. +Whether to print the vdev tree in the debugging message buffer during pool +import. . .It Sy spa_load_verify_data Ns = Ns Sy 1 Ns | Ns 0 Pq int Whether to traverse data blocks during an "extreme rewind" @@ -655,7 +658,8 @@ which indicates that a percentage based on .Sy zfs_arc_meta_limit_percent of the ARC may be used for metadata. .Pp -This value my be changed dynamically, except that must be set to an explicit value +This value my be changed dynamically, except that must be set to an explicit +value .Pq cannot be set back to Sy 0 . . .It Sy zfs_arc_meta_limit_percent Ns = Ns Sy 75 Ns % Pq u64 @@ -778,7 +782,7 @@ If nonzero, this will update with the new value. .Sy arc_p_min_shift No is used as a shift of Sy arc_c when calculating the minumum -.Sy arc_p No size. +.Sy arc_p No size . . .It Sy zfs_arc_p_dampener_disable Ns = Ns Sy 1 Ns | Ns 0 Pq int Disable @@ -851,7 +855,8 @@ milliseconds during mapping generation. Intended for use with the test suite to throttle vdev removal speed. . .It Sy zfs_condense_indirect_obsolete_pct Ns = Ns Sy 25 Ns % Pq uint -Minimum percent of obsolete bytes in vdev mapping required to attempt to condense +Minimum percent of obsolete bytes in vdev mapping required to attempt to +condense .Pq see Sy zfs_condense_indirect_vdevs_enable . Intended for use with the test suite to facilitate triggering condensing as needed. @@ -864,7 +869,8 @@ if the mapping uses more than bytes of memory and if the obsolete space map object uses more than .Sy zfs_condense_max_obsolete_bytes bytes on-disk. -The condensing process is an attempt to save memory by removing obsolete mappings. +The condensing process is an attempt to save memory by removing obsolete +mappings. . .It Sy zfs_condense_max_obsolete_bytes Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq u64 Only attempt to condense indirect vdev mappings if the on-disk size @@ -991,7 +997,8 @@ will result in objects waiting when there is not actually contention on the same object. . .It Sy zfs_slow_io_events_per_second Ns = Ns Sy 20 Ns /s Pq int -Rate limit delay and deadman zevents (which report slow I/O operations) to this many per +Rate limit delay and deadman zevents (which report slow I/O operations) to this +many per second. . .It Sy zfs_unflushed_max_mem_amt Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq u64 @@ -1059,7 +1066,8 @@ Files containing more than will be deleted asynchronously, while smaller files are deleted synchronously. Decreasing this value will reduce the time spent in an .Xr unlink 2 -system call, at the expense of a longer delay before the freed space is available. +system call, at the expense of a longer delay before the freed space is +available. This only applies on Linux. . .It Sy zfs_dirty_data_max Ns = Pq int @@ -1123,7 +1131,7 @@ Write operations are throttled when approaching the limit until log data is cleared out after transaction group sync. Because of some overhead, it should be set at least 2 times the size of .Sy zfs_dirty_data_max -.No to prevent harming normal write throughput. +.No to prevent harming normal write throughput . It also should be smaller than the size of the slog device if slog is present. .Pp Defaults to @@ -1393,7 +1401,7 @@ _ 4096 ZFS_DEBUG_LOG_SPACEMAP Verify that the log summary is consistent with the spacemap log and enable \fBzfs_dbgmsgs\fP for metaslab loading and flushing. .TE -.Sy \& * No Requires debug build. +.Sy \& * No Requires debug build . . .It Sy zfs_btree_verify_intensity Ns = Ns Sy 0 Pq uint Enables btree verification. @@ -1409,7 +1417,7 @@ lbz r l l . 4 Verify element order. (expensive) * 5 Verify unused memory is poisoned. (expensive) .TE -.Sy \& * No Requires debug build. +.Sy \& * No Requires debug build . . .It Sy zfs_free_leak_on_eio Ns = Ns Sy 0 Ns | Ns 1 Pq int If destroy encounters an @@ -1583,7 +1591,8 @@ Once all groups have reached the threshold, all groups are allowed to accept allocations. The default value of .Sy 0 -disables the feature and causes all metaslab groups to be eligible for allocations. +disables the feature and causes all metaslab groups to be eligible for +allocations. .Pp This parameter allows one to deal with pools having heavily imbalanced vdevs such as would be the case when a new vdev has been added. @@ -1602,7 +1611,8 @@ If enabled, ZFS will place user data indirect blocks into the special allocation class. . .It Sy zfs_multihost_history Ns = Ns Sy 0 Pq uint -Historical statistics for this many latest multihost updates will be available in +Historical statistics for this many latest multihost updates will be available +in .Pa /proc/spl/kstat/zfs/ Ns Ao Ar pool Ac Ns Pa /multihost . . .It Sy zfs_multihost_interval Ns = Ns Sy 1000 Ns ms Po 1 s Pc Pq u64 @@ -1701,7 +1711,7 @@ or other data crawling operations. .It Sy zfs_per_txg_dirty_frees_percent Ns = Ns Sy 30 Ns % Pq u64 Control percentage of dirtied indirect blocks from frees allowed into one TXG. After this threshold is crossed, additional frees will wait until the next TXG. -.Sy 0 No disables this throttle. +.Sy 0 No disables this throttle . . .It Sy zfs_prefetch_disable Ns = Ns Sy 0 Ns | Ns 1 Pq int Disable predictive prefetch. @@ -1818,7 +1828,8 @@ A higher number indicates that we care more about how filled in a segment is, while a lower number indicates we care more about the size of the extent without considering the gaps within a segment. This value is only tunable upon module insertion. -Changing the value afterwards will have no effect on scrub or resilver performance. +Changing the value afterwards will have no effect on scrub or resilver +performance. . .It Sy zfs_scan_issue_strategy Ns = Ns Sy 0 Pq uint Determines the order that data will be verified while scrubbing or resilvering: @@ -1834,7 +1845,7 @@ By deferring scrubbing of small segments, we may later find adjacent data to coalesce and increase the segment size. .It Sy 0 .No Use strategy Sy 1 No during normal verification -.No and strategy Sy 2 No while taking a checkpoint. +.No and strategy Sy 2 No while taking a checkpoint . .El . .It Sy zfs_scan_legacy Ns = Ns Sy 0 Ns | Ns 1 Pq int @@ -1861,7 +1872,8 @@ This is done until we get below the soft limit. The fraction of the hard limit used to determined the soft limit for I/O sorting by the sequential scan algorithm. When we cross this limit from below no action is taken. -When we cross this limit from above it is because we are issuing verification I/O. +When we cross this limit from above it is because we are issuing verification +I/O. In this case (unless the metadata scan is done) we stop issuing verification I/O and start scanning metadata again until we get to the hard limit. . @@ -1960,7 +1972,8 @@ vdev while discarding the checkpoint. . .It Sy zfs_special_class_metadata_reserve_pct Ns = Ns Sy 25 Ns % Pq uint Only allow small data blocks to be allocated on the special and dedup vdev -types when the available free space percentage on these vdevs exceeds this value. +types when the available free space percentage on these vdevs exceeds this +value. This ensures reserved space is available for pool metadata as the special vdevs approach capacity. . @@ -1982,7 +1995,8 @@ because these will not be compressed. The .Em 128 KiB allocations are especially detrimental to performance -on highly fragmented systems, which may have very few free segments of this size, +on highly fragmented systems, which may have very few free segments of this +size, and may need to load new metaslabs to satisfy these allocations. . .It Sy zfs_sync_pass_rewrite Ns = Ns Sy 2 Pq uint @@ -1997,7 +2011,8 @@ will create a maximum of one thread per CPU. . .It Sy zfs_trim_extent_bytes_max Ns = Ns Sy 134217728 Ns B Po 128 MiB Pc Pq uint Maximum size of TRIM command. -Larger ranges will be split into chunks no larger than this value before issuing. +Larger ranges will be split into chunks no larger than this value before +issuing. . .It Sy zfs_trim_extent_bytes_min Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq uint Minimum size of TRIM commands. @@ -2008,7 +2023,8 @@ to negatively impact overall performance. . .It Sy zfs_trim_metaslab_skip Ns = Ns Sy 0 Ns | Ns 1 Pq uint Skip uninitialized metaslabs during the TRIM process. -This option is useful for pools constructed from large thinly-provisioned devices +This option is useful for pools constructed from large thinly-provisioned +devices where TRIM operations are slow. As a pool ages, an increasing fraction of the pool's metaslabs will be initialized, progressively degrading the usefulness of this option. @@ -2028,7 +2044,8 @@ more efficient TRIM operations and the delay before the recently trimmed space is available for use by the device. .Pp Increasing this value will allow frees to be aggregated for a longer time. -This will result is larger TRIM operations and potentially increased memory usage. +This will result is larger TRIM operations and potentially increased memory +usage. Decreasing this value will have the opposite effect. The default of .Sy 32 @@ -2039,7 +2056,8 @@ Historical statistics for this many latest TXGs will be available in .Pa /proc/spl/kstat/zfs/ Ns Ao Ar pool Ac Ns Pa /TXGs . . .It Sy zfs_txg_timeout Ns = Ns Sy 5 Ns s Pq uint -Flush dirty data to disk at least every this many seconds (maximum TXG duration). +Flush dirty data to disk at least every this many seconds (maximum TXG +duration). . .It Sy zfs_vdev_aggregate_trim Ns = Ns Sy 0 Ns | Ns 1 Pq uint Allow TRIM I/O operations to be aggregated. @@ -2094,7 +2112,8 @@ when I/O operations do not immediately follow one another. . .It Sy zfs_vdev_mirror_non_rotating_seek_inc Ns = Ns Sy 1 Pq int A number by which the balancing algorithm increments the load calculation for -the purpose of selecting the least busy mirror member when an I/O operation lacks +the purpose of selecting the least busy mirror member when an I/O operation +lacks locality as defined by the .Sy zfs_vdev_mirror_rotating_seek_offset . Operations within this that are not immediately following the previous operation @@ -2208,7 +2227,8 @@ the ZIL to log synchronous writes. However, if there are fewer than .Sy zfs_embedded_slog_min_ms metaslabs in the vdev, this functionality is disabled. -This ensures that we don't set aside an unreasonable amount of space for the ZIL. +This ensures that we don't set aside an unreasonable amount of space for the +ZIL. . .It Sy zstd_earlyabort_pass Ns = Ns Sy 1 Pq uint Whether heuristic for detection of incompressible data with zstd levels >= 3 @@ -2435,7 +2455,8 @@ the scheduler looks for classes whose maximum has not been satisfied. Iteration through the I/O classes is done in the order specified above. No further operations are issued if the aggregate maximum number of concurrent operations has been hit, -or if there are no operations queued for an I/O class that has not hit its maximum. +or if there are no operations queued for an I/O class that has not hit its +maximum. Every time an I/O operation is queued or an operation completes, the scheduler looks for new operations to issue. .Pp @@ -2466,10 +2487,10 @@ the I/O scheduler changes the maximum number of active async write operations according to the amount of dirty data in the pool. Since both throughput and latency typically increase with the number of concurrent operations issued to physical devices, reducing the -burstiness in the number of concurrent operations also stabilizes the -response time of operations from other – and in particular synchronous – queues. +burstiness in the number of simultaneous operations also stabilizes the +response time of operations from other queues, in particular synchronous ones. In broad strokes, the I/O scheduler will issue more concurrent operations -from the async write queue as there's more dirty data in the pool. +from the async write queue as there is more dirty data in the pool. . .Ss Async Writes The number of concurrent operations issued for the async write I/O class @@ -2534,7 +2555,8 @@ so that we only start to delay after writing at full speed has failed to keep up with the incoming write rate. The scale of the curve is defined by .Sy zfs_delay_scale . -Roughly speaking, this variable determines the amount of delay at the midpoint of the curve. +Roughly speaking, this variable determines the amount of delay at the midpoint +of the curve. .Bd -literal delay 10ms +-------------------------------------------------------------*+ diff --git a/man/man7/dracut.zfs.7 b/man/man7/dracut.zfs.7 index 0f446fe2fe3..2db2f6639ea 100644 --- a/man/man7/dracut.zfs.7 +++ b/man/man7/dracut.zfs.7 @@ -71,7 +71,8 @@ module. .Pp Booting into a ZFS dataset requires .Sy mountpoint Ns = Ns Pa / -to be set on the dataset containing the root filesystem (henceforth "the boot dataset") and at the very least either the +to be set on the dataset containing the root filesystem (henceforth "the boot +dataset") and at the very least either the .Sy bootfs property to be set to that dataset, or the .Sy root= @@ -86,7 +87,8 @@ matching globs are deemed essential and will be mounted as well. .Pp .Xr zfs-mount-generator 8 -is recommended for proper functioning of the system afterward (correct mount properties, remounting, &c.). +is recommended for proper functioning of the system afterward (correct mount +properties, remounting, &c.). . .Sh CMDLINE .Ss Standard @@ -122,7 +124,8 @@ cf.\& .Sx Temporary Mount Point Properties in .Xr zfsprops 7 . -These properties will not last, since all filesystems will be re-mounted from the real root. +These properties will not last, since all filesystems will be re-mounted from +the real root. . .It Sy debug If specified, @@ -263,7 +266,8 @@ Does nothing on .Nm systemd systems .Pq if Pa dracut-zfs-generator No succeeded . -Otherwise, loads encryption key for the boot dataset from the console or via plymouth. +Otherwise, loads encryption key for the boot dataset from the console or via +plymouth. It may not work at all! .El . diff --git a/man/man7/zfsconcepts.7 b/man/man7/zfsconcepts.7 index 31c8b53e7fa..18a9e9b5caf 100644 --- a/man/man7/zfsconcepts.7 +++ b/man/man7/zfsconcepts.7 @@ -81,7 +81,8 @@ Bookmarks can be created extremely quickly, compared to snapshots, and they consume no additional space within the pool. Bookmarks can also have arbitrary names, much like snapshots. .Pp -Unlike snapshots, bookmarks can not be accessed through the filesystem in any way. +Unlike snapshots, bookmarks can not be accessed through the filesystem in any +way. From a storage standpoint a bookmark just provides a way to reference when a snapshot was created as a distinct object. Bookmarks are initially tied to a snapshot, not the filesystem or volume, diff --git a/man/man7/zfsprops.7 b/man/man7/zfsprops.7 index 0b7711da88a..1f6ffb59e32 100644 --- a/man/man7/zfsprops.7 +++ b/man/man7/zfsprops.7 @@ -192,7 +192,8 @@ and .It Sy guid The 64 bit GUID of this dataset or bookmark which does not change over its entire lifetime. -When a snapshot is sent to another pool, the received snapshot has the same GUID. +When a snapshot is sent to another pool, the received snapshot has the same +GUID. Thus, the .Sy guid is suitable to identify a snapshot across pools. @@ -259,7 +260,8 @@ this opaque token can be provided to to resume and complete the .Nm zfs Cm receive . .It Sy redact_snaps -For bookmarks, this is the list of snapshot guids the bookmark contains a redaction +For bookmarks, this is the list of snapshot guids the bookmark contains a +redaction list for. For snapshots, this is the list of snapshot guids the snapshot is redacted with respect to. @@ -798,7 +800,8 @@ Controls the compression algorithm used for this dataset. .Pp When set to .Sy on -(the default), indicates that the current default compression algorithm should be used. +(the default), indicates that the current default compression algorithm should +be used. The default balances compression and decompression speed, with compression ratio and is expected to work well on a wide variety of workloads. Unlike all other settings for this property, @@ -861,7 +864,8 @@ is equivalent to .Pp The .Sy zstd -compression algorithm provides both high compression ratios and good performance. +compression algorithm provides both high compression ratios and good +performance. You can specify the .Sy zstd level by using the value @@ -916,7 +920,8 @@ after compression, otherwise the compression will not be considered worthwhile and the block saved uncompressed. Note that when the logical block is less than 8 times the disk sector size this effectively reduces the necessary compression -ratio; for example, 8 KiB blocks on disks with 4 KiB disk sectors must compress to 1/2 +ratio; for example, 8 KiB blocks on disks with 4 KiB disk sectors must compress +to 1/2 or less of their original size. .It Xo .Sy context Ns = Ns Sy none Ns | Ns @@ -1040,7 +1045,7 @@ file system. The default value is .Sy legacy . Setting this property to a value other than -.Sy legacy No requires the Sy large_dnode No pool feature to be enabled. +.Sy legacy No requires the Sy large_dnode No pool feature to be enabled . .Pp Consider setting .Sy dnodesize @@ -1063,7 +1068,7 @@ if you need to receive a send stream of this dataset on a pool that doesn't enable the .Sy large_dnode feature, or if you need to import this pool on a system that doesn't support the -.Sy large_dnode No feature. +.Sy large_dnode No feature . .Pp This property can also be referred to by its shortened column name, .Sy dnsize . @@ -1132,14 +1137,16 @@ is selected ZFS will ask for the key at the command prompt when it is required to access the encrypted data (see .Nm zfs Cm load-key for details). -This setting will also allow the key to be passed in via the standard input stream, +This setting will also allow the key to be passed in via the standard input +stream, but users should be careful not to place keys which should be kept secret on the command line. If a file URI is selected, the key will be loaded from the specified absolute file path. If an HTTPS or HTTP URL is selected, it will be GETted using .Xr fetch 3 , -libcurl, or nothing, depending on compile-time configuration and run-time availability. +libcurl, or nothing, depending on compile-time configuration and run-time +availability. The .Sy SSL_CA_CERT_FILE environment variable can be set to set the location @@ -1499,7 +1506,8 @@ future releases. When set to .Sy some , ZFS stores an extra copy of only critical metadata. -This can improve file create performance since less metadata needs to be written. +This can improve file create performance since less metadata +needs to be written. If a single on-disk block is corrupt, at worst a single user file can be lost. .Pp When set to @@ -1642,7 +1650,8 @@ LDAP- or .Xr smbpasswd 5 Ns -based ) by default. This means that any additional access control -(disallow specific user specific access etc) must be done on the underlying file system. +(disallow specific user specific access etc) must be done on the underlying file +system. .It Sy sharenfs Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Ar opts Controls whether the file system is shared via NFS, and what options are to be used. diff --git a/man/man7/zpool-features.7 b/man/man7/zpool-features.7 index 0ff1a9a52a1..3ff3d97ba70 100644 --- a/man/man7/zpool-features.7 +++ b/man/man7/zpool-features.7 @@ -62,7 +62,8 @@ Refer to the documentation for the ZFS implementation that created the pool for information about those features. .Pp Each supported feature also has a short name. -By convention a feature's short name is the portion of its GUID which follows the +By convention a feature's short name is the portion of its GUID which follows +the .Sq \&: .Po i.e. @@ -167,7 +168,8 @@ separated by whitespace and/or commas. Only features present in all files are enabled. .Pp Simple sanity checks are applied to the files: -they must be between 1 B and 16 KiB in size, and must end with a newline character. +they must be between 1 B and 16 KiB in size, and must end with a newline +character. .Pp The requested features are applied when a pool is created using .Nm zpool Cm create Fl o Sy compatibility Ns = Ns Ar … @@ -268,7 +270,7 @@ or when a new file is created under that filesystem. \ The upgrade can also be triggered on filesystems via \ Nm zfs Cm set Sy version Ns = Ns Sy current Ar fs . \ No The upgrade process runs in the background and may take a while to complete \ -for filesystems containing large amounts of files. +for filesystems containing large amounts of files . . .de checksum-spiel When the @@ -339,7 +341,8 @@ while is non-zero. . .feature org.openzfs blake3 no extensible_dataset -This feature enables the use of the BLAKE3 hash algorithm for checksum and dedup. +This feature enables the use of the BLAKE3 hash algorithm for checksum and +dedup. BLAKE3 is a secure hash algorithm focused on high performance. .Pp .checksum-spiel blake3 diff --git a/man/man7/zpoolconcepts.7 b/man/man7/zpoolconcepts.7 index c181ea3b889..4ef96b15756 100644 --- a/man/man7/zpoolconcepts.7 +++ b/man/man7/zpoolconcepts.7 @@ -91,7 +91,7 @@ vdev type is an alias for .Pp A raidz group with .Em N No disks of size Em X No with Em P No parity disks can hold approximately -.Em (N-P)*X No bytes and can withstand Em P No devices failing without losing data. +.Em (N-P)*X No bytes and can withstand Em P No devices failing without losing data . The minimum number of devices in a raidz group is one more than the number of parity disks. The recommended number is between 3 and 9 to help increase performance. @@ -99,7 +99,7 @@ The recommended number is between 3 and 9 to help increase performance. A variant of raidz that provides integrated distributed hot spares which allows for faster resilvering while retaining the benefits of raidz. A dRAID vdev is constructed from multiple internal raidz groups, each with -.Em D No data devices and Em P No parity devices. +.Em D No data devices and Em P No parity devices . These groups are distributed over all of the children in order to fully utilize the available disk performance. .Pp @@ -119,7 +119,7 @@ recommended to also add a mirrored vdev to store those blocks. .Pp In regards to I/O, performance is similar to raidz since for any read all -.Em D No data disks must be accessed. +.Em D No data disks must be accessed . Delivered random IOPS can be reasonably approximated as .Sy floor((N-S)/(D+P))*single_drive_IOPS . .Pp @@ -136,7 +136,7 @@ vdev type is an alias for .Sy draid1 . .Pp A dRAID with -.Em N No disks of size Em X , D No data disks per redundancy group, Em P +.Em N No disks of size Em X , D No data disks per redundancy group , Em P .No parity level, and Em S No distributed hot spares can hold approximately .Em (N-S)*(D/(D+P))*X No bytes and can withstand Em P devices failing without losing data. @@ -151,7 +151,7 @@ The parity level (1-3). .It Ar data The number of data devices per redundancy group. In general, a smaller value of -.Em D No will increase IOPS, improve the compression ratio, +.Em D No will increase IOPS, improve the compression ratio , and speed up resilvering at the expense of total usable capacity. Defaults to .Em 8 , No unless Em N-P-S No is less than Em 8 . diff --git a/man/man7/zpoolprops.7 b/man/man7/zpoolprops.7 index 2164c126011..7be0a21d980 100644 --- a/man/man7/zpoolprops.7 +++ b/man/man7/zpoolprops.7 @@ -82,11 +82,13 @@ By contrast, the property describes how much new data can be written to ZFS filesystems/volumes. The zpool .Sy free -property is not generally useful for this purpose, and can be substantially more than the zfs +property is not generally useful for this purpose, and can be substantially more +than the zfs .Sy available space. This discrepancy is due to several factors, including raidz parity; -zfs reservation, quota, refreservation, and refquota properties; and space set aside by +zfs reservation, quota, refreservation, and refquota properties; and space set +aside by .Sy spa_slop_shift (see .Xr zfs 4 @@ -272,7 +274,8 @@ using the command. .It Sy bootfs Ns = Ns Sy (unset) Ns | Ns Ar pool Ns Op / Ns Ar dataset Identifies the default bootable dataset for the root pool. -This property is expected to be set mainly by the installation and upgrade programs. +This property is expected to be set mainly by the installation and upgrade +programs. Not all Linux distribution boot processes use the bootfs property. .It Sy cachefile Ns = Ns Ar path Ns | Ns Sy none Controls the location of where the pool configuration is cached. diff --git a/man/man8/fsck.zfs.8 b/man/man8/fsck.zfs.8 index a3506798b38..57d41f61d29 100644 --- a/man/man8/fsck.zfs.8 +++ b/man/man8/fsck.zfs.8 @@ -34,7 +34,8 @@ . .Sh DESCRIPTION .Nm -is a thin shell wrapper that at most checks the status of a dataset's container pool. +is a thin shell wrapper that at most checks the status of a dataset's container +pool. It is installed by OpenZFS because some Linux distributions expect a fsck helper for all filesystems. .Pp diff --git a/man/man8/vdev_id.8 b/man/man8/vdev_id.8 index 2b327b3192a..96f8d9c0854 100644 --- a/man/man8/vdev_id.8 +++ b/man/man8/vdev_id.8 @@ -30,8 +30,10 @@ is an udev helper which parses to map a physical path in a storage topology to a channel name. The channel name is combined with a disk enclosure slot number to create an alias that reflects the physical location of the drive. -This is particularly helpful when it comes to tasks like replacing failed drives. -Slot numbers may also be remapped in case the default numbering is unsatisfactory. +This is particularly helpful when it comes to tasks like replacing failed +drives. +Slot numbers may also be remapped in case the default numbering is +unsatisfactory. The drive aliases will be created as symbolic links in .Pa /dev/disk/by-vdev . .Pp diff --git a/man/man8/zdb.8 b/man/man8/zdb.8 index 31ee601538c..db99ff65df7 100644 --- a/man/man8/zdb.8 +++ b/man/man8/zdb.8 @@ -174,7 +174,8 @@ negates the effect of the flag that follows it and has no effect unless preceded by the .Ar A flag. -For example, the range 0:-1:A-d will dump all object types except for directories. +For example, the range 0:-1:A-d will dump all object types except for +directories. .Pp .Bl -tag -compact -width Ds .It Sy A @@ -274,7 +275,8 @@ the percentage of free space in each space map. .It Fl mmmm Display every spacemap record. .It Fl M , -metaslab-groups -Display all "normal" vdev metaslab group information - per-vdev metaslab count, fragmentation, +Display all "normal" vdev metaslab group information - per-vdev metaslab count, +fragmentation, and free space histogram, as well as overall pool fragmentation and histogram. .It Fl MM "Special" vdevs are added to -M's normal output. diff --git a/man/man8/zed.8.in b/man/man8/zed.8.in index 00f23edec37..1bbca05e385 100644 --- a/man/man8/zed.8.in +++ b/man/man8/zed.8.in @@ -61,8 +61,10 @@ Lock all current and future pages in the virtual memory address space. This may help the daemon remain responsive when the system is under heavy memory pressure. .It Fl I -Request that the daemon idle rather than exit when the kernel modules are not loaded. -Processing of events will start, or resume, when the kernel modules are (re)loaded. +Request that the daemon idle rather than exit when the kernel modules are not +loaded. +Processing of events will start, or resume, when the kernel modules are +(re)loaded. Under Linux the kernel modules cannot be unloaded while the daemon is running. .It Fl Z Zero the daemon's state, thereby allowing zevents still within the kernel @@ -75,12 +77,14 @@ Write the daemon's process ID to the specified file. Custom .Ev $PATH for zedlets to use. -Normally zedlets run in a locked-down environment, with hardcoded paths to the ZFS commands +Normally zedlets run in a locked-down environment, with hardcoded paths to the +ZFS commands .Pq Ev $ZFS , $ZPOOL , $ZED , … , and a hard-coded .Ev $PATH . This is done for security reasons. -However, the ZFS test suite uses a custom PATH for its ZFS commands, and passes it to +However, the ZFS test suite uses a custom PATH for its ZFS commands, and passes +it to .Nm with .Fl P . @@ -111,7 +115,8 @@ Defaults to .El .Sh ZEVENTS A zevent is comprised of a list of nvpairs (name/value pairs). -Each zevent contains an EID (Event IDentifier) that uniquely identifies it throughout +Each zevent contains an EID (Event IDentifier) that uniquely identifies it +throughout the lifetime of the loaded ZFS kernel module; this EID is a monotonically increasing integer that resets to 1 each time the kernel module is loaded. Each zevent also contains a class string that identifies the type of event. @@ -217,7 +222,8 @@ The ZFS release the daemon is part of. .El .Pp ZEDLETs may need to call other ZFS commands. -The installation paths of the following executables are defined as environment variables: +The installation paths of the following executables are defined as environment +variables: .Sy ZDB , .Sy ZED , .Sy ZFS , diff --git a/man/man8/zfs-allow.8 b/man/man8/zfs-allow.8 index c88cf9f0092..d26984317c2 100644 --- a/man/man8/zfs-allow.8 +++ b/man/man8/zfs-allow.8 @@ -411,7 +411,7 @@ mount point permission is set to 755 by default, user will be unable to mount file systems under .Ar tank/cindys . Add an ACE similar to the following syntax to provide mount point access: -.Dl # Cm chmod No A+user: Ns Ar cindys Ns :add_subdirectory:allow Ar /tank/cindys +.Dl # Cm chmod No A+user : Ns Ar cindys Ns :add_subdirectory:allow Ar /tank/cindys . .Ss Example 2 : No Delegating Create Time Permissions on a ZFS Dataset The following example shows how to grant anyone in the group diff --git a/man/man8/zfs-jail.8 b/man/man8/zfs-jail.8 index 72e83f7fe3e..53a1ccef774 100644 --- a/man/man8/zfs-jail.8 +++ b/man/man8/zfs-jail.8 @@ -97,7 +97,8 @@ property cannot be changed from within a jail. 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. +since the jail administrator might have set the mount point to an unacceptable +value. .Pp See .Xr jail 8 diff --git a/man/man8/zfs-load-key.8 b/man/man8/zfs-load-key.8 index 98682c95a0a..f68d6e985a7 100644 --- a/man/man8/zfs-load-key.8 +++ b/man/man8/zfs-load-key.8 @@ -236,7 +236,8 @@ Key rotation is managed by ZFS. Changing the user's key (e.g. a passphrase) does not require re-encrypting the entire dataset. Datasets can be scrubbed, -resilvered, renamed, and deleted without the encryption keys being loaded (see the +resilvered, renamed, and deleted without the encryption keys being loaded (see +the .Cm load-key subcommand for more info on key loading). .Pp @@ -291,9 +292,11 @@ Encrypted datasets may not have since the implementation stores some encryption metadata where the third copy would normally be. Since compression is applied before encryption, datasets may -be vulnerable to a CRIME-like attack if applications accessing the data allow for it. +be vulnerable to a CRIME-like attack if applications accessing the data allow +for it. Deduplication with encryption will leak information about which blocks -are equivalent in a dataset and will incur an extra CPU cost for each block written. +are equivalent in a dataset and will incur an extra CPU cost for each block +written. . .Sh SEE ALSO .Xr zfsprops 7 , diff --git a/man/man8/zfs-mount-generator.8.in b/man/man8/zfs-mount-generator.8.in index ae8937038e6..be60ea68f96 100644 --- a/man/man8/zfs-mount-generator.8.in +++ b/man/man8/zfs-mount-generator.8.in @@ -49,7 +49,7 @@ units for configured ZFS datasets. .No Skipped if Sy off . .No Skipped if only Sy noauto datasets exist for a given mountpoint and there's more than one. -.No Datasets with Sy yes No take precedence over ones with Sy noauto No for the same mountpoint. +.No Datasets with Sy yes No take precedence over ones with Sy noauto No for the same mountpoint . .No Sets logical Em noauto No flag if Sy noauto . Encryption roots always generate .Sy zfs-load-key@ Ns Ar root Ns Sy .service , @@ -94,14 +94,15 @@ as the mount unit. .No Sets Sy After Ns = for the mount unit. . .It Sy org.openzfs.systemd:wanted-by Ns = Ns Pa unit Ns Oo " " Ns Pa unit Oc Ns … -.No Sets logical Em noauto No flag (see below). +.No Sets logical Em noauto No flag (see below) . .No If not Sy none , No sets Sy WantedBy Ns = for the mount unit. .It Sy org.openzfs.systemd:required-by Ns = Ns Pa unit Ns Oo " " Ns Pa unit Oc Ns … -.No Sets logical Em noauto No flag (see below). +.No Sets logical Em noauto No flag (see below) . .No If not Sy none , No sets Sy RequiredBy Ns = for the mount unit. . .It Sy org.openzfs.systemd:nofail Ns = Ns (unset) Ns | Ns Sy on Ns | Ns Sy off -Waxes or wanes strength of default reverse dependencies of the mount unit, see below. +Waxes or wanes strength of default reverse dependencies of the mount unit, see +below. . .It Sy org.openzfs.systemd:ignore Ns = Ns Sy on Ns | Ns Sy off .No Skip if Sy on . diff --git a/man/man8/zfs-mount.8 b/man/man8/zfs-mount.8 index 873190eb862..35aa187cf06 100644 --- a/man/man8/zfs-mount.8 +++ b/man/man8/zfs-mount.8 @@ -104,7 +104,8 @@ this will cause the terminal to interactively block after asking for the key. .It Fl v Report mount progress. .It Fl f -Attempt to force mounting of all filesystems, even those that couldn't normally be mounted (e.g. redacted datasets). +Attempt to force mounting of all filesystems, even those that couldn't normally +be mounted (e.g. redacted datasets). .El .It Xo .Nm zfs diff --git a/man/man8/zfs-project.8 b/man/man8/zfs-project.8 index 1c3abc76c4a..12f50312403 100644 --- a/man/man8/zfs-project.8 +++ b/man/man8/zfs-project.8 @@ -99,7 +99,8 @@ Clear subdirectories' flags recursively. .Ar file Ns | Ns Ar directory Ns … .Xc Check project ID and inherit flag on the files and directories: -report entries without the project inherit flag, or with project IDs different from the +report entries without the project inherit flag, or with project IDs different +from the target directory's project ID or the one specified with .Fl p . .Bl -tag -width "-p id" diff --git a/man/man8/zfs-promote.8 b/man/man8/zfs-promote.8 index 1c14c3a0bc9..cdb04d05de1 100644 --- a/man/man8/zfs-promote.8 +++ b/man/man8/zfs-promote.8 @@ -44,7 +44,8 @@ .Sh DESCRIPTION The .Nm zfs Cm promote -command makes it possible to destroy the dataset that the clone was created from. +command makes it possible to destroy the dataset that the clone was created +from. The clone parent-child dependency relationship is reversed, so that the origin dataset becomes a clone of the specified dataset. .Pp diff --git a/man/man8/zfs-send.8 b/man/man8/zfs-send.8 index b033e15a1d8..83f4e81da7b 100644 --- a/man/man8/zfs-send.8 +++ b/man/man8/zfs-send.8 @@ -215,7 +215,8 @@ compress on the receiver, unless you specify .Fl o Sy compress Ns = Em off . .It Fl w , -raw For encrypted datasets, send data exactly as it exists on disk. -This allows backups to be taken even if encryption keys are not currently loaded. +This allows backups to be taken even if encryption keys are not currently +loaded. The backup may then be received on an untrusted machine since that machine will not have the encryption keys to read the protected data or alter it without being detected. @@ -286,7 +287,8 @@ when using this flag. Allows sending a replication stream even when there are snapshots missing in the hierarchy. When a snapshot is missing, instead of throwing an error and aborting the send, -a warning is printed to the standard error stream and the dataset to which it belongs +a warning is printed to the standard error stream and the dataset to which it +belongs and its descendents are skipped. This flag can only be used in conjunction with .Fl R . @@ -354,7 +356,8 @@ then the data will be decompressed before sending so it can be split into smaller block sizes. .It Fl w , -raw For encrypted datasets, send data exactly as it exists on disk. -This allows backups to be taken even if encryption keys are not currently loaded. +This allows backups to be taken even if encryption keys are not currently +loaded. The backup may then be received on an untrusted machine since that machine will not have the encryption keys to read the protected data or alter it without being detected. @@ -386,7 +389,8 @@ If the .Sy lz4_compress feature is active on the sending system, then the receiving system must have that feature enabled as well. -Datasets that are sent with this flag may not be received as an encrypted dataset, +Datasets that are sent with this flag may not be received as an encrypted +dataset, since encrypted datasets cannot use the .Sy embedded_data feature. @@ -445,7 +449,7 @@ included in the redaction list contained in the bookmark specified by the flag. The resulting send stream is said to be redacted with respect to the snapshots the bookmark specified by the -.Fl -redact No flag was created with. +.Fl -redact No flag was created with . The bookmark must have been created by running .Nm zfs Cm redact on the snapshot being sent. @@ -629,7 +633,8 @@ snapshots themselves. In order to make the purpose of the feature more clear, an example is provided. Consider a zfs filesystem containing four files. These files represent information for an online shopping service. -One file contains a list of usernames and passwords, another contains purchase histories, +One file contains a list of usernames and passwords, another contains purchase +histories, a third contains click tracking data, and a fourth contains user preferences. The owner of this data wants to make it available for their development teams to test against, and their market research teams to do analysis on. @@ -641,7 +646,8 @@ However, because all of this data is stored in one ZFS filesystem, it must all be sent and received together. In addition, the owner of the data wants to take advantage of features like compression, checksumming, and -snapshots, so they do want to continue to use ZFS to store and transmit their data. +snapshots, so they do want to continue to use ZFS to store and transmit their +data. Redaction can help them do so. First, they would make two clones of a snapshot of the data on the source. In one clone, they create the setup they want their market research team to see; @@ -654,7 +660,8 @@ They would then create a redaction bookmark on the parent snapshot, using snapshots on the two clones as redaction snapshots. The parent can then be sent, redacted, to the target server where the research and development teams have access. -Finally, incremental sends from the parent snapshot to each of the clones can be sent +Finally, incremental sends from the parent snapshot to each of the clones can be +sent to and received on the target server; these snapshots are identical to the ones on the source, and are ready to be used, while the parent snapshot on the target contains none of the username and password data present on the source, diff --git a/man/man8/zfs-userspace.8 b/man/man8/zfs-userspace.8 index bc6b607e291..4bd7bb7cbef 100644 --- a/man/man8/zfs-userspace.8 +++ b/man/man8/zfs-userspace.8 @@ -73,7 +73,8 @@ .Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns … Oc .Ar filesystem Ns | Ns Ar snapshot Ns | Ns Ar path .Xc -Displays space consumed by, and quotas on, each user in the specified filesystem, +Displays space consumed by, and quotas on, each user in the specified +filesystem, snapshot, or path. If a path is given, the filesystem that contains that path will be used. This corresponds to the diff --git a/man/man8/zinject.8 b/man/man8/zinject.8 index f69dc6890ff..4f0bbae8121 100644 --- a/man/man8/zinject.8 +++ b/man/man8/zinject.8 @@ -188,7 +188,7 @@ Each number is in hexadecimal, and only one block can be specified. .It Fl C Ar dvas Inject the given error only into specific DVAs. The mask should be specified as a list of 0-indexed DVAs separated by commas -.No (e.g. Ar 0,2 Ns No ). +.No (e.g . Ar 0,2 Ns No ). This option is not applicable to logical data errors such as .Sy decompress and diff --git a/man/man8/zpool-create.8 b/man/man8/zpool-create.8 index 76e5476ea04..da1a79c72c2 100644 --- a/man/man8/zpool-create.8 +++ b/man/man8/zpool-create.8 @@ -87,7 +87,8 @@ currently in use by another subsystem. However this check is not robust enough to detect simultaneous attempts to use a new device in different pools, even if .Sy multihost Ns = Sy enabled . -The administrator must ensure, that simultaneous invocations of any combination of +The administrator must ensure, that simultaneous invocations of any combination +of .Nm zpool Cm replace , .Nm zpool Cm create , .Nm zpool Cm add , diff --git a/man/man8/zpool-events.8 b/man/man8/zpool-events.8 index 80fb21878f9..1b79149b52e 100644 --- a/man/man8/zpool-events.8 +++ b/man/man8/zpool-events.8 @@ -108,7 +108,8 @@ Issued when a pool is exported. .It Sy zpool.import Issued when a pool is imported. .It Sy zpool.reguid -Issued when a REGUID (new unique identifier for the pool have been regenerated) have been detected. +Issued when a REGUID (new unique identifier for the pool have been regenerated) +have been detected. .It Sy vdev.unknown Issued when the vdev is unknown. Such as trying to clear device errors on a vdev that have failed/been kicked @@ -226,7 +227,8 @@ ID of vdev (if any). .It Sy vdev_fru Physical FRU location. .It Sy vdev_state -State of vdev (0=uninitialized, 1=closed, 2=offline, 3=removed, 4=failed to open, 5=faulted, 6=degraded, 7=healthy). +State of vdev (0=uninitialized, 1=closed, 2=offline, 3=removed, 4=failed to +open, 5=faulted, 6=degraded, 7=healthy). .It Sy vdev_ashift The ashift value of the vdev. .It Sy vdev_complete_ts @@ -373,7 +375,8 @@ If this field exists, it is an array of counters. Each entry counts bit clears in a particular bit of a big-endian uint64 type. The first entry counts bits clears of the high-order bit of the first byte, the 9th byte, etc, and the -last entry counts clears of the low-order bit of the 8th byte, the 16th byte, etc. +last entry counts clears of the low-order bit of the 8th byte, the 16th byte, +etc. This information is useful for observing a stuck bit in a parallel data path, such as IDE or parallel SCSI. .El diff --git a/man/man8/zpool-export.8 b/man/man8/zpool-export.8 index 3b0edcef552..4fed98cfe27 100644 --- a/man/man8/zpool-export.8 +++ b/man/man8/zpool-export.8 @@ -61,7 +61,8 @@ the disks. .It Fl a Exports all pools imported on the system. .It Fl f -Forcefully unmount all datasets, and allow export of pools with active shared spares. +Forcefully unmount all datasets, and allow export of pools with active shared +spares. .Pp This command will forcefully export the pool even if it has a shared spare that is currently being used. diff --git a/man/man8/zpool-iostat.8 b/man/man8/zpool-iostat.8 index 76fdee7d09c..34f7243d5aa 100644 --- a/man/man8/zpool-iostat.8 +++ b/man/man8/zpool-iostat.8 @@ -66,7 +66,8 @@ If is specified, the command exits after .Ar count reports are printed. -The first report printed is always the statistics since boot regardless of whether +The first report printed is always the statistics since boot regardless of +whether .Ar interval and .Ar count @@ -117,7 +118,7 @@ If is passed without a script name, it prints a list of all scripts. .Fl c also sets verbose mode -.No \&( Ns Fl v Ns No \&). +.No \&( Ns Fl v Ns No \&) . .Pp Script output should be in the form of "name=value". The column name is set to "name" and the value is set to "value". diff --git a/man/man8/zpool-remove.8 b/man/man8/zpool-remove.8 index 1b5ae72f8da..b5cc6e4fc57 100644 --- a/man/man8/zpool-remove.8 +++ b/man/man8/zpool-remove.8 @@ -75,9 +75,11 @@ The feature flag must be enabled to remove a top-level vdev, see .Xr zpool-features 7 . .Pp -A mirrored top-level device (log or data) can be removed by specifying the top-level mirror for the +A mirrored top-level device (log or data) can be removed by specifying the top- +level mirror for the same. -Non-log devices or data devices that are part of a mirrored configuration can be removed using +Non-log devices or data devices that are part of a mirrored configuration can be +removed using the .Nm zpool Cm detach command. @@ -137,11 +139,11 @@ config: .Ed .Pp The command to remove the mirrored log -.Ar mirror-2 No is: +.Ar mirror-2 No is : .Dl # Nm zpool Cm remove Ar tank mirror-2 .Pp The command to remove the mirrored data -.Ar mirror-1 No is: +.Ar mirror-1 No is : .Dl # Nm zpool Cm remove Ar tank mirror-1 . .Sh SEE ALSO diff --git a/man/man8/zpool-resilver.8 b/man/man8/zpool-resilver.8 index 92fdaccafce..420f9bcb560 100644 --- a/man/man8/zpool-resilver.8 +++ b/man/man8/zpool-resilver.8 @@ -40,7 +40,8 @@ . .Sh DESCRIPTION Starts a resilver of the specified pools. -If an existing resilver is already running it will be restarted from the beginning. +If an existing resilver is already running it will be restarted from the +beginning. Any drives that were scheduled for a deferred resilver will be added to the new one. This requires the diff --git a/man/man8/zpool-scrub.8 b/man/man8/zpool-scrub.8 index f5b9ccd2e51..1fdbb8a5d56 100644 --- a/man/man8/zpool-scrub.8 +++ b/man/man8/zpool-scrub.8 @@ -97,7 +97,9 @@ again. Wait until scrub has completed before returning. .El .Sh EXAMPLES -.Ss Example 1 : No Status of pool with ongoing scrub: +.Ss Example 1 +Status of pool with ongoing scrub: +.sp .Bd -literal -compact .No # Nm zpool Cm status ... diff --git a/man/man8/zpool-split.8 b/man/man8/zpool-split.8 index eb98f48741f..6bbe4924852 100644 --- a/man/man8/zpool-split.8 +++ b/man/man8/zpool-split.8 @@ -81,7 +81,8 @@ datasets it attempts to mount as it is bringing the new pool online. Note that if any datasets have .Sy keylocation Ns = Ns Sy prompt , this command will block waiting for the keys to be entered. -Without this flag, encrypted datasets will be left unavailable until the keys are loaded. +Without this flag, encrypted datasets will be left unavailable until the keys +are loaded. .It Fl n Do a dry-run .Pq Qq No-op diff --git a/man/man8/zpool-status.8 b/man/man8/zpool-status.8 index 2c882a9a928..ed572e29f51 100644 --- a/man/man8/zpool-status.8 +++ b/man/man8/zpool-status.8 @@ -98,7 +98,8 @@ This is the number of I/O operations that didn't complete in .Sy zio_slow_io_ms milliseconds .Pq Sy 30000 No by default . -This does not necessarily mean the I/O operations failed to complete, just took an +This does not necessarily mean the I/O operations failed to complete, just took +an unreasonably long amount of time. This may indicate a problem with the underlying storage. .It Fl t diff --git a/man/man8/zpool-upgrade.8 b/man/man8/zpool-upgrade.8 index a2421f5846b..1c87630b5e6 100644 --- a/man/man8/zpool-upgrade.8 +++ b/man/man8/zpool-upgrade.8 @@ -92,7 +92,8 @@ for details on compatibility with systems that support feature flags, but do not support all features enabled on the pool. .Bl -tag -width Ds .It Fl a -Enables all supported features (from specified compatibility sets, if any) on all +Enables all supported features (from specified compatibility sets, if any) on +all pools. .It Fl V Ar version Upgrade to the specified legacy version. diff --git a/man/man8/zpool.8 b/man/man8/zpool.8 index a837db38f95..48e4eb3c557 100644 --- a/man/man8/zpool.8 +++ b/man/man8/zpool.8 @@ -121,7 +121,8 @@ or removes the specified device from the pool. .It Xr zpool-replace 8 Replaces an existing device (which may be faulted) with a new one. .It Xr zpool-split 8 -Creates a new pool by splitting all mirrors in an existing pool (which decreases its redundancy). +Creates a new pool by splitting all mirrors in an existing pool (which decreases +its redundancy). .El . .Ss Properties @@ -174,7 +175,8 @@ Checkpoints the current state of which can be later restored by .Nm zpool Cm import Fl -rewind-to-checkpoint . .It Xr zpool-trim 8 -Initiates an immediate on-demand TRIM operation for all of the free space in a pool. +Initiates an immediate on-demand TRIM operation for all of the free space in a +pool. This operation informs the underlying storage devices of all blocks in the pool which are no longer allocated and allows thinly provisioned devices to reclaim the space. @@ -201,7 +203,8 @@ pool. Takes the specified physical device offline or brings it online. .It Xr zpool-resilver 8 Starts a resilver. -If an existing resilver is already running it will be restarted from the beginning. +If an existing resilver is already running it will be restarted from the +beginning. .It Xr zpool-reopen 8 Reopen all the vdevs associated with the pool. .It Xr zpool-clear 8 @@ -384,11 +387,11 @@ config: .Ed .Pp The command to remove the mirrored log -.Ar mirror-2 No is: +.Ar mirror-2 No is : .Dl # Nm zpool Cm remove Ar tank mirror-2 .Pp The command to remove the mirrored data -.Ar mirror-1 No is: +.Ar mirror-1 No is : .Dl # Nm zpool Cm remove Ar tank mirror-1 . .Ss Example 15 : No Displaying expanded space on a device From 28ea4f9b088fd7fb33593f09d37bae44ea85e4fb Mon Sep 17 00:00:00 2001 From: szubersk Date: Sat, 12 Nov 2022 22:29:29 +1000 Subject: [PATCH 04/45] Ubuntu 22.04 integration: Cppcheck Suppress a false positive found by new Cppcheck version. Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Reviewed-by: George Melikov Signed-off-by: szubersk Closes #14148 --- lib/libshare/nfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libshare/nfs.c b/lib/libshare/nfs.c index 3251913cba6..118ad7ef220 100644 --- a/lib/libshare/nfs.c +++ b/lib/libshare/nfs.c @@ -91,6 +91,7 @@ nfs_init_tmpfile(const char *prefix, const char *mdir, struct tmpfile *tmpf) mkdir(mdir, 0755) < 0 && errno != EEXIST) { fprintf(stderr, "failed to create %s: %s\n", + // cppcheck-suppress uninitvar mdir, strerror(errno)); return (B_FALSE); } From 32ef14de0f3609c35d2478dd52950e9ad65b8c6d Mon Sep 17 00:00:00 2001 From: szubersk Date: Sat, 12 Nov 2022 22:30:57 +1000 Subject: [PATCH 05/45] Ubuntu 22.04 integration: ZTS Add `detect_odr_violation=1` to ASAN_OPTIONS to allow both libzfs and libzpool expose ``` zfeature_info_t spa_feature_table[SPA_FEATURES] ``` from module/zcommon/zfeature_common.c in public ABI. Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Reviewed-by: George Melikov Signed-off-by: szubersk Closes #14148 --- tests/zfs-tests/include/default.cfg.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/zfs-tests/include/default.cfg.in b/tests/zfs-tests/include/default.cfg.in index 56111a1473c..3aed8ebea03 100644 --- a/tests/zfs-tests/include/default.cfg.in +++ b/tests/zfs-tests/include/default.cfg.in @@ -156,7 +156,7 @@ done export MAX_PARTITIONS=8 if [ "@ASAN_ENABLED@" = "yes" ]; then - export ASAN_OPTIONS=abort_on_error=true:halt_on_error=true:allocator_may_return_null=true:disable_coredump=false:detect_stack_use_after_return=true + export ASAN_OPTIONS=abort_on_error=true:halt_on_error=true:allocator_may_return_null=true:disable_coredump=false:detect_stack_use_after_return=true:detect_odr_violation=1 # TODO # disable memory leaks detection From 9e7fc5da3806b971304d13d513ea1504c7fe98f6 Mon Sep 17 00:00:00 2001 From: szubersk Date: Sat, 12 Nov 2022 22:48:32 +1000 Subject: [PATCH 06/45] Ubuntu 22.04 integration: GitHub workflows - GitHub workflows are run on Ubuntu 22.04 - Extract the `checkstyle` workflow dependencies to a separate file. - Refresh the `build-dependencies.txt` list. Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Reviewed-by: George Melikov Signed-off-by: szubersk Closes #14148 --- .github/workflows/build-dependencies.txt | 6 ++++-- .github/workflows/checkstyle-dependencies.txt | 5 +++++ .github/workflows/checkstyle.yaml | 5 +++-- .github/workflows/zfs-tests-functional.yml | 8 ++++++-- .github/workflows/zfs-tests-sanity.yml | 5 +++-- .github/workflows/zloop.yml | 5 +++-- 6 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/checkstyle-dependencies.txt diff --git a/.github/workflows/build-dependencies.txt b/.github/workflows/build-dependencies.txt index e591399001f..482d82fff17 100644 --- a/.github/workflows/build-dependencies.txt +++ b/.github/workflows/build-dependencies.txt @@ -23,10 +23,11 @@ libelf-dev libffi-dev libmount-dev libpam0g-dev -libselinux-dev +libselinux1-dev libssl-dev libtool libudev-dev +linux-headers-generic lsscsi mdadm nfs-kernel-server @@ -36,8 +37,9 @@ python3 python3-cffi python3-dev python3-packaging +python3-pip python3-setuptools -rng-tools +rng-tools-debian rsync samba sysstat diff --git a/.github/workflows/checkstyle-dependencies.txt b/.github/workflows/checkstyle-dependencies.txt new file mode 100644 index 00000000000..879d3dbc555 --- /dev/null +++ b/.github/workflows/checkstyle-dependencies.txt @@ -0,0 +1,5 @@ +cppcheck +devscripts +mandoc +pax-utils +shellcheck diff --git a/.github/workflows/checkstyle.yaml b/.github/workflows/checkstyle.yaml index 2e593e0a566..008adcc03e0 100644 --- a/.github/workflows/checkstyle.yaml +++ b/.github/workflows/checkstyle.yaml @@ -6,7 +6,7 @@ on: jobs: checkstyle: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 with: @@ -14,8 +14,9 @@ jobs: - name: Install dependencies run: | sudo apt-get update + sudo apt-get -qq upgrade sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq - sudo apt-get install -qq mandoc cppcheck pax-utils devscripts + sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/checkstyle-dependencies.txt apt-get install -qq sudo python3 -m pip install --quiet flake8 sudo apt-get clean diff --git a/.github/workflows/zfs-tests-functional.yml b/.github/workflows/zfs-tests-functional.yml index 1c2b2b80406..236bf599f68 100644 --- a/.github/workflows/zfs-tests-functional.yml +++ b/.github/workflows/zfs-tests-functional.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - os: [18.04, 20.04] + os: [18.04, 20.04, 22.04] runs-on: ubuntu-${{ matrix.os }} steps: - uses: actions/checkout@v3 @@ -21,7 +21,11 @@ jobs: - name: Install dependencies run: | sudo apt-get update - xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt sudo apt-get install -qq + sudo apt-get -qq upgrade + if [ "${{ matrix.os }}" = "18.04" ]; then + sed -i.bak 's/rng-tools-debian/rng-tools/' ${{ github.workspace }}/.github/workflows/build-dependencies.txt + fi + sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq sudo apt-get clean - name: Autogen.sh run: | diff --git a/.github/workflows/zfs-tests-sanity.yml b/.github/workflows/zfs-tests-sanity.yml index ace046ad1c1..f3fc607cb4f 100644 --- a/.github/workflows/zfs-tests-sanity.yml +++ b/.github/workflows/zfs-tests-sanity.yml @@ -6,7 +6,7 @@ on: jobs: tests: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 with: @@ -17,7 +17,8 @@ jobs: - name: Install dependencies run: | sudo apt-get update - xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt sudo apt-get install -qq + sudo apt-get -qq upgrade + sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq sudo apt-get clean - name: Autogen.sh run: | diff --git a/.github/workflows/zloop.yml b/.github/workflows/zloop.yml index 807a1bc4612..1a234ac9940 100644 --- a/.github/workflows/zloop.yml +++ b/.github/workflows/zloop.yml @@ -6,7 +6,7 @@ on: jobs: tests: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: TEST_DIR: /var/tmp/zloop steps: @@ -16,7 +16,8 @@ jobs: - name: Install dependencies run: | sudo apt-get update - xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt sudo apt-get install -qq + sudo apt-get -qq upgrade + sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq sudo apt-get clean - name: Autogen.sh run: | From 31247c78b15aefeac5d395109209ca8a99ff5d60 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Thu, 3 Nov 2022 13:58:38 -0400 Subject: [PATCH 07/45] FreeBSD: get_zfs_ioctl_version() should be cast to (void) FreeBSD's Coverity scans complain that we ignore the return value. There is no need to check the return value so we cast it to (void) to suppress further complaints by static analyzers. Reported-by: Coverity (CID 1018175) Reviewed-by: Brian Behlendorf Reviewed-by: szubersk Reviewed-by: Alexander Motin Signed-off-by: Richard Yao Closes #14136 --- lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c b/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c index 72f8f393039..76778b36521 100644 --- a/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c +++ b/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c @@ -38,7 +38,7 @@ get_zfs_ioctl_version(void) int ver = ZFS_IOCVER_NONE; ver_size = sizeof (ver); - sysctlbyname("vfs.zfs.version.ioctl", &ver, &ver_size, NULL, 0); + (void) sysctlbyname("vfs.zfs.version.ioctl", &ver, &ver_size, NULL, 0); return (ver); } From 0a0166c9755a423906c097a29702d4962c73cf77 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Thu, 3 Nov 2022 13:53:17 -0400 Subject: [PATCH 08/45] FreeBSD: do_mount() passes wrong string length to helper It should pass `MNT_LINE_MAX`, but passes `sizeof (mntpt)`. This is harmless because the strlen is not actually used by the helper, but FreeBSD's Coverity scans complained about it. This was missed in my audit of various string functions since it is not actually passed to a string function. Upon review, it was noticed that the helper function does not need to be a separate function, so I have inlined it as cleanup. Reported-by: Coverity (CID 1432079) Reviewed-by: Brian Behlendorf Reviewed-by: szubersk Reviewed-by: Alexander Motin Signed-off-by: Richard Yao Closes #14136 --- lib/libzfs/os/freebsd/libzfs_zmount.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/lib/libzfs/os/freebsd/libzfs_zmount.c b/lib/libzfs/os/freebsd/libzfs_zmount.c index 6a26cae1e09..34976f7bbf4 100644 --- a/lib/libzfs/os/freebsd/libzfs_zmount.c +++ b/lib/libzfs/os/freebsd/libzfs_zmount.c @@ -73,33 +73,30 @@ build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, *iovlen = ++i; } -static int -do_mount_(const char *spec, const char *dir, int mflag, - char *dataptr, int datalen, const char *optptr, int optlen) +int +do_mount(zfs_handle_t *zhp, const char *mntpt, const char *opts, int flags) { struct iovec *iov; char *optstr, *p, *tofree; int iovlen, rv; + const char *spec = zfs_get_name(zhp); assert(spec != NULL); - assert(dir != NULL); - assert(dataptr == NULL), (void) dataptr; - assert(datalen == 0), (void) datalen; - assert(optptr != NULL); - assert(optlen > 0), (void) optlen; + assert(mntpt != NULL); + assert(opts != NULL); - tofree = optstr = strdup(optptr); + tofree = optstr = strdup(opts); assert(optstr != NULL); iov = NULL; iovlen = 0; if (strstr(optstr, MNTOPT_REMOUNT) != NULL) build_iovec(&iov, &iovlen, "update", NULL, 0); - if (mflag & MS_RDONLY) + if (flags & MS_RDONLY) build_iovec(&iov, &iovlen, "ro", NULL, 0); build_iovec(&iov, &iovlen, "fstype", __DECONST(char *, MNTTYPE_ZFS), (size_t)-1); - build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, dir), + build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, mntpt), (size_t)-1); build_iovec(&iov, &iovlen, "from", __DECONST(char *, spec), (size_t)-1); while ((p = strsep(&optstr, ",/")) != NULL) @@ -109,14 +106,7 @@ do_mount_(const char *spec, const char *dir, int mflag, if (rv < 0) return (errno); return (rv); -} -int -do_mount(zfs_handle_t *zhp, const char *mntpt, const char *opts, int flags) -{ - - return (do_mount_(zfs_get_name(zhp), mntpt, flags, NULL, 0, - opts, sizeof (mntpt))); } int From 99c0479a4ef4cbfdf49ad05a4457d0872ab98f4c Mon Sep 17 00:00:00 2001 From: Laura Hild Date: Fri, 18 Nov 2022 14:36:19 -0500 Subject: [PATCH 09/45] Correct multipathd.target to .service https://github.com/openzfs/zfs/pull/9863 says it "orders zfs-import-cache.service and zfs-import-scan.service after multipathd.service" but the commit (79add96) actually ordered them after .target. Reviewed-by: Brian Behlendorf Signed-off-by: Laura Hild Closes #12709 Closes #14171 --- etc/systemd/system/zfs-import-cache.service.in | 2 +- etc/systemd/system/zfs-import-scan.service.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/systemd/system/zfs-import-cache.service.in b/etc/systemd/system/zfs-import-cache.service.in index 08c11698bcc..fd822989da9 100644 --- a/etc/systemd/system/zfs-import-cache.service.in +++ b/etc/systemd/system/zfs-import-cache.service.in @@ -5,7 +5,7 @@ DefaultDependencies=no Requires=systemd-udev-settle.service After=systemd-udev-settle.service After=cryptsetup.target -After=multipathd.target +After=multipathd.service After=systemd-remount-fs.service Before=zfs-import.target ConditionFileNotEmpty=@sysconfdir@/zfs/zpool.cache diff --git a/etc/systemd/system/zfs-import-scan.service.in b/etc/systemd/system/zfs-import-scan.service.in index c37f70f13b7..c5dd45d87e6 100644 --- a/etc/systemd/system/zfs-import-scan.service.in +++ b/etc/systemd/system/zfs-import-scan.service.in @@ -5,7 +5,7 @@ DefaultDependencies=no Requires=systemd-udev-settle.service After=systemd-udev-settle.service After=cryptsetup.target -After=multipathd.target +After=multipathd.service Before=zfs-import.target ConditionFileNotEmpty=!@sysconfdir@/zfs/zpool.cache ConditionPathIsDirectory=/sys/module/zfs From 3226e0dc8ef6f7770035c42b28f2b088bbdd2944 Mon Sep 17 00:00:00 2001 From: George Amanakis Date: Fri, 18 Nov 2022 20:38:37 +0100 Subject: [PATCH 10/45] Fix setting the large_block feature after receiving a snapshot We are not allowed to dirty a filesystem when done receiving a snapshot. In this case the flag SPA_FEATURE_LARGE_BLOCKS will not be set on that filesystem since the filesystem is not on dp_dirty_datasets, and a subsequent encrypted raw send will fail. Fix this by checking in dsl_dataset_snapshot_sync_impl() if the feature needs to be activated and do so if appropriate. Reviewed-by: Brian Behlendorf Signed-off-by: George Amanakis Closes #13699 Closes #13782 --- module/zfs/dsl_dataset.c | 15 ++++ tests/runfiles/common.run | 2 +- tests/zfs-tests/tests/Makefile.am | 1 + .../rsend/send_raw_large_blocks.ksh | 78 +++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100755 tests/zfs-tests/tests/functional/rsend/send_raw_large_blocks.ksh diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index c7577fc584a..4da4effca60 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -1760,6 +1760,21 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname, } } + /* + * We are not allowed to dirty a filesystem when done receiving + * a snapshot. In this case the flag SPA_FEATURE_LARGE_BLOCKS will + * not be set and a subsequent encrypted raw send will fail. Hence + * activate this feature if needed here. + */ + for (spa_feature_t f = 0; f < SPA_FEATURES; f++) { + if (zfeature_active(f, ds->ds_feature_activation[f]) && + !(zfeature_active(f, ds->ds_feature[f]))) { + dsl_dataset_activate_feature(dsobj, f, + ds->ds_feature_activation[f], tx); + ds->ds_feature[f] = ds->ds_feature_activation[f]; + } + } + ASSERT3U(ds->ds_prev != 0, ==, dsl_dataset_phys(ds)->ds_prev_snap_obj != 0); if (ds->ds_prev) { diff --git a/tests/runfiles/common.run b/tests/runfiles/common.run index 73ca6999314..1b42786e9d5 100644 --- a/tests/runfiles/common.run +++ b/tests/runfiles/common.run @@ -847,7 +847,7 @@ tests = ['recv_dedup', 'recv_dedup_encrypted_zvol', 'rsend_001_pos', 'send_realloc_encrypted_files', 'send_spill_block', 'send_holds', 'send_hole_birth', 'send_mixed_raw', 'send-wR_encrypted_zvol', 'send_partial_dataset', 'send_invalid', 'send_doall', - 'send_raw_spill_block', 'send_raw_ashift'] + 'send_raw_spill_block', 'send_raw_ashift', 'send_raw_large_blocks'] tags = ['functional', 'rsend'] [tests/functional/scrub_mirror] diff --git a/tests/zfs-tests/tests/Makefile.am b/tests/zfs-tests/tests/Makefile.am index 39eb44f7317..c7aa4c7b89f 100644 --- a/tests/zfs-tests/tests/Makefile.am +++ b/tests/zfs-tests/tests/Makefile.am @@ -1812,6 +1812,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \ functional/rsend/send_partial_dataset.ksh \ functional/rsend/send_raw_ashift.ksh \ functional/rsend/send_raw_spill_block.ksh \ + functional/rsend/send_raw_large_blocks.ksh \ functional/rsend/send_realloc_dnode_size.ksh \ functional/rsend/send_realloc_encrypted_files.ksh \ functional/rsend/send_realloc_files.ksh \ diff --git a/tests/zfs-tests/tests/functional/rsend/send_raw_large_blocks.ksh b/tests/zfs-tests/tests/functional/rsend/send_raw_large_blocks.ksh new file mode 100755 index 00000000000..39e93a7df3c --- /dev/null +++ b/tests/zfs-tests/tests/functional/rsend/send_raw_large_blocks.ksh @@ -0,0 +1,78 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2022, George Amanakis. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/rsend/rsend.kshlib + +# +# Description: +# Receiving a snapshot with large blocks and raw sending it succeeds. +# +# Strategy: +# 1) Create a set of files each containing some file data in an +# encrypted filesystem with recordsize=1m. +# 2) Snapshot and send with large_blocks enabled to a new filesystem. +# 3) Raw send to a file. If the large_blocks feature is not activated +# in the filesystem created in (2) the raw send will fail. +# + +verify_runnable "both" + +log_assert "Receiving and raw sending a snapshot with large blocks succeeds" + +backup=$TEST_BASE_DIR/backup +raw_backup=$TEST_BASE_DIR/raw_backup + +function cleanup +{ + log_must rm -f $backup $raw_backup $ibackup $unc_backup + destroy_pool pool_lb/fs + log_must rm -f $TESTDIR/vdev_a +} + +log_onexit cleanup + +typeset passphrase="password" +typeset file="/pool_lb/fs/$TESTFILE0" + +# Create pool +truncate -s $MINVDEVSIZE $TESTDIR/vdev_a +log_must zpool create -f -o feature@large_blocks=enabled pool_lb $TESTDIR/vdev_a + +log_must eval "echo $passphrase > /pool_lb/pwd" + +log_must zfs create -o recordsize=1m pool_lb/fs +log_must dd if=/dev/urandom of=$file bs=1024 count=1024 +log_must zfs snapshot pool_lb/fs@snap1 + +log_must eval "zfs send -L pool_lb/fs@snap1 > $backup" +log_must eval "zfs recv -o encryption=aes-256-ccm -o keyformat=passphrase \ + -o keylocation=file:///pool_lb/pwd -o primarycache=none \ + -o recordsize=1m pool_lb/testfs5 < $backup" + +log_must eval "zfs send --raw pool_lb/testfs5@snap1 > $raw_backup" + +log_pass "Receiving and raw sending a snapshot with large blocks succeeds" From 3a74f488fcd9b3802efa366adcb813415d3f13a8 Mon Sep 17 00:00:00 2001 From: Ameer Hamza <106930537+ixhamza@users.noreply.github.com> Date: Sat, 19 Nov 2022 00:39:59 +0500 Subject: [PATCH 11/45] zed: post a udev change event from spa_vdev_attach() In order for zed to process the removal event correctly, udev change event needs to be posted to sync the blkid information. spa_create() and spa_config_update() posts the event already through spa_write_cachefile(). Doing the same for spa_vdev_attach() that handles the case for vdev attachment and replacement. Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Reviewed-by: Alexander Motin Reviewed-by: Ryan Moeller Signed-off-by: Ameer Hamza Closes #14172 --- module/zfs/spa_misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c index ca55d55405d..822fd0ee89b 100644 --- a/module/zfs/spa_misc.c +++ b/module/zfs/spa_misc.c @@ -1290,7 +1290,7 @@ spa_vdev_config_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error, * If the config changed, update the config cache. */ if (config_changed) - spa_write_cachefile(spa, B_FALSE, B_TRUE, B_FALSE); + spa_write_cachefile(spa, B_FALSE, B_TRUE, B_TRUE); } /* From b0657a59abb38659721bf8d973920292c4f4a1a8 Mon Sep 17 00:00:00 2001 From: John Wren Kennedy Date: Fri, 18 Nov 2022 12:43:18 -0700 Subject: [PATCH 12/45] ZTS: zts-report silently ignores perf test results The regex used to extract test result information from a test run only matches the functional tests. Update the regex so it matches both. Reviewed-by: Richard Yao Reviewed-by: George Melikov Reviewed-by: Tony Nguyen Signed-off-by: John Wren Kennedy Closes #14185 --- tests/test-runner/bin/zts-report.py.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-runner/bin/zts-report.py.in b/tests/test-runner/bin/zts-report.py.in index 66b041b6e2a..e5b1ae0f65e 100755 --- a/tests/test-runner/bin/zts-report.py.in +++ b/tests/test-runner/bin/zts-report.py.in @@ -325,7 +325,7 @@ def process_results(pathname): print('Error opening file:', e) sys.exit(1) - prefix = '/zfs-tests/tests/functional/' + prefix = '/zfs-tests/tests/(?:functional|perf/regression)/' pattern = \ r'^Test(?:\s+\(\S+\))?:' + \ rf'\s*\S*{prefix}(\S+)' + \ From 5f45e3f699091e257941c2a5c37d8a65d91cd3a9 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 28 Nov 2022 14:36:53 -0500 Subject: [PATCH 13/45] Remove atomics from zh_refcount It is protected by z_hold_locks, so we do not need more serialization, simple integer math should be fine. Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Reviewed-by: Richard Yao Signed-off-by: Alexander Motin Closes #14196 --- include/sys/zfs_znode.h | 4 ++-- module/os/linux/zfs/zfs_znode.c | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 88d64235069..3a4a0c3cb53 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -242,9 +242,9 @@ zfs_enter_verify_zp(zfsvfs_t *zfsvfs, znode_t *zp, const char *tag) typedef struct znode_hold { uint64_t zh_obj; /* object id */ - kmutex_t zh_lock; /* lock serializing object access */ avl_node_t zh_node; /* avl tree linkage */ - zfs_refcount_t zh_refcount; /* active consumer reference count */ + kmutex_t zh_lock; /* lock serializing object access */ + int zh_refcount; /* active consumer reference count */ } znode_hold_t; static inline uint64_t diff --git a/module/os/linux/zfs/zfs_znode.c b/module/os/linux/zfs/zfs_znode.c index 662147ab472..d673da38463 100644 --- a/module/os/linux/zfs/zfs_znode.c +++ b/module/os/linux/zfs/zfs_znode.c @@ -169,8 +169,7 @@ zfs_znode_hold_cache_constructor(void *buf, void *arg, int kmflags) znode_hold_t *zh = buf; mutex_init(&zh->zh_lock, NULL, MUTEX_DEFAULT, NULL); - zfs_refcount_create(&zh->zh_refcount); - zh->zh_obj = ZFS_NO_OBJECT; + zh->zh_refcount = 0; return (0); } @@ -182,7 +181,6 @@ zfs_znode_hold_cache_destructor(void *buf, void *arg) znode_hold_t *zh = buf; mutex_destroy(&zh->zh_lock); - zfs_refcount_destroy(&zh->zh_refcount); } void @@ -281,26 +279,26 @@ zfs_znode_hold_enter(zfsvfs_t *zfsvfs, uint64_t obj) boolean_t found = B_FALSE; zh_new = kmem_cache_alloc(znode_hold_cache, KM_SLEEP); - zh_new->zh_obj = obj; search.zh_obj = obj; mutex_enter(&zfsvfs->z_hold_locks[i]); zh = avl_find(&zfsvfs->z_hold_trees[i], &search, NULL); if (likely(zh == NULL)) { zh = zh_new; + zh->zh_obj = obj; avl_add(&zfsvfs->z_hold_trees[i], zh); } else { ASSERT3U(zh->zh_obj, ==, obj); found = B_TRUE; } - zfs_refcount_add(&zh->zh_refcount, NULL); + zh->zh_refcount++; + ASSERT3S(zh->zh_refcount, >, 0); mutex_exit(&zfsvfs->z_hold_locks[i]); if (found == B_TRUE) kmem_cache_free(znode_hold_cache, zh_new); ASSERT(MUTEX_NOT_HELD(&zh->zh_lock)); - ASSERT3S(zfs_refcount_count(&zh->zh_refcount), >, 0); mutex_enter(&zh->zh_lock); return (zh); @@ -313,11 +311,11 @@ zfs_znode_hold_exit(zfsvfs_t *zfsvfs, znode_hold_t *zh) boolean_t remove = B_FALSE; ASSERT(zfs_znode_held(zfsvfs, zh->zh_obj)); - ASSERT3S(zfs_refcount_count(&zh->zh_refcount), >, 0); mutex_exit(&zh->zh_lock); mutex_enter(&zfsvfs->z_hold_locks[i]); - if (zfs_refcount_remove(&zh->zh_refcount, NULL) == 0) { + ASSERT3S(zh->zh_refcount, >, 0); + if (--zh->zh_refcount == 0) { avl_remove(&zfsvfs->z_hold_trees[i], zh); remove = B_TRUE; } From 387109364e66468736000a57e071cdfff8328ff6 Mon Sep 17 00:00:00 2001 From: Damian Szuberski Date: Tue, 29 Nov 2022 05:39:41 +1000 Subject: [PATCH 14/45] Python3: replace `distutils` with `sysconfig` - `distutils` module is long time deprecated and already deleted from the CPython mainline. - To remain compatible with Debian/Ubuntu Python3 packaging style, try `distutils.sysconfig.get_python_path(0,0)` first with fallback on `sysconfig.get_path('purelib')` - pyzfs_unittest suite is run unconditionally as a part of ZTS. - Add pyzfs_unittest suite to sanity tests. Reviewed-by: Brian Behlendorf Signed-off-by: szubersk Closes #12833 Closes #13280 Closes #14177 --- config/ax_python_devel.m4 | 51 +++++++------------ rpm/generic/zfs.spec.in | 2 +- tests/runfiles/sanity.run | 4 ++ tests/test-runner/bin/zts-report.py.in | 9 ---- .../functional/pyzfs/pyzfs_unittest.ksh.in | 16 +----- 5 files changed, 26 insertions(+), 56 deletions(-) diff --git a/config/ax_python_devel.m4 b/config/ax_python_devel.m4 index 7adcf01a04c..e6cee04288b 100644 --- a/config/ax_python_devel.m4 +++ b/config/ax_python_devel.m4 @@ -165,31 +165,16 @@ variable to configure. See ``configure --help'' for reference. fi fi - # - # Check if you have distutils, else fail - # - AC_MSG_CHECKING([for the distutils Python package]) - if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - m4_ifvaln([$2],[$2],[ - AC_MSG_ERROR([cannot import Python module "distutils". -Please check your Python installation. The error was: -$ac_distutils_result]) - PYTHON_VERSION="" - ]) - fi - # # Check for Python include path # + # AC_MSG_CHECKING([for Python include path]) if test -z "$PYTHON_CPPFLAGS"; then - python_path=`$PYTHON -c "import distutils.sysconfig; \ - print (distutils.sysconfig.get_python_inc ());"` - plat_python_path=`$PYTHON -c "import distutils.sysconfig; \ - print (distutils.sysconfig.get_python_inc (plat_specific=1));"` + python_path=`$PYTHON -c "import sysconfig; \ + print (sysconfig.get_path('include'));"` + plat_python_path=`$PYTHON -c "import sysconfig; \ + print (sysconfig.get_path('platinclude'));"` if test -n "${python_path}"; then if test "${plat_python_path}" != "${python_path}"; then python_path="-I$python_path -I$plat_python_path" @@ -213,7 +198,7 @@ $ac_distutils_result]) # join all versioning strings, on some systems # major/minor numbers could be in different list elements -from distutils.sysconfig import * +from sysconfig import * e = get_config_var('VERSION') if e is not None: print(e) @@ -236,8 +221,8 @@ EOD` ac_python_libdir=`cat</dev/null || \ + $PYTHON -c "import sysconfig; \ + print (sysconfig.get_path('purelib'));"` fi AC_MSG_RESULT([$PYTHON_SITE_PKG]) AC_SUBST([PYTHON_SITE_PKG]) @@ -299,8 +286,8 @@ EOD` # AC_MSG_CHECKING(python extra libraries) if test -z "$PYTHON_EXTRA_LIBS"; then - PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \ - conf = distutils.sysconfig.get_config_var; \ + PYTHON_EXTRA_LIBS=`$PYTHON -c "import sysconfig; \ + conf = sysconfig.get_config_var; \ print (conf('LIBS') + ' ' + conf('SYSLIBS'))"` fi AC_MSG_RESULT([$PYTHON_EXTRA_LIBS]) @@ -311,8 +298,8 @@ EOD` # AC_MSG_CHECKING(python extra linking flags) if test -z "$PYTHON_EXTRA_LDFLAGS"; then - PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \ - conf = distutils.sysconfig.get_config_var; \ + PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import sysconfig; \ + conf = sysconfig.get_config_var; \ print (conf('LINKFORSHARED'))"` fi AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS]) diff --git a/rpm/generic/zfs.spec.in b/rpm/generic/zfs.spec.in index aea82d24178..166411d91ad 100644 --- a/rpm/generic/zfs.spec.in +++ b/rpm/generic/zfs.spec.in @@ -78,7 +78,7 @@ %define __python %{__use_python} %define __python_pkg_version %{__use_python_pkg_version} %endif -%define __python_sitelib %(%{__python} -Esc "from distutils.sysconfig import get_python_lib; print(get_python_lib())") +%define __python_sitelib %(%{__python} -Esc "from distutils.sysconfig import get_python_lib; print(get_python_lib())" 2>/dev/null || %{__python} -Esc "import sysconfig; print(sysconfig.get_path('purelib'))") Name: @PACKAGE@ Version: @VERSION@ diff --git a/tests/runfiles/sanity.run b/tests/runfiles/sanity.run index f115f0b578c..51423966206 100644 --- a/tests/runfiles/sanity.run +++ b/tests/runfiles/sanity.run @@ -624,3 +624,7 @@ tags = ['functional', 'zvol', 'zvol_swap'] [tests/functional/zpool_influxdb] tests = ['zpool_influxdb'] tags = ['functional', 'zpool_influxdb'] + +[tests/functional/pyzfs] +tests = ['pyzfs_unittest'] +tags = ['functional', 'pyzfs'] diff --git a/tests/test-runner/bin/zts-report.py.in b/tests/test-runner/bin/zts-report.py.in index e5b1ae0f65e..a2324d4b52e 100755 --- a/tests/test-runner/bin/zts-report.py.in +++ b/tests/test-runner/bin/zts-report.py.in @@ -61,14 +61,6 @@ known_reason = 'Known issue' # exec_reason = 'Test user execute permissions required for utilities' -# -# Some tests require a minimum python version of 3.6 and will be skipped when -# the default system version is too old. There may also be tests which require -# additional python modules be installed, for example python3-cffi is required -# by the pyzfs tests. -# -python_deps_reason = 'Python modules missing: python3-cffi' - # # Some tests require that the kernel supports renameat2 syscall. # @@ -232,7 +224,6 @@ maybe = { 'io/mmap': ['SKIP', fio_reason], 'largest_pool/largest_pool_001_pos': ['FAIL', known_reason], 'mmp/mmp_on_uberblocks': ['FAIL', known_reason], - 'pyzfs/pyzfs_unittest': ['SKIP', python_deps_reason], 'pool_checkpoint/checkpoint_discard_busy': ['FAIL', 11946], 'projectquota/setup': ['SKIP', exec_reason], 'removal/removal_condense_export': ['FAIL', known_reason], diff --git a/tests/zfs-tests/tests/functional/pyzfs/pyzfs_unittest.ksh.in b/tests/zfs-tests/tests/functional/pyzfs/pyzfs_unittest.ksh.in index d55c4f3270a..7fa14161a53 100755 --- a/tests/zfs-tests/tests/functional/pyzfs/pyzfs_unittest.ksh.in +++ b/tests/zfs-tests/tests/functional/pyzfs/pyzfs_unittest.ksh.in @@ -18,6 +18,8 @@ if [ -n "$ASAN_OPTIONS" ]; then export LD_PRELOAD=$(ldd "$(command -v zfs)" | awk '/libasan\.so/ {print $3}') + # ASan reports leaks in CPython 3.10 + ASAN_OPTIONS="$ASAN_OPTIONS:detect_leaks=false" fi # @@ -30,20 +32,6 @@ fi # verify_runnable "global" - -# Verify that the required dependencies for testing are installed. -@PYTHON@ -c "import cffi" 2>/dev/null || - log_unsupported "python3-cffi not found by Python" - -# We don't just try to "import libzfs_core" because we want to skip these tests -# only if pyzfs was not installed due to missing, build-time, dependencies; if -# we cannot load "libzfs_core" due to other reasons, for instance an API/ABI -# mismatch, we want to report it. -@PYTHON@ -c ' -import pkgutil, sys -sys.exit(pkgutil.find_loader("libzfs_core") is None)' || - log_unsupported "libzfs_core not found by Python" - log_assert "Verify the nvlist and libzfs_core Python unittest run successfully" # log_must buffers stderr, which interacts badly with From 077fd55e85506ad892e9367b8ce7fb69e2ca590d Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Mon, 28 Nov 2022 14:41:14 -0500 Subject: [PATCH 15/45] zfs.4: Correct the default for zfs_vdev_async_write_max_active Reviewed-by: Alexander Motin Reviewed-by: Richard Yao Reviewed-by: George Melikov Signed-off-by: Allan Jude Closes #14179 --- man/man4/zfs.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man4/zfs.4 b/man/man4/zfs.4 index 3b3fbcabebc..8cef04cda99 100644 --- a/man/man4/zfs.4 +++ b/man/man4/zfs.4 @@ -1225,7 +1225,7 @@ the active I/O limit is linearly interpolated. .No See Sx ZFS I/O SCHEDULER . . -.It Sy zfs_vdev_async_write_max_active Ns = Ns Sy 30 Pq uint +.It Sy zfs_vdev_async_write_max_active Ns = Ns Sy 10 Pq uint Maximum asynchronous write I/O operations active to each device. .No See Sx ZFS I/O SCHEDULER . . From adf3b84fc7341864d13b99fcbecf18bbc325b1e4 Mon Sep 17 00:00:00 2001 From: Minsoo Choo Date: Mon, 28 Nov 2022 16:24:17 -0500 Subject: [PATCH 16/45] Add header According to the UNIX standard, does not include some PTHREAD_* values which are included in . OpenZFS uses some of these values in its code, and this might cause build failure on systems that do not have these PTHREAD_* values in Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Reviewed-by: Damian Szuberski Signed-off-by: Minsoo Choo Closes #14225 --- lib/libtpool/thread_pool.c | 1 + lib/libzpool/kernel.c | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/libtpool/thread_pool.c b/lib/libtpool/thread_pool.c index 3eef3d1e481..7802f8c1750 100644 --- a/lib/libtpool/thread_pool.c +++ b/lib/libtpool/thread_pool.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "thread_pool_impl.h" static pthread_mutex_t thread_pool_lock = PTHREAD_MUTEX_INITIALIZER; diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index 77264470bae..0e3e4cee7ba 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include From 022bdb5b0b722d5acef2a06cdab889cd62c22872 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Mon, 28 Nov 2022 16:29:55 -0500 Subject: [PATCH 17/45] Set multiple make jobs on CodeQL github workflows github supports 2 processors right now, although we use nproc instead of hard coding -j2, so if that ever increases, we will take advantage of it right away. Reviewed-by: George Melikov Reviewed-by: Damian Szuberski Reviewed-by: Tino Reichardt Signed-off-by: Richard Yao Closes #14217 --- .github/workflows/codeql.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c8a49a7f00b..037f8aca0ea 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,6 +19,10 @@ jobs: language: [ 'cpp', 'python' ] steps: + - name: Set make jobs + run: | + echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV + - name: Checkout repository uses: actions/checkout@v3 From 3069872ef5dcffd5343a9165ce08356a840a70d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Mon, 28 Nov 2022 22:37:07 +0100 Subject: [PATCH 18/45] cmd: zfs: fix missing mention of zfs diff -h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 344bbc82e7054f61d5e7b3610b119820285fd2cb Reviewed-by: Damian Szuberski Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Signed-off-by: Ahelenia Ziemiańska Closes #14224 --- cmd/zfs/zfs_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 6e79a73b95f..2d644c5de16 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -396,7 +396,7 @@ get_usage(zfs_help_t idx) case HELP_RELEASE: return (gettext("\trelease [-r] ...\n")); case HELP_DIFF: - return (gettext("\tdiff [-FHt] " + return (gettext("\tdiff [-FHth] " "[snapshot|filesystem]\n")); case HELP_BOOKMARK: return (gettext("\tbookmark " From d27a00283faf4ec2b997ff2376dee4a080e1ca7b Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Mon, 28 Nov 2022 16:40:49 -0500 Subject: [PATCH 19/45] Avoid a null pointer dereference in zfs_mount() on FreeBSD When mounting the root filesystem, vfs_t->mnt_vnodecovered is null This will cause zfsctl_is_node() to dereference a null pointer when mounting, or updating the mount flags, on the root filesystem, both of which happen during the boot process. Reported-by: Martin Matuska Reviewed-by: Richard Yao Reviewed-by: Alexander Motin Reviewed-by: Richard Yao Signed-off-by: Allan Jude Closes #14218 --- module/os/freebsd/zfs/zfs_vfsops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/os/freebsd/zfs/zfs_vfsops.c b/module/os/freebsd/zfs/zfs_vfsops.c index b4c122bdf4c..ffe63176459 100644 --- a/module/os/freebsd/zfs/zfs_vfsops.c +++ b/module/os/freebsd/zfs/zfs_vfsops.c @@ -1328,7 +1328,8 @@ zfs_mount(vfs_t *vfsp) } fetch_osname_options(osname, &checkpointrewind); - isctlsnap = (zfsctl_is_node(mvp) && strchr(osname, '@') != NULL); + isctlsnap = (mvp != NULL && zfsctl_is_node(mvp) && + strchr(osname, '@') != NULL); /* * Check for mount privilege? From 303678350a7253c7bee9d6a3347ee1bcdf9cc177 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Mon, 28 Nov 2022 16:49:58 -0500 Subject: [PATCH 20/45] Convert some sprintf() calls to kmem_scnprintf() These `sprintf()` calls are used repeatedly to write to a buffer. There is no protection against overflow other than reviewers explicitly checking to see if the buffers are big enough. However, such issues are easily missed during review and when they are missed, we would rather stop printing rather than have a buffer overflow, so we convert these functions to use `kmem_scnprintf()`. The Linux kernel provides an entire page for module parameters, so we are safe to write up to PAGE_SIZE. Removing `sprintf()` from these functions removes the last instances of `sprintf()` usage in our platform-independent kernel code. This improves XNU kernel compatibility because the XNU kernel does not support (removed support for?) `sprintf()`. Reviewed-by: Brian Behlendorf Reviewed-by: Jorgen Lundman Signed-off-by: Richard Yao Closes #14209 --- module/icp/algs/aes/aes_impl.c | 6 ++++-- module/icp/algs/blake3/blake3_impl.c | 6 +++--- module/icp/algs/modes/gcm.c | 6 ++++-- module/zcommon/zfs_fletcher.c | 4 ++-- module/zfs/vdev_raidz_math.c | 6 ++++-- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/module/icp/algs/aes/aes_impl.c b/module/icp/algs/aes/aes_impl.c index 7c92a7c8d13..9d90914aacf 100644 --- a/module/icp/algs/aes/aes_impl.c +++ b/module/icp/algs/aes/aes_impl.c @@ -424,13 +424,15 @@ icp_aes_impl_get(char *buffer, zfs_kernel_param_t *kp) /* list mandatory options */ for (i = 0; i < ARRAY_SIZE(aes_impl_opts); i++) { fmt = (impl == aes_impl_opts[i].sel) ? "[%s] " : "%s "; - cnt += sprintf(buffer + cnt, fmt, aes_impl_opts[i].name); + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, + aes_impl_opts[i].name); } /* list all supported implementations */ for (i = 0; i < aes_supp_impl_cnt; i++) { fmt = (i == impl) ? "[%s] " : "%s "; - cnt += sprintf(buffer + cnt, fmt, aes_supp_impl[i]->name); + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, + aes_supp_impl[i]->name); } return (cnt); diff --git a/module/icp/algs/blake3/blake3_impl.c b/module/icp/algs/blake3/blake3_impl.c index 1692916cef9..7bc4db2c980 100644 --- a/module/icp/algs/blake3/blake3_impl.c +++ b/module/icp/algs/blake3/blake3_impl.c @@ -282,16 +282,16 @@ blake3_param_get(char *buffer, zfs_kernel_param_t *unused) /* cycling */ fmt = IMPL_FMT(impl, IMPL_CYCLE); - cnt += sprintf(buffer + cnt, fmt, "cycle"); + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, "cycle"); /* list fastest */ fmt = IMPL_FMT(impl, IMPL_FASTEST); - cnt += sprintf(buffer + cnt, fmt, "fastest"); + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, "fastest"); /* list all supported implementations */ for (uint32_t i = 0; i < blake3_supp_impls_cnt; ++i) { fmt = IMPL_FMT(impl, i); - cnt += sprintf(buffer + cnt, fmt, + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, blake3_supp_impls[i]->name); } diff --git a/module/icp/algs/modes/gcm.c b/module/icp/algs/modes/gcm.c index 16ef14b8cca..558a578090b 100644 --- a/module/icp/algs/modes/gcm.c +++ b/module/icp/algs/modes/gcm.c @@ -1020,13 +1020,15 @@ icp_gcm_impl_get(char *buffer, zfs_kernel_param_t *kp) } #endif fmt = (impl == gcm_impl_opts[i].sel) ? "[%s] " : "%s "; - cnt += sprintf(buffer + cnt, fmt, gcm_impl_opts[i].name); + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, + gcm_impl_opts[i].name); } /* list all supported implementations */ for (i = 0; i < gcm_supp_impl_cnt; i++) { fmt = (i == impl) ? "[%s] " : "%s "; - cnt += sprintf(buffer + cnt, fmt, gcm_supp_impl[i]->name); + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, + gcm_supp_impl[i]->name); } return (cnt); diff --git a/module/zcommon/zfs_fletcher.c b/module/zcommon/zfs_fletcher.c index 9a201842ea6..44c8f486f6d 100644 --- a/module/zcommon/zfs_fletcher.c +++ b/module/zcommon/zfs_fletcher.c @@ -903,12 +903,12 @@ fletcher_4_param_get(char *buffer, zfs_kernel_param_t *unused) /* list fastest */ fmt = IMPL_FMT(impl, IMPL_FASTEST); - cnt += sprintf(buffer + cnt, fmt, "fastest"); + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, "fastest"); /* list all supported implementations */ for (uint32_t i = 0; i < fletcher_4_supp_impls_cnt; ++i) { fmt = IMPL_FMT(impl, i); - cnt += sprintf(buffer + cnt, fmt, + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, fletcher_4_supp_impls[i]->name); } diff --git a/module/zfs/vdev_raidz_math.c b/module/zfs/vdev_raidz_math.c index 2980f8acfbd..66f211c430c 100644 --- a/module/zfs/vdev_raidz_math.c +++ b/module/zfs/vdev_raidz_math.c @@ -653,13 +653,15 @@ zfs_vdev_raidz_impl_get(char *buffer, zfs_kernel_param_t *kp) /* list mandatory options */ for (i = 0; i < ARRAY_SIZE(math_impl_opts) - 2; i++) { fmt = (impl == math_impl_opts[i].sel) ? "[%s] " : "%s "; - cnt += sprintf(buffer + cnt, fmt, math_impl_opts[i].name); + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, + math_impl_opts[i].name); } /* list all supported implementations */ for (i = 0; i < raidz_supp_impl_cnt; i++) { fmt = (i == impl) ? "[%s] " : "%s "; - cnt += sprintf(buffer + cnt, fmt, raidz_supp_impl[i]->name); + cnt += kmem_scnprintf(buffer + cnt, PAGE_SIZE - cnt, fmt, + raidz_supp_impl[i]->name); } return (cnt); From e996c502e4f55facaa3b836fcf41f824eb1b6f73 Mon Sep 17 00:00:00 2001 From: Ameer Hamza <106930537+ixhamza@users.noreply.github.com> Date: Tue, 29 Nov 2022 22:24:10 +0500 Subject: [PATCH 21/45] zed: unclean disk attachment faults the vdev If the attached disk already contains a vdev GUID, it means the disk is not clean. In such a scenario, the physical path would be a match that makes the disk faulted when trying to online it. So, we would only want to proceed if either GUID matches with the last attached disk or the disk is in a clean state. Reviewed-by: Brian Behlendorf Reviewed-by: Alexander Motin Reviewed-by: Ryan Moeller Reviewed-by: Tony Hutter Signed-off-by: Ameer Hamza Closes #14181 --- cmd/zed/agents/zfs_mod.c | 26 +++++++++++++++++++------- module/zfs/vdev.c | 4 ++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/cmd/zed/agents/zfs_mod.c b/cmd/zed/agents/zfs_mod.c index 0271fffe42e..4fc8ceb9fb4 100644 --- a/cmd/zed/agents/zfs_mod.c +++ b/cmd/zed/agents/zfs_mod.c @@ -535,6 +535,7 @@ typedef struct dev_data { boolean_t dd_islabeled; uint64_t dd_pool_guid; uint64_t dd_vdev_guid; + uint64_t dd_new_vdev_guid; const char *dd_new_devid; } dev_data_t; @@ -545,6 +546,7 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data) char *path = NULL; uint_t c, children; nvlist_t **child; + uint64_t guid = 0; /* * First iterate over any children. @@ -572,17 +574,14 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data) /* once a vdev was matched and processed there is nothing left to do */ if (dp->dd_found) return; + (void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &guid); /* * Match by GUID if available otherwise fallback to devid or physical */ if (dp->dd_vdev_guid != 0) { - uint64_t guid; - - if (nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, - &guid) != 0 || guid != dp->dd_vdev_guid) { + if (guid != dp->dd_vdev_guid) return; - } zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched on %llu", guid); dp->dd_found = B_TRUE; @@ -592,6 +591,12 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data) * illumos, substring matching is not required to accommodate * the partition suffix. An exact match will be present in * the dp->dd_compare value. + * If the attached disk already contains a vdev GUID, it means + * the disk is not clean. In such a scenario, the physical path + * would be a match that makes the disk faulted when trying to + * online it. So, we would only want to proceed if either GUID + * matches with the last attached disk or the disk is in clean + * state. */ if (nvlist_lookup_string(nvl, dp->dd_prop, &path) != 0 || strcmp(dp->dd_compare, path) != 0) { @@ -599,6 +604,12 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data) __func__, dp->dd_compare, path); return; } + if (dp->dd_new_vdev_guid != 0 && dp->dd_new_vdev_guid != guid) { + zed_log_msg(LOG_INFO, " %s: no match (GUID:%llu" + " != vdev GUID:%llu)", __func__, + dp->dd_new_vdev_guid, guid); + return; + } zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched %s on %s", dp->dd_prop, path); @@ -680,7 +691,7 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data) */ static boolean_t devphys_iter(const char *physical, const char *devid, zfs_process_func_t func, - boolean_t is_slice) + boolean_t is_slice, uint64_t new_vdev_guid) { dev_data_t data = { 0 }; @@ -690,6 +701,7 @@ devphys_iter(const char *physical, const char *devid, zfs_process_func_t func, data.dd_found = B_FALSE; data.dd_islabeled = is_slice; data.dd_new_devid = devid; /* used by auto replace code */ + data.dd_new_vdev_guid = new_vdev_guid; (void) zpool_iter(g_zfshdl, zfs_iter_pool, &data); @@ -858,7 +870,7 @@ zfs_deliver_add(nvlist_t *nvl) if (devid_iter(devid, zfs_process_add, is_slice)) return (0); if (devpath != NULL && devphys_iter(devpath, devid, zfs_process_add, - is_slice)) + is_slice, vdev_guid)) return (0); if (vdev_guid != 0) (void) guid_iter(pool_guid, vdev_guid, devid, zfs_process_add, diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index 4520ca31b7d..89174426101 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -4269,9 +4269,9 @@ vdev_clear(spa_t *spa, vdev_t *vd) vdev_clear(spa, vd->vdev_child[c]); /* - * It makes no sense to "clear" an indirect vdev. + * It makes no sense to "clear" an indirect or removed vdev. */ - if (!vdev_is_concrete(vd)) + if (!vdev_is_concrete(vd) || vd->vdev_removed) return; /* From f0a76fbec1e536291eb0ef973625e07a19db04d5 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 29 Nov 2022 12:26:03 -0500 Subject: [PATCH 22/45] Micro-optimize zrl_remove() atomic_dec_32() should be a bit lighter than atomic_dec_32_nv(). Reviewed-by: Tino Reichardt Reviewed-by: Richard Yao Signed-off-by: Ryan Moeller Signed-off-by: Alexander Motin Closes #14200 --- module/zfs/zrlock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/zfs/zrlock.c b/module/zfs/zrlock.c index 3de2bde4cfe..0d50cc4712c 100644 --- a/module/zfs/zrlock.c +++ b/module/zfs/zrlock.c @@ -106,16 +106,16 @@ zrl_add_impl(zrlock_t *zrl, const char *zc) void zrl_remove(zrlock_t *zrl) { - uint32_t n; - #ifdef ZFS_DEBUG if (zrl->zr_owner == curthread) { zrl->zr_owner = NULL; zrl->zr_caller = NULL; } + int32_t n = atomic_dec_32_nv((uint32_t *)&zrl->zr_refcount); + ASSERT3S(n, >=, 0); +#else + atomic_dec_32((uint32_t *)&zrl->zr_refcount); #endif - n = atomic_dec_32_nv((uint32_t *)&zrl->zr_refcount); - ASSERT3S((int32_t)n, >=, 0); } int From 6712c7714083ba2c02bf5a9c0aa1024031fed858 Mon Sep 17 00:00:00 2001 From: Xinliang Liu Date: Wed, 30 Nov 2022 01:27:22 +0800 Subject: [PATCH 23/45] rpm: add support for openEuler OpenEuler uses the same package manager DNF as RHEL/Fedora. And it is similar to RHEL/Fedora. OpenEuler Linux is becoming the mainstream Linux distro in China. So adding support for it makes sense for the users. For more details about it see: https://www.openeuler.org/en/. Reviewed-by: Richard Yao Reviewed-by: George Melikov Reviewed-by: Damian Szuberski Signed-off-by: Xinliang Liu Closes #14222 --- rpm/generic/zfs-dkms.spec.in | 6 +++--- rpm/generic/zfs-kmod.spec.in | 11 ++++++----- rpm/generic/zfs.spec.in | 20 ++++++++++---------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/rpm/generic/zfs-dkms.spec.in b/rpm/generic/zfs-dkms.spec.in index 196d9a140b4..23c3ed6ff40 100644 --- a/rpm/generic/zfs-dkms.spec.in +++ b/rpm/generic/zfs-dkms.spec.in @@ -1,6 +1,6 @@ %{?!packager: %define packager Brian Behlendorf } -%if ! 0%{?rhel}%{?fedora}%{?mageia}%{?suse_version} +%if ! 0%{?rhel}%{?fedora}%{?mageia}%{?suse_version}%{?openEuler} %define not_rpm 1 %endif @@ -28,7 +28,7 @@ Requires(post): dkms >= 2.2.0.3 Requires(preun): dkms >= 2.2.0.3 Requires: gcc, make, perl, diffutils Requires(post): gcc, make, perl, diffutils -%if 0%{?rhel}%{?fedora}%{?mageia}%{?suse_version} +%if 0%{?rhel}%{?fedora}%{?mageia}%{?suse_version}%{?openEuler} Requires: kernel-devel >= @ZFS_META_KVER_MIN@, kernel-devel <= @ZFS_META_KVER_MAX@.999 Requires(post): kernel-devel >= @ZFS_META_KVER_MIN@, kernel-devel <= @ZFS_META_KVER_MAX@.999 Obsoletes: spl-dkms <= %{version} @@ -36,7 +36,7 @@ Obsoletes: spl-dkms <= %{version} Provides: %{module}-kmod = %{version} AutoReqProv: no -%if (0%{?fedora}%{?suse_version}) || (0%{?rhel} && 0%{?rhel} < 9) +%if (0%{?fedora}%{?suse_version}%{?openEuler}) || (0%{?rhel} && 0%{?rhel} < 9) # We don't directly use it, but if this isn't installed, rpmbuild as root can # crash+corrupt rpmdb # See issue #12071 diff --git a/rpm/generic/zfs-kmod.spec.in b/rpm/generic/zfs-kmod.spec.in index ae079542786..3c73e2ff2d6 100644 --- a/rpm/generic/zfs-kmod.spec.in +++ b/rpm/generic/zfs-kmod.spec.in @@ -1,7 +1,7 @@ %define module @PACKAGE@ %if !%{defined ksrc} -%if 0%{?rhel}%{?fedora} +%if 0%{?rhel}%{?fedora}%{?openEuler} %define ksrc ${kernel_version##*___} %else %define ksrc "$( \ @@ -16,7 +16,7 @@ %endif %if !%{defined kobj} -%if 0%{?rhel}%{?fedora} +%if 0%{?rhel}%{?fedora}%{?openEuler} %define kobj ${kernel_version##*___} %else %define kobj "$( \ @@ -52,12 +52,12 @@ URL: https://github.com/openzfs/zfs Source0: %{module}-%{version}.tar.gz Source10: kmodtool BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id} -u -n) -%if 0%{?rhel}%{?fedora} +%if 0%{?rhel}%{?fedora}%{?openEuler} BuildRequires: gcc, make BuildRequires: elfutils-libelf-devel %endif -%if (0%{?fedora}%{?suse_version}) || (0%{?rhel} && 0%{?rhel} < 9) +%if (0%{?fedora}%{?suse_version}%{?openEuler}) || (0%{?rhel} && 0%{?rhel} < 9) # We don't directly use it, but if this isn't installed, rpmbuild as root can # crash+corrupt rpmdb # See issue #12071 @@ -79,10 +79,11 @@ BuildRequires: %{_bindir}/kmodtool # Building local packages attempt to to use the installed kernel. %{?rhel:BuildRequires: kernel-devel} %{?fedora:BuildRequires: kernel-devel} +%{?openEuler:BuildRequires: kernel-devel} %{?suse_version:BuildRequires: kernel-source} %if !%{defined kernels} && !%{defined build_src_rpm} - %if 0%{?rhel}%{?fedora}%{?suse_version} + %if 0%{?rhel}%{?fedora}%{?suse_version}%{?openEuler} %define kernels %(ls -1 /usr/src/kernels) %else %define kernels %(ls -1 /lib/modules) diff --git a/rpm/generic/zfs.spec.in b/rpm/generic/zfs.spec.in index 166411d91ad..251470a67fb 100644 --- a/rpm/generic/zfs.spec.in +++ b/rpm/generic/zfs.spec.in @@ -3,7 +3,7 @@ # Set the default udev directory based on distribution. %if %{undefined _udevdir} -%if 0%{?fedora}%{?rhel}%{?centos} +%if 0%{?fedora}%{?rhel}%{?centos}%{?openEuler} %global _udevdir %{_prefix}/lib/udev %else %global _udevdir /lib/udev @@ -12,7 +12,7 @@ # Set the default udevrule directory based on distribution. %if %{undefined _udevruledir} -%if 0%{?fedora}%{?rhel}%{?centos} +%if 0%{?fedora}%{?rhel}%{?centos}%{?openEuler} %global _udevruledir %{_prefix}/lib/udev/rules.d %else %global _udevruledir /lib/udev/rules.d @@ -21,7 +21,7 @@ # Set the default dracut directory based on distribution. %if %{undefined _dracutdir} -%if 0%{?fedora}%{?rhel}%{?centos} +%if 0%{?fedora}%{?rhel}%{?centos}%{?openEuler} %global _dracutdir %{_prefix}/lib/dracut %else %global _dracutdir %{_prefix}/share/dracut @@ -66,7 +66,7 @@ %endif # Distros below support systemd -%if 0%{?rhel}%{?fedora}%{?centos}%{?suse_version} +%if 0%{?rhel}%{?fedora}%{?centos}%{?suse_version}%{?openEuler} %define _systemd 1 %endif @@ -102,7 +102,7 @@ Obsoletes: spl <= %{version} # Renaming those on either side would conflict with all available documentation. Conflicts: zfs-fuse -%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version} +%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version}%{?openEuler} BuildRequires: gcc, make BuildRequires: zlib-devel BuildRequires: libuuid-devel @@ -110,11 +110,11 @@ BuildRequires: libblkid-devel BuildRequires: libudev-devel BuildRequires: libattr-devel BuildRequires: openssl-devel -%if 0%{?fedora} || 0%{?rhel} >= 8 || 0%{?centos} >= 8 +%if 0%{?fedora}%{?openEuler} || 0%{?rhel} >= 8 || 0%{?centos} >= 8 BuildRequires: libtirpc-devel %endif -%if (0%{?fedora}%{?suse_version}) || (0%{?rhel} && 0%{?rhel} < 9) +%if (0%{?fedora}%{?suse_version}%{?openEuler}) || (0%{?rhel} && 0%{?rhel} < 9) # We don't directly use it, but if this isn't installed, rpmbuild as root can # crash+corrupt rpmdb # See issue #12071 @@ -251,7 +251,7 @@ Requires: sudo Requires: sysstat Requires: libaio Requires: python%{__python_pkg_version} -%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version} +%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version}%{?openEuler} BuildRequires: libaio-devel %endif AutoReqProv: no @@ -292,7 +292,7 @@ Requires: python36-cffi Requires: python%{__python_pkg_version}-cffi %endif -%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version} +%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version}%{?openEuler} %if 0%{?centos} == 7 BuildRequires: python36-packaging BuildRequires: python36-devel @@ -328,7 +328,7 @@ image which is ZFS aware. %package -n pam_zfs_key Summary: PAM module for encrypted ZFS datasets -%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version} +%if 0%{?rhel}%{?centos}%{?fedora}%{?suse_version}%{?openEuler} BuildRequires: pam-devel %endif From 4df415aa864690163808147b82d9e5ce2be12f68 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 29 Nov 2022 12:33:45 -0500 Subject: [PATCH 24/45] Switch dnode stats to wmsums I've noticed that some of those counters are used in hot paths like dnode_hold_impl(), and results of this change is visible in profiler. Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Reviewed-by: Ryan Moeller Signed-off-by: Alexander Motin Closes #14198 --- include/sys/dnode.h | 35 +++++++++++- module/zfs/dnode.c | 127 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 1 deletion(-) diff --git a/include/sys/dnode.h b/include/sys/dnode.h index 28d8847a172..9553988e7dd 100644 --- a/include/sys/dnode.h +++ b/include/sys/dnode.h @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -587,10 +588,42 @@ typedef struct dnode_stats { kstat_named_t dnode_move_active; } dnode_stats_t; +typedef struct dnode_sums { + wmsum_t dnode_hold_dbuf_hold; + wmsum_t dnode_hold_dbuf_read; + wmsum_t dnode_hold_alloc_hits; + wmsum_t dnode_hold_alloc_misses; + wmsum_t dnode_hold_alloc_interior; + wmsum_t dnode_hold_alloc_lock_retry; + wmsum_t dnode_hold_alloc_lock_misses; + wmsum_t dnode_hold_alloc_type_none; + wmsum_t dnode_hold_free_hits; + wmsum_t dnode_hold_free_misses; + wmsum_t dnode_hold_free_lock_misses; + wmsum_t dnode_hold_free_lock_retry; + wmsum_t dnode_hold_free_refcount; + wmsum_t dnode_hold_free_overflow; + wmsum_t dnode_free_interior_lock_retry; + wmsum_t dnode_allocate; + wmsum_t dnode_reallocate; + wmsum_t dnode_buf_evict; + wmsum_t dnode_alloc_next_chunk; + wmsum_t dnode_alloc_race; + wmsum_t dnode_alloc_next_block; + wmsum_t dnode_move_invalid; + wmsum_t dnode_move_recheck1; + wmsum_t dnode_move_recheck2; + wmsum_t dnode_move_special; + wmsum_t dnode_move_handle; + wmsum_t dnode_move_rwlock; + wmsum_t dnode_move_active; +} dnode_sums_t; + extern dnode_stats_t dnode_stats; +extern dnode_sums_t dnode_sums; #define DNODE_STAT_INCR(stat, val) \ - atomic_add_64(&dnode_stats.stat.value.ui64, (val)); + wmsum_add(&dnode_sums.stat, (val)) #define DNODE_STAT_BUMP(stat) \ DNODE_STAT_INCR(stat, 1); diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c index ef27dfd40af..1a40e394ee7 100644 --- a/module/zfs/dnode.c +++ b/module/zfs/dnode.c @@ -71,6 +71,8 @@ dnode_stats_t dnode_stats = { { "dnode_move_active", KSTAT_DATA_UINT64 }, }; +dnode_sums_t dnode_sums; + static kstat_t *dnode_ksp; static kmem_cache_t *dnode_cache; @@ -225,6 +227,72 @@ dnode_dest(void *arg, void *unused) avl_destroy(&dn->dn_dbufs); } +static int +dnode_kstats_update(kstat_t *ksp, int rw) +{ + dnode_stats_t *ds = ksp->ks_data; + + if (rw == KSTAT_WRITE) + return (EACCES); + ds->dnode_hold_dbuf_hold.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_dbuf_hold); + ds->dnode_hold_dbuf_read.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_dbuf_read); + ds->dnode_hold_alloc_hits.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_alloc_hits); + ds->dnode_hold_alloc_misses.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_alloc_misses); + ds->dnode_hold_alloc_interior.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_alloc_interior); + ds->dnode_hold_alloc_lock_retry.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_alloc_lock_retry); + ds->dnode_hold_alloc_lock_misses.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_alloc_lock_misses); + ds->dnode_hold_alloc_type_none.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_alloc_type_none); + ds->dnode_hold_free_hits.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_free_hits); + ds->dnode_hold_free_misses.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_free_misses); + ds->dnode_hold_free_lock_misses.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_free_lock_misses); + ds->dnode_hold_free_lock_retry.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_free_lock_retry); + ds->dnode_hold_free_refcount.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_free_refcount); + ds->dnode_hold_free_overflow.value.ui64 = + wmsum_value(&dnode_sums.dnode_hold_free_overflow); + ds->dnode_free_interior_lock_retry.value.ui64 = + wmsum_value(&dnode_sums.dnode_free_interior_lock_retry); + ds->dnode_allocate.value.ui64 = + wmsum_value(&dnode_sums.dnode_allocate); + ds->dnode_reallocate.value.ui64 = + wmsum_value(&dnode_sums.dnode_reallocate); + ds->dnode_buf_evict.value.ui64 = + wmsum_value(&dnode_sums.dnode_buf_evict); + ds->dnode_alloc_next_chunk.value.ui64 = + wmsum_value(&dnode_sums.dnode_alloc_next_chunk); + ds->dnode_alloc_race.value.ui64 = + wmsum_value(&dnode_sums.dnode_alloc_race); + ds->dnode_alloc_next_block.value.ui64 = + wmsum_value(&dnode_sums.dnode_alloc_next_block); + ds->dnode_move_invalid.value.ui64 = + wmsum_value(&dnode_sums.dnode_move_invalid); + ds->dnode_move_recheck1.value.ui64 = + wmsum_value(&dnode_sums.dnode_move_recheck1); + ds->dnode_move_recheck2.value.ui64 = + wmsum_value(&dnode_sums.dnode_move_recheck2); + ds->dnode_move_special.value.ui64 = + wmsum_value(&dnode_sums.dnode_move_special); + ds->dnode_move_handle.value.ui64 = + wmsum_value(&dnode_sums.dnode_move_handle); + ds->dnode_move_rwlock.value.ui64 = + wmsum_value(&dnode_sums.dnode_move_rwlock); + ds->dnode_move_active.value.ui64 = + wmsum_value(&dnode_sums.dnode_move_active); + return (0); +} + void dnode_init(void) { @@ -233,11 +301,41 @@ dnode_init(void) 0, dnode_cons, dnode_dest, NULL, NULL, NULL, 0); kmem_cache_set_move(dnode_cache, dnode_move); + wmsum_init(&dnode_sums.dnode_hold_dbuf_hold, 0); + wmsum_init(&dnode_sums.dnode_hold_dbuf_read, 0); + wmsum_init(&dnode_sums.dnode_hold_alloc_hits, 0); + wmsum_init(&dnode_sums.dnode_hold_alloc_misses, 0); + wmsum_init(&dnode_sums.dnode_hold_alloc_interior, 0); + wmsum_init(&dnode_sums.dnode_hold_alloc_lock_retry, 0); + wmsum_init(&dnode_sums.dnode_hold_alloc_lock_misses, 0); + wmsum_init(&dnode_sums.dnode_hold_alloc_type_none, 0); + wmsum_init(&dnode_sums.dnode_hold_free_hits, 0); + wmsum_init(&dnode_sums.dnode_hold_free_misses, 0); + wmsum_init(&dnode_sums.dnode_hold_free_lock_misses, 0); + wmsum_init(&dnode_sums.dnode_hold_free_lock_retry, 0); + wmsum_init(&dnode_sums.dnode_hold_free_refcount, 0); + wmsum_init(&dnode_sums.dnode_hold_free_overflow, 0); + wmsum_init(&dnode_sums.dnode_free_interior_lock_retry, 0); + wmsum_init(&dnode_sums.dnode_allocate, 0); + wmsum_init(&dnode_sums.dnode_reallocate, 0); + wmsum_init(&dnode_sums.dnode_buf_evict, 0); + wmsum_init(&dnode_sums.dnode_alloc_next_chunk, 0); + wmsum_init(&dnode_sums.dnode_alloc_race, 0); + wmsum_init(&dnode_sums.dnode_alloc_next_block, 0); + wmsum_init(&dnode_sums.dnode_move_invalid, 0); + wmsum_init(&dnode_sums.dnode_move_recheck1, 0); + wmsum_init(&dnode_sums.dnode_move_recheck2, 0); + wmsum_init(&dnode_sums.dnode_move_special, 0); + wmsum_init(&dnode_sums.dnode_move_handle, 0); + wmsum_init(&dnode_sums.dnode_move_rwlock, 0); + wmsum_init(&dnode_sums.dnode_move_active, 0); + dnode_ksp = kstat_create("zfs", 0, "dnodestats", "misc", KSTAT_TYPE_NAMED, sizeof (dnode_stats) / sizeof (kstat_named_t), KSTAT_FLAG_VIRTUAL); if (dnode_ksp != NULL) { dnode_ksp->ks_data = &dnode_stats; + dnode_ksp->ks_update = dnode_kstats_update; kstat_install(dnode_ksp); } } @@ -250,6 +348,35 @@ dnode_fini(void) dnode_ksp = NULL; } + wmsum_fini(&dnode_sums.dnode_hold_dbuf_hold); + wmsum_fini(&dnode_sums.dnode_hold_dbuf_read); + wmsum_fini(&dnode_sums.dnode_hold_alloc_hits); + wmsum_fini(&dnode_sums.dnode_hold_alloc_misses); + wmsum_fini(&dnode_sums.dnode_hold_alloc_interior); + wmsum_fini(&dnode_sums.dnode_hold_alloc_lock_retry); + wmsum_fini(&dnode_sums.dnode_hold_alloc_lock_misses); + wmsum_fini(&dnode_sums.dnode_hold_alloc_type_none); + wmsum_fini(&dnode_sums.dnode_hold_free_hits); + wmsum_fini(&dnode_sums.dnode_hold_free_misses); + wmsum_fini(&dnode_sums.dnode_hold_free_lock_misses); + wmsum_fini(&dnode_sums.dnode_hold_free_lock_retry); + wmsum_fini(&dnode_sums.dnode_hold_free_refcount); + wmsum_fini(&dnode_sums.dnode_hold_free_overflow); + wmsum_fini(&dnode_sums.dnode_free_interior_lock_retry); + wmsum_fini(&dnode_sums.dnode_allocate); + wmsum_fini(&dnode_sums.dnode_reallocate); + wmsum_fini(&dnode_sums.dnode_buf_evict); + wmsum_fini(&dnode_sums.dnode_alloc_next_chunk); + wmsum_fini(&dnode_sums.dnode_alloc_race); + wmsum_fini(&dnode_sums.dnode_alloc_next_block); + wmsum_fini(&dnode_sums.dnode_move_invalid); + wmsum_fini(&dnode_sums.dnode_move_recheck1); + wmsum_fini(&dnode_sums.dnode_move_recheck2); + wmsum_fini(&dnode_sums.dnode_move_special); + wmsum_fini(&dnode_sums.dnode_move_handle); + wmsum_fini(&dnode_sums.dnode_move_rwlock); + wmsum_fini(&dnode_sums.dnode_move_active); + kmem_cache_destroy(dnode_cache); dnode_cache = NULL; } From 9aea88ba4402238dc70ba35754c446f880971c6e Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Tue, 29 Nov 2022 18:35:25 +0100 Subject: [PATCH 25/45] FreeBSD: stop using buffer cache-only routines on sync Both vop_fsync and vfs_stdsync are effectively just costly no-ops as they only act on ->v_bufobj.bo_dirty et al, which are unused by zfs. Reviewed-by: Ryan Moeller Signed-off-by: Mateusz Guzik Closes #14157 --- module/os/freebsd/zfs/zfs_vfsops.c | 4 ---- module/os/freebsd/zfs/zfs_vnops_os.c | 1 - 2 files changed, 5 deletions(-) diff --git a/module/os/freebsd/zfs/zfs_vfsops.c b/module/os/freebsd/zfs/zfs_vfsops.c index ffe63176459..1063e6f7596 100644 --- a/module/os/freebsd/zfs/zfs_vfsops.c +++ b/module/os/freebsd/zfs/zfs_vfsops.c @@ -438,10 +438,6 @@ zfs_sync(vfs_t *vfsp, int waitfor) dsl_pool_t *dp; int error; - error = vfs_stdsync(vfsp, waitfor); - if (error != 0) - return (error); - if ((error = zfs_enter(zfsvfs, FTAG)) != 0) return (error); dp = dmu_objset_pool(zfsvfs->z_os); diff --git a/module/os/freebsd/zfs/zfs_vnops_os.c b/module/os/freebsd/zfs/zfs_vnops_os.c index 8a350ab4985..f552531a52e 100644 --- a/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/module/os/freebsd/zfs/zfs_vnops_os.c @@ -4724,7 +4724,6 @@ static int zfs_freebsd_fsync(struct vop_fsync_args *ap) { - vop_stdfsync(ap); return (zfs_fsync(VTOZ(ap->a_vp), 0, ap->a_td->td_ucred)); } From fd61b2eabaa172c3ef08f7dbfac6e228c7d49dc9 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 29 Nov 2022 12:49:02 -0500 Subject: [PATCH 26/45] Remove few pointer dereferences in dbuf_read() Reviewed-by: Brian Behlendorf Reviewed-by: Richard Yao Reviewed-by: Ryan Moeller Signed-off-by: Alexander Motin Closes #14199 --- module/zfs/dbuf.c | 9 ++++----- module/zfs/dnode.c | 8 -------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 7982d970289..8190b0f76d5 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -1503,8 +1503,8 @@ dbuf_read_verify_dnode_crypt(dmu_buf_impl_t *db, uint32_t flags) ASSERT(MUTEX_HELD(&db->db_mtx)); - if (!os->os_encrypted || os->os_raw_receive || - (flags & DB_RF_NO_DECRYPT) != 0) + if ((flags & DB_RF_NO_DECRYPT) != 0 || + !os->os_encrypted || os->os_raw_receive) return (0); DB_DNODE_ENTER(db); @@ -1738,8 +1738,6 @@ dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags) mutex_enter(&db->db_mtx); if (db->db_state == DB_CACHED) { - spa_t *spa = dn->dn_objset->os_spa; - /* * Ensure that this block's dnode has been decrypted if * the caller has requested decrypted data. @@ -1758,6 +1756,7 @@ dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags) (arc_is_encrypted(db->db_buf) || arc_is_unauthenticated(db->db_buf) || arc_get_compression(db->db_buf) != ZIO_COMPRESS_OFF)) { + spa_t *spa = dn->dn_objset->os_spa; zbookmark_phys_t zb; SET_BOOKMARK(&zb, dmu_objset_id(db->db_objset), @@ -1774,13 +1773,13 @@ dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags) DB_DNODE_EXIT(db); DBUF_STAT_BUMP(hash_hits); } else if (db->db_state == DB_UNCACHED) { - spa_t *spa = dn->dn_objset->os_spa; boolean_t need_wait = B_FALSE; db_lock_type_t dblt = dmu_buf_lock_parent(db, RW_READER, FTAG); if (zio == NULL && db->db_blkptr != NULL && !BP_IS_HOLE(db->db_blkptr)) { + spa_t *spa = dn->dn_objset->os_spa; zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL); need_wait = B_TRUE; } diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c index 1a40e394ee7..2a2c66f9ff9 100644 --- a/module/zfs/dnode.c +++ b/module/zfs/dnode.c @@ -2407,19 +2407,11 @@ dnode_spill_freed(dnode_t *dn) uint64_t dnode_block_freed(dnode_t *dn, uint64_t blkid) { - void *dp = spa_get_dsl(dn->dn_objset->os_spa); int i; if (blkid == DMU_BONUS_BLKID) return (FALSE); - /* - * If we're in the process of opening the pool, dp will not be - * set yet, but there shouldn't be anything dirty. - */ - if (dp == NULL) - return (FALSE); - if (dn->dn_free_txg) return (TRUE); From d6df4441c03ae1fb90f57b125d2c4813cc1561ca Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Tue, 29 Nov 2022 09:51:35 -0800 Subject: [PATCH 27/45] Don't leak packed recieved proprties When local properties (e.g., from -o and -x) are provided, don't leak the packed representation of the received properties due to variable reuse. Reviewed-by: Brian Behlendorf Signed-off-by: Brooks Davis Closes #14197 --- lib/libzfs_core/libzfs_core.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/libzfs_core/libzfs_core.c b/lib/libzfs_core/libzfs_core.c index 3fe65e665b9..254f14e0432 100644 --- a/lib/libzfs_core/libzfs_core.c +++ b/lib/libzfs_core/libzfs_core.c @@ -1105,7 +1105,8 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops, fnvlist_free(outnvl); } else { zfs_cmd_t zc = {"\0"}; - char *packed = NULL; + char *rp_packed = NULL; + char *lp_packed = NULL; size_t size; ASSERT3S(g_refcount, >, 0); @@ -1114,14 +1115,14 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops, (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value)); if (recvdprops != NULL) { - packed = fnvlist_pack(recvdprops, &size); - zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed; + rp_packed = fnvlist_pack(recvdprops, &size); + zc.zc_nvlist_src = (uint64_t)(uintptr_t)rp_packed; zc.zc_nvlist_src_size = size; } if (localprops != NULL) { - packed = fnvlist_pack(localprops, &size); - zc.zc_nvlist_conf = (uint64_t)(uintptr_t)packed; + lp_packed = fnvlist_pack(localprops, &size); + zc.zc_nvlist_conf = (uint64_t)(uintptr_t)lp_packed; zc.zc_nvlist_conf_size = size; } @@ -1156,8 +1157,10 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops, zc.zc_nvlist_dst_size, errors, KM_SLEEP)); } - if (packed != NULL) - fnvlist_pack_free(packed, size); + if (rp_packed != NULL) + fnvlist_pack_free(rp_packed, size); + if (lp_packed != NULL) + fnvlist_pack_free(lp_packed, size); free((void *)(uintptr_t)zc.zc_nvlist_dst); } From 587a39b7290b8437dbc15edbf679f33d72459df0 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Tue, 29 Nov 2022 12:53:33 -0500 Subject: [PATCH 28/45] Lua: Fix bad bitshift in lua_strx2number() The port of lua to OpenZFS modified lua to use int64_t for numbers instead of double. As part of this, a function for calculating exponentiation was replaced with a bit shift. Unfortunately, it did not handle negative values. Also, it only supported exponents numbers with 7 digits before before overflow. This supports exponents up to 15 digits before overflow. Clang's static analyzer reported this as "Result of operation is garbage or undefined" because the exponent was negative. Reviewed-by: Damian Szuberski Reviewed-by: Brian Behlendorf Signed-off-by: Richard Yao Closes #14204 --- module/lua/lobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/lua/lobject.c b/module/lua/lobject.c index f74dacdf5fa..ea1f9a8e3b9 100644 --- a/module/lua/lobject.c +++ b/module/lua/lobject.c @@ -143,7 +143,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { *endptr = cast(char *, s); /* valid up to here */ ret: if (neg) r = -r; - return (r * (1 << e)); + return ((e >= 0) ? (r * (1ULL << e)) : (r / (1ULL << -e))); } #endif From b5459dd3541e76a46d3c49b480742ded05c429fd Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 29 Nov 2022 18:56:16 +0100 Subject: [PATCH 29/45] Fix the last two CFI callback prototype mismatches There was the series from me a year ago which fixed most of the callback vs implementation prototype mismatches. It was based on running the CFI-enabled kernel (in permissive mode -- warning instead of panic) and performing a full ZTS cycle, and then fixing all of the problems caught by CFI. Now, Clang 16-dev has new warning flag, -Wcast-function-type-strict, which detect such mismatches at compile-time. It allows to find the remaining issues missed by the first series. There are only two of them left: one for the secpolicy_vnode_setattr() callback and one for taskq_dispatch(). The fix is easy, since they are not used anywhere else. Reviewed-by: Brian Behlendorf Signed-off-by: Alexander Lobakin Closes #14207 --- include/sys/zfs_acl.h | 2 +- module/os/freebsd/zfs/zfs_acl.c | 2 +- module/os/linux/zfs/zfs_acl.c | 2 +- module/os/linux/zfs/zfs_vnops_os.c | 2 +- module/zfs/txg.c | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/sys/zfs_acl.h b/include/sys/zfs_acl.h index 82fb98c9fb8..e5c570c474a 100644 --- a/include/sys/zfs_acl.h +++ b/include/sys/zfs_acl.h @@ -219,7 +219,7 @@ extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *, zuserns_t *); int zfs_fastaccesschk_execute(struct znode *, cred_t *); extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *, zuserns_t *); -extern int zfs_zaccess_unix(struct znode *, mode_t, cred_t *); +extern int zfs_zaccess_unix(void *, int, cred_t *); extern int zfs_acl_access(struct znode *, int, cred_t *); int zfs_acl_chmod_setattr(struct znode *, zfs_acl_t **, uint64_t); int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *, zuserns_t *); diff --git a/module/os/freebsd/zfs/zfs_acl.c b/module/os/freebsd/zfs/zfs_acl.c index 16bcd338de2..64906b3bad6 100644 --- a/module/os/freebsd/zfs/zfs_acl.c +++ b/module/os/freebsd/zfs/zfs_acl.c @@ -2483,7 +2483,7 @@ zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr, * Access function for secpolicy_vnode_setattr */ int -zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr) +zfs_zaccess_unix(void *zp, int mode, cred_t *cr) { int v4_mode = zfs_unix_to_v4(mode >> 6); diff --git a/module/os/linux/zfs/zfs_acl.c b/module/os/linux/zfs/zfs_acl.c index 7d14863c56c..89bfa02af76 100644 --- a/module/os/linux/zfs/zfs_acl.c +++ b/module/os/linux/zfs/zfs_acl.c @@ -2788,7 +2788,7 @@ zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr, * Access function for secpolicy_vnode_setattr */ int -zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr) +zfs_zaccess_unix(void *zp, int mode, cred_t *cr) { int v4_mode = zfs_unix_to_v4(mode >> 6); diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c index 29d62837a82..94ae5e91f1c 100644 --- a/module/os/linux/zfs/zfs_vnops_os.c +++ b/module/os/linux/zfs/zfs_vnops_os.c @@ -2186,7 +2186,7 @@ top: vap->va_mask &= ~trim_mask; } err = secpolicy_vnode_setattr(cr, ip, vap, &oldva, flags, - (int (*)(void *, int, cred_t *))zfs_zaccess_unix, zp); + zfs_zaccess_unix, zp); if (err) goto out3; diff --git a/module/zfs/txg.c b/module/zfs/txg.c index 29eb9e8e801..ec61cabcaab 100644 --- a/module/zfs/txg.c +++ b/module/zfs/txg.c @@ -429,7 +429,7 @@ txg_quiesce(dsl_pool_t *dp, uint64_t txg) } static void -txg_do_callbacks(list_t *cb_list) +txg_do_callbacks(void *cb_list) { dmu_tx_do_callbacks(cb_list, 0); @@ -479,7 +479,7 @@ txg_dispatch_callbacks(dsl_pool_t *dp, uint64_t txg) list_move_tail(cb_list, &tc->tc_callbacks[g]); - (void) taskq_dispatch(tx->tx_commit_cb_taskq, (task_func_t *) + (void) taskq_dispatch(tx->tx_commit_cb_taskq, txg_do_callbacks, cb_list, TQ_SLEEP); } } From 8532da5e20b90bed8decd22726a70c7c81ef6951 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Wed, 16 Nov 2022 16:38:19 -0500 Subject: [PATCH 30/45] Cleanup: Delete dead code from send_merge_thread() range is always deferenced before it reaches this check, such that the kmem_zalloc() call is never executed. A previously version of this had erronously also pruned the `range->eos_marker = B_TRUE` line, but it must be set whenever we encounter an error or are cancelled early. Coverity incorrectly complained about a potential NULL pointer dereference because of this. Reported-by: Coverity (CID 1524550) Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Signed-off-by: Richard Yao Closes #14210 --- module/zfs/dmu_send.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index ccb7eb20756..fbf19d5c337 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -1586,8 +1586,6 @@ send_merge_thread(void *arg) } range_free(front_ranges[i]); } - if (range == NULL) - range = kmem_zalloc(sizeof (*range), KM_SLEEP); range->eos_marker = B_TRUE; bqueue_enqueue_flush(&smt_arg->q, range, 1); spl_fstrans_unmark(cookie); From 887fb37843887f79582003f55b314530b870643a Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Wed, 16 Nov 2022 16:23:53 -0500 Subject: [PATCH 31/45] zdb: Silence Coverity complaint about verify_livelist_allocs() svb is declared on the stack. We then set parts of svb.svb_dva with DVA_SET_VDEV(), DVA_SET_OFFSET() and DVA_SET_ASIZE(). However, the DVA contains other fields for pad, GRID and G. When setting the fields we use, we technically read uninitialized bits from the fields we do not use. This makes Coverity and Clang's Static Analyzer complain. Presumably, other static analyzers might complain too. There is no real bug here, but we are still technically reading undefined data and unless we stop doing that, static analyzers will complain about it in perpetuum and this could obscure real issues. We silence the static analyzer complaints by using a 0 struct initializer. Reported by: Coverity (CID 1524627) Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Signed-off-by: Richard Yao Closes #14210 --- cmd/zdb/zdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index d19eb71f0f6..8b5e5a4ed93 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -468,7 +468,7 @@ static void verify_livelist_allocs(metaslab_verify_t *mv, uint64_t txg, uint64_t offset, uint64_t size) { - sublivelist_verify_block_t svb; + sublivelist_verify_block_t svb = {{{0}}}; DVA_SET_VDEV(&svb.svb_dva, mv->mv_vdid); DVA_SET_OFFSET(&svb.svb_dva, offset); DVA_SET_ASIZE(&svb.svb_dva, size); From 97fac0fb70e35bb01c0d97f227c802c0fcbbf3da Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Sun, 20 Nov 2022 18:04:08 -0500 Subject: [PATCH 32/45] Fix NULL pointer dereference in dbuf_prefetch_indirect_done() When ZFS is built with assertions, a prefetch is done on a redacted blkptr and `dpa->dpa_dnode` is NULL, we will have a NULL pointer dereference in `dbuf_prefetch_indirect_done()`. Both Coverity and Clang's Static Analyzer caught this. Reported-by: Coverity (CID 1524671) Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Signed-off-by: Richard Yao Closes #14210 --- module/zfs/dbuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 8190b0f76d5..52760fb1b57 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -3322,10 +3322,10 @@ dbuf_prefetch_indirect_done(zio_t *zio, const zbookmark_phys_t *zb, blkptr_t *bp = ((blkptr_t *)abuf->b_data) + P2PHASE(nextblkid, 1ULL << dpa->dpa_epbs); - ASSERT(!BP_IS_REDACTED(bp) || + ASSERT(!BP_IS_REDACTED(bp) || (dpa->dpa_dnode && dsl_dataset_feature_is_active( dpa->dpa_dnode->dn_objset->os_dsl_dataset, - SPA_FEATURE_REDACTED_DATASETS)); + SPA_FEATURE_REDACTED_DATASETS))); if (BP_IS_HOLE(bp) || BP_IS_REDACTED(bp)) { arc_buf_destroy(abuf, private); dbuf_prefetch_fini(dpa, B_TRUE); From eb1ed2a66b7fddb30d62fb90bea1f8afa722098a Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Wed, 19 Oct 2022 16:28:52 -0400 Subject: [PATCH 33/45] Coverity Model Update When reviewing Clang Static Analyzer reports against a branch that had experimental header changes based on the Coverity model file to inform it that KM_SLEEP allocations cannot return NULL, I found a report saying that a KM_PUSHPAGE allocation returned NULL. The actual implementation does not return NULL unless KM_NOSLEEP has been passed, so we backport the correction from the experimental header changes to the Coverity model. Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Signed-off-by: Richard Yao Closes #14210 --- contrib/coverity/model.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/contrib/coverity/model.c b/contrib/coverity/model.c index 8e3e83cada1..8b4d14ee22a 100644 --- a/contrib/coverity/model.c +++ b/contrib/coverity/model.c @@ -24,6 +24,8 @@ #include +#define KM_NOSLEEP 0x0001 /* cannot block for memory; may fail */ + #define UMEM_DEFAULT 0x0000 /* normal -- may fail */ #define UMEM_NOFAIL 0x0100 /* Never fails */ @@ -173,7 +175,7 @@ spl_kmem_alloc(size_t sz, int fl, const char *func, int line) if (condition1) __coverity_sleep__(); - if ((fl == 0) || condition0) { + if (((fl & KM_NOSLEEP) != KM_NOSLEEP) || condition0) { void *buf = __coverity_alloc__(sz); __coverity_mark_as_uninitialized_buffer__(buf); __coverity_mark_as_afm_allocated__(buf, "spl_kmem_free"); @@ -194,7 +196,7 @@ spl_kmem_zalloc(size_t sz, int fl, const char *func, int line) if (condition1) __coverity_sleep__(); - if ((fl == 0) || condition0) { + if (((fl & KM_NOSLEEP) != KM_NOSLEEP) || condition0) { void *buf = __coverity_alloc__(sz); __coverity_writeall0__(buf); __coverity_mark_as_afm_allocated__(buf, "spl_kmem_free"); @@ -276,7 +278,7 @@ spl_vmem_alloc(size_t sz, int fl, const char *func, int line) if (condition1) __coverity_sleep__(); - if ((fl == 0) || condition0) { + if (((fl & KM_NOSLEEP) != KM_NOSLEEP) || condition0) { void *buf = __coverity_alloc__(sz); __coverity_mark_as_uninitialized_buffer__(buf); __coverity_mark_as_afm_allocated__(buf, "spl_vmem_free"); @@ -295,7 +297,7 @@ spl_vmem_zalloc(size_t sz, int fl, const char *func, int line) if (condition1) __coverity_sleep__(); - if ((fl == 0) || condition0) { + if (((fl & KM_NOSLEEP) != KM_NOSLEEP) || condition0) { void *buf = __coverity_alloc__(sz); __coverity_writeall0__(buf); __coverity_mark_as_afm_allocated__(buf, "spl_vmem_free"); From 466cf54ecf2ff0d6ad2e07ae1c03301de9d602b6 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 22 Jun 2020 10:21:38 -0700 Subject: [PATCH 34/45] zstd: [superblock] Add defensive assert and bounds check The bound check condition should always be met because we selected `set_basic` as our encoding type. But that code is very far away, so assert it is true so if it is ever false we can catch it, and add a bounds check. Port of facebook/zstd@1047097dadd5f8dfd47e25af0738eeb4bd82f6ec Reported-by: Coverity (CID 1524446) Reviewed-by: Damian Szuberski Reviewed-by: Brian Behlendorf Reviewed-by: Tino Reichardt Ported-by: Richard Yao Closes #14212 --- .../zstd/lib/compress/zstd_compress_superblock.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/module/zstd/lib/compress/zstd_compress_superblock.c b/module/zstd/lib/compress/zstd_compress_superblock.c index ffa4bb67597..77d05d394c3 100644 --- a/module/zstd/lib/compress/zstd_compress_superblock.c +++ b/module/zstd/lib/compress/zstd_compress_superblock.c @@ -603,7 +603,7 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type, const BYTE* codeTable, unsigned maxCode, size_t nbSeq, const FSE_CTable* fseCTable, const U32* additionalBits, - short const* defaultNorm, U32 defaultNormLog, + short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, void* workspace, size_t wkspSize) { unsigned* const countWksp = (unsigned*)workspace; @@ -615,7 +615,11 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type, HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */ if (type == set_basic) { - cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max); + /* We selected this encoding type, so it must be valid. */ + assert(max <= defaultMax); + cSymbolTypeSizeEstimateInBits = max <= defaultMax + ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max) + : ERROR(GENERIC); } else if (type == set_rle) { cSymbolTypeSizeEstimateInBits = 0; } else if (type == set_compressed || type == set_repeat) { @@ -643,15 +647,15 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable, size_t cSeqSizeEstimate = 0; cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff, nbSeq, fseTables->offcodeCTable, NULL, - OF_defaultNorm, OF_defaultNormLog, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, workspace, wkspSize); cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL, nbSeq, fseTables->litlengthCTable, LL_bits, - LL_defaultNorm, LL_defaultNormLog, + LL_defaultNorm, LL_defaultNormLog, MaxLL, workspace, wkspSize); cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML, nbSeq, fseTables->matchlengthCTable, ML_bits, - ML_defaultNorm, ML_defaultNormLog, + ML_defaultNorm, ML_defaultNormLog, MaxML, workspace, wkspSize); if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize; return cSeqSizeEstimate + sequencesSectionHeaderSize; @@ -809,7 +813,7 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr, if (sp < send) { seqDef const* seq; repcodes_t rep; - memcpy(&rep, prevCBlock->rep, sizeof(rep)); + memcpy(&rep, prevCBlock->rep, sizeof(rep)); for (seq = sstart; seq < sp; ++seq) { rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0); } From 776441152e9617244e527add7fcd6ccbe99fd4f5 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 18 Mar 2021 11:28:22 -0700 Subject: [PATCH 35/45] zstd: Refactor prefetching for the decoding loop Following facebook/zstd#2545, I noticed that one field in `seq_t` is optional, and only used in combination with prefetching. (This may have contributed to static analyzer failure to detect correct initialization). I then wondered if it would be possible to rewrite the code so that this optional part is handled directly by the prefetching code rather than delegated as an option into `ZSTD_decodeSequence()`. This resulted into this refactoring exercise where the prefetching responsibility is better isolated into its own function and `ZSTD_decodeSequence()` is streamlined to contain strictly Sequence decoding operations. Incidently, due to better code locality, it reduces the need to send information around, leading to simplified interface, and smaller state structures. Port of facebook/zstd@f5434663ea2a79b287ab4cd299179342f64a23a7 Reported-by: Coverity (CID 1462271) Reviewed-by: Damian Szuberski Reviewed-by: Brian Behlendorf Reviewed-by: Tino Reichardt Ported-by: Richard Yao Closes #14212 --- .../lib/decompress/zstd_decompress_block.c | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/module/zstd/lib/decompress/zstd_decompress_block.c b/module/zstd/lib/decompress/zstd_decompress_block.c index ad3b3d8dbd0..6f09e61b70c 100644 --- a/module/zstd/lib/decompress/zstd_decompress_block.c +++ b/module/zstd/lib/decompress/zstd_decompress_block.c @@ -554,7 +554,6 @@ typedef struct { size_t litLength; size_t matchLength; size_t offset; - const BYTE* match; } seq_t; typedef struct { @@ -568,9 +567,6 @@ typedef struct { ZSTD_fseState stateOffb; ZSTD_fseState stateML; size_t prevOffset[ZSTD_REP_NUM]; - const BYTE* prefixStart; - const BYTE* dictEnd; - size_t pos; } seqState_t; /*! ZSTD_overlapCopy8() : @@ -832,10 +828,9 @@ ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, ZSTD : 0) typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e; -typedef enum { ZSTD_p_noPrefetch=0, ZSTD_p_prefetch=1 } ZSTD_prefetch_e; FORCE_INLINE_TEMPLATE seq_t -ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const ZSTD_prefetch_e prefetch) +ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) { seq_t seq; ZSTD_seqSymbol const llDInfo = seqState->stateLL.table[seqState->stateLL.state]; @@ -910,14 +905,6 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); - if (prefetch == ZSTD_p_prefetch) { - size_t const pos = seqState->pos + seq.litLength; - const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart; - seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. - * No consequence though : no memory access will occur, offset is only used for prefetching */ - seqState->pos = pos + seq.matchLength; - } - /* ANS state update * gcc-9.0.0 does 2.5% worse with ZSTD_updateFseStateWithDInfo(). * clang-9.2.0 does 7% worse with ZSTD_updateFseState(). @@ -1072,7 +1059,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, __asm__(".p2align 4"); #endif for ( ; ; ) { - seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, ZSTD_p_noPrefetch); + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) assert(!ZSTD_isError(oneSeqSize)); @@ -1124,6 +1111,24 @@ ZSTD_decompressSequences_default(ZSTD_DCtx* dctx, #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT + +FORCE_INLINE_TEMPLATE size_t +ZSTD_prefetchMatch(size_t prefixPos, seq_t const sequence, + const BYTE* const prefixStart, const BYTE* const dictEnd) +{ + prefixPos += sequence.litLength; + { const BYTE* const matchBase = (sequence.offset > prefixPos) ? dictEnd : prefixStart; + const BYTE* const match = matchBase + prefixPos - sequence.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. + * No consequence though : no memory access will occur, offset is only used for prefetching */ + PREFETCH_L1(match); PREFETCH_L1(match + sequence.matchLength - 1); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */ + } + return prefixPos + sequence.matchLength; +} + +/* This decoding function employs prefetching + * to reduce latency impact of cache misses. + * It's generally employed when block contains a significant portion of long-distance matches + * or when coupled with a "cold" dictionary */ FORCE_INLINE_TEMPLATE size_t ZSTD_decompressSequencesLong_body( ZSTD_DCtx* dctx, @@ -1153,11 +1158,10 @@ ZSTD_decompressSequencesLong_body( int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); seqState_t seqState; int seqNb; + size_t prefixPos = (size_t)(op-prefixStart); /* track position relative to prefixStart */ + dctx->fseEntropy = 1; { int i; for (i=0; ientropy.rep[i]; } - seqState.prefixStart = prefixStart; - seqState.pos = (size_t)(op-prefixStart); - seqState.dictEnd = dictEnd; assert(dst != NULL); assert(iend >= ip); RETURN_ERROR_IF( @@ -1169,21 +1173,23 @@ ZSTD_decompressSequencesLong_body( /* prepare in advance */ for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb Date: Wed, 30 Nov 2022 10:25:57 -0800 Subject: [PATCH 36/45] Retire Ubuntu 18.04 CI builder The GitHub-hosted Ubuntu 18.04 has been deprecated and will be entirely unsupported as of April 2023. Leading up to this there will be scheduled "brownouts" to encourage users to update their workflows. This commit retires our use of the GitHub-hosted Ubuntu 18.04 runners in advance of their removal. Reviewed-by: Richard Yao Reviewed-by: George Melikov Reviewed-by: Damian Szuberski Signed-off-by: Brian Behlendorf Closes #14238 --- .github/workflows/zfs-tests-functional.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/zfs-tests-functional.yml b/.github/workflows/zfs-tests-functional.yml index 236bf599f68..69ca539b7bb 100644 --- a/.github/workflows/zfs-tests-functional.yml +++ b/.github/workflows/zfs-tests-functional.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - os: [18.04, 20.04, 22.04] + os: [20.04, 22.04] runs-on: ubuntu-${{ matrix.os }} steps: - uses: actions/checkout@v3 @@ -22,9 +22,6 @@ jobs: run: | sudo apt-get update sudo apt-get -qq upgrade - if [ "${{ matrix.os }}" = "18.04" ]; then - sed -i.bak 's/rng-tools-debian/rng-tools/' ${{ github.workspace }}/.github/workflows/build-dependencies.txt - fi sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq sudo apt-get clean - name: Autogen.sh From 3c1e1933b681cb68e0494c09d902e0187673ecc3 Mon Sep 17 00:00:00 2001 From: szubersk Date: Wed, 30 Nov 2022 20:27:28 +1000 Subject: [PATCH 37/45] Fix GCC 12 compilation errors Squelch false positives reported by GCC 12 with UBSan. Reviewed-by: Richard Yao Reviewed-by: Brian Behlendorf Signed-off-by: szubersk Closes #14150 --- cmd/zfs/zfs_main.c | 2 +- cmd/zpool/zpool_main.c | 2 +- config/always-compiler-options.m4 | 56 +++++++++++++++++++++++++++++++ config/zfs-build.m4 | 2 ++ lib/libnvpair/libnvpair.c | 15 +++++++++ lib/libzfs/libzfs_sendrecv.c | 30 +++++++++++++++++ module/icp/algs/blake3/blake3.c | 2 +- module/lua/ldo.c | 3 +- module/os/linux/zfs/zio_crypt.c | 17 ++++++++++ 9 files changed, 125 insertions(+), 4 deletions(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 2d644c5de16..03640a4cdce 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -548,7 +548,7 @@ usage(boolean_t requested) show_properties = B_TRUE; if (show_properties) { - (void) fprintf(fp, + (void) fprintf(fp, "%s", gettext("\nThe following properties are supported:\n")); (void) fprintf(fp, "\n\t%-14s %s %s %s\n\n", diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index 8a4f3dd1627..0b55bf21f44 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -548,7 +548,7 @@ usage(boolean_t requested) (strcmp(current_command->name, "get") == 0) || (strcmp(current_command->name, "list") == 0))) { - (void) fprintf(fp, + (void) fprintf(fp, "%s", gettext("\nthe following properties are supported:\n")); (void) fprintf(fp, "\n\t%-19s %s %s\n\n", diff --git a/config/always-compiler-options.m4 b/config/always-compiler-options.m4 index a6731969152..1e7ec3db9f6 100644 --- a/config/always-compiler-options.m4 +++ b/config/always-compiler-options.m4 @@ -227,6 +227,62 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_INFINITE_RECURSION], [ AC_SUBST([INFINITE_RECURSION]) ]) +dnl # +dnl # Check if kernel cc supports -Winfinite-recursion option. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_KERNEL_CC_INFINITE_RECURSION], [ + AC_MSG_CHECKING([whether $KERNEL_CC supports -Winfinite-recursion]) + + saved_cc="$CC" + saved_flags="$CFLAGS" + CC="gcc" + CFLAGS="$CFLAGS -Werror -Winfinite-recursion" + + AS_IF([ test -n "$KERNEL_CC" ], [ + CC="$KERNEL_CC" + ]) + AS_IF([ test -n "$KERNEL_LLVM" ], [ + CC="clang" + ]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + KERNEL_INFINITE_RECURSION=-Winfinite-recursion + AC_DEFINE([HAVE_KERNEL_INFINITE_RECURSION], 1, + [Define if compiler supports -Winfinite-recursion]) + AC_MSG_RESULT([yes]) + ], [ + KERNEL_INFINITE_RECURSION= + AC_MSG_RESULT([no]) + ]) + + CC="$saved_cc" + CFLAGS="$saved_flags" + AC_SUBST([KERNEL_INFINITE_RECURSION]) +]) + +dnl # +dnl # Check if cc supports -Wformat-overflow option. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_FORMAT_OVERFLOW], [ + AC_MSG_CHECKING([whether $CC supports -Wformat-overflow]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -Wformat-overflow" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + FORMAT_OVERFLOW=-Wformat-overflow + AC_DEFINE([HAVE_FORMAT_OVERFLOW], 1, + [Define if compiler supports -Wformat-overflow]) + AC_MSG_RESULT([yes]) + ], [ + FORMAT_OVERFLOW= + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([FORMAT_OVERFLOW]) +]) + dnl # dnl # Check if cc supports -fno-omit-frame-pointer option. dnl # diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 index d14a6bb7ac9..bb10bec0401 100644 --- a/config/zfs-build.m4 +++ b/config/zfs-build.m4 @@ -211,10 +211,12 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [ ZFS_AC_CONFIG_ALWAYS_CC_NO_CLOBBERED ZFS_AC_CONFIG_ALWAYS_CC_INFINITE_RECURSION + ZFS_AC_CONFIG_ALWAYS_KERNEL_CC_INFINITE_RECURSION ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH + ZFS_AC_CONFIG_ALWAYS_CC_FORMAT_OVERFLOW ZFS_AC_CONFIG_ALWAYS_CC_NO_OMIT_FRAME_POINTER ZFS_AC_CONFIG_ALWAYS_CC_NO_IPA_SRA ZFS_AC_CONFIG_ALWAYS_CC_ASAN diff --git a/lib/libnvpair/libnvpair.c b/lib/libnvpair/libnvpair.c index 48423226743..a75e7316739 100644 --- a/lib/libnvpair/libnvpair.c +++ b/lib/libnvpair/libnvpair.c @@ -199,6 +199,17 @@ nvprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \ return (1); \ } +/* + * Workaround for GCC 12+ with UBSan enabled deficencies. + * + * GCC 12+ invoked with -fsanitize=undefined incorrectly reports the code + * below as violating -Wformat-overflow. + */ +#if defined(__GNUC__) && !defined(__clang__) && \ + defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-overflow" +#endif NVLIST_PRTFUNC(boolean, int, int, "%d") NVLIST_PRTFUNC(boolean_value, boolean_t, int, "%d") NVLIST_PRTFUNC(byte, uchar_t, uchar_t, "0x%2.2x") @@ -213,6 +224,10 @@ NVLIST_PRTFUNC(uint64, uint64_t, u_longlong_t, "0x%llx") NVLIST_PRTFUNC(double, double, double, "0x%f") NVLIST_PRTFUNC(string, char *, char *, "%s") NVLIST_PRTFUNC(hrtime, hrtime_t, hrtime_t, "0x%llx") +#if defined(__GNUC__) && !defined(__clang__) && \ + defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW) +#pragma GCC diagnostic pop +#endif /* * Generate functions to print array-valued nvlist members. diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index 3e9f6377742..b53acdcea73 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -1007,8 +1007,23 @@ send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap, (void) fprintf(fout, dgettext(TEXT_DOMAIN, "incremental\t%s\t%s"), fromsnap, tosnap); } else { +/* + * Workaround for GCC 12+ with UBSan enabled deficencies. + * + * GCC 12+ invoked with -fsanitize=undefined incorrectly reports the code + * below as violating -Wformat-overflow. + */ +#if defined(__GNUC__) && !defined(__clang__) && \ + defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-overflow" +#endif (void) fprintf(fout, dgettext(TEXT_DOMAIN, "full\t%s"), tosnap); +#if defined(__GNUC__) && !defined(__clang__) && \ + defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW) +#pragma GCC diagnostic pop +#endif } (void) fprintf(fout, "\t%llu", (longlong_t)size); } else { @@ -1028,8 +1043,23 @@ send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap, if (size != 0) { char buf[16]; zfs_nicebytes(size, buf, sizeof (buf)); +/* + * Workaround for GCC 12+ with UBSan enabled deficencies. + * + * GCC 12+ invoked with -fsanitize=undefined incorrectly reports the code + * below as violating -Wformat-overflow. + */ +#if defined(__GNUC__) && !defined(__clang__) && \ + defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-overflow" +#endif (void) fprintf(fout, dgettext(TEXT_DOMAIN, " estimated size is %s"), buf); +#if defined(__GNUC__) && !defined(__clang__) && \ + defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW) +#pragma GCC diagnostic pop +#endif } } (void) fprintf(fout, "\n"); diff --git a/module/icp/algs/blake3/blake3.c b/module/icp/algs/blake3/blake3.c index 604e05847ee..8e441f454a7 100644 --- a/module/icp/algs/blake3/blake3.c +++ b/module/icp/algs/blake3/blake3.c @@ -276,7 +276,7 @@ static size_t compress_parents_parallel(const blake3_ops_t *ops, const uint8_t *child_chaining_values, size_t num_chaining_values, const uint32_t key[8], uint8_t flags, uint8_t *out) { - const uint8_t *parents_array[MAX_SIMD_DEGREE_OR_2]; + const uint8_t *parents_array[MAX_SIMD_DEGREE_OR_2] = {0}; size_t parents_array_len = 0; while (num_chaining_values - (2 * parents_array_len) >= 2) { diff --git a/module/lua/ldo.c b/module/lua/ldo.c index 6bef80514ce..e2a3d0279d7 100644 --- a/module/lua/ldo.c +++ b/module/lua/ldo.c @@ -170,7 +170,8 @@ static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { /* * Silence infinite recursion warning which was added to -Wall in gcc 12.1 */ -#if defined(HAVE_INFINITE_RECURSION) +#if defined(__GNUC__) && !defined(__clang__) && \ + defined(HAVE_KERNEL_INFINITE_RECURSION) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Winfinite-recursion" #endif diff --git a/module/os/linux/zfs/zio_crypt.c b/module/os/linux/zfs/zio_crypt.c index 6f2bf7ed756..a9043ae4dc7 100644 --- a/module/os/linux/zfs/zio_crypt.c +++ b/module/os/linux/zfs/zio_crypt.c @@ -229,7 +229,24 @@ zio_crypt_key_init(uint64_t crypt, zio_crypt_key_t *key) ASSERT(key != NULL); ASSERT3U(crypt, <, ZIO_CRYPT_FUNCTIONS); +/* + * Workaround for GCC 12+ with UBSan enabled deficencies. + * + * GCC 12+ invoked with -fsanitize=undefined incorrectly reports the code + * below as violating -Warray-bounds + */ +#if defined(__GNUC__) && !defined(__clang__) && \ + ((!defined(_KERNEL) && defined(ZFS_UBSAN_ENABLED)) || \ + defined(CONFIG_UBSAN)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif keydata_len = zio_crypt_table[crypt].ci_keylen; +#if defined(__GNUC__) && !defined(__clang__) && \ + ((!defined(_KERNEL) && defined(ZFS_UBSAN_ENABLED)) || \ + defined(CONFIG_UBSAN)) +#pragma GCC diagnostic pop +#endif memset(key, 0, sizeof (zio_crypt_key_t)); rw_init(&key->zk_salt_lock, NULL, RW_DEFAULT, NULL); From fe975048da29c4756bafd9f63a192db17e3acb7c Mon Sep 17 00:00:00 2001 From: szubersk Date: Wed, 30 Nov 2022 20:27:28 +1000 Subject: [PATCH 38/45] Fix Clang 15 compilation errors - Clang 15 doesn't support `-fno-ipa-sra` anymore. Do a separate check for `-fno-ipa-sra` support by $KERNEL_CC. - Don't enable `-mgeneral-regs-only` for certain module files. Fix #13260 - Scope `GCC diagnostic ignored` statements to GCC only. Clang doesn't need them to compile the code. Reviewed-by: Richard Yao Reviewed-by: Brian Behlendorf Signed-off-by: szubersk Closes #13260 Closes #14150 --- config/always-compiler-options.m4 | 31 +++++++++++++++++++++ config/zfs-build.m4 | 3 +- module/Kbuild.in | 6 ++++ module/icp/algs/edonr/edonr.c | 4 ++- module/icp/algs/skein/skein_block.c | 2 ++ module/lua/ldo.c | 3 +- module/os/linux/spl/spl-generic.c | 4 +++ module/zfs/vdev_raidz_math_aarch64_neonx2.c | 4 +++ 8 files changed, 54 insertions(+), 3 deletions(-) diff --git a/config/always-compiler-options.m4 b/config/always-compiler-options.m4 index 1e7ec3db9f6..6383b12506e 100644 --- a/config/always-compiler-options.m4 +++ b/config/always-compiler-options.m4 @@ -324,3 +324,34 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_IPA_SRA], [ CFLAGS="$saved_flags" AC_SUBST([NO_IPA_SRA]) ]) + +dnl # +dnl # Check if kernel cc supports -fno-ipa-sra option. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_KERNEL_CC_NO_IPA_SRA], [ + AC_MSG_CHECKING([whether $KERNEL_CC supports -fno-ipa-sra]) + + saved_cc="$CC" + saved_flags="$CFLAGS" + CC="gcc" + CFLAGS="$CFLAGS -Werror -fno-ipa-sra" + + AS_IF([ test -n "$KERNEL_CC" ], [ + CC="$KERNEL_CC" + ]) + AS_IF([ test -n "$KERNEL_LLVM" ], [ + CC="clang" + ]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + KERNEL_NO_IPA_SRA=-fno-ipa-sra + AC_MSG_RESULT([yes]) + ], [ + KERNEL_NO_IPA_SRA= + AC_MSG_RESULT([no]) + ]) + + CC="$saved_cc" + CFLAGS="$saved_flags" + AC_SUBST([KERNEL_NO_IPA_SRA]) +]) diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 index bb10bec0401..6355952487f 100644 --- a/config/zfs-build.m4 +++ b/config/zfs-build.m4 @@ -81,7 +81,7 @@ AC_DEFUN([ZFS_AC_DEBUG], [ AC_DEFUN([ZFS_AC_DEBUGINFO_ENABLE], [ DEBUG_CFLAGS="$DEBUG_CFLAGS -g -fno-inline $NO_IPA_SRA" - KERNEL_DEBUG_CFLAGS="$KERNEL_DEBUG_CFLAGS -fno-inline $NO_IPA_SRA" + KERNEL_DEBUG_CFLAGS="$KERNEL_DEBUG_CFLAGS -fno-inline $KERNEL_NO_IPA_SRA" KERNEL_MAKE="$KERNEL_MAKE CONFIG_DEBUG_INFO=y" DEBUGINFO_ZFS="_with_debuginfo" @@ -219,6 +219,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [ ZFS_AC_CONFIG_ALWAYS_CC_FORMAT_OVERFLOW ZFS_AC_CONFIG_ALWAYS_CC_NO_OMIT_FRAME_POINTER ZFS_AC_CONFIG_ALWAYS_CC_NO_IPA_SRA + ZFS_AC_CONFIG_ALWAYS_KERNEL_CC_NO_IPA_SRA ZFS_AC_CONFIG_ALWAYS_CC_ASAN ZFS_AC_CONFIG_ALWAYS_CC_UBSAN ZFS_AC_CONFIG_ALWAYS_TOOLCHAIN_SIMD diff --git a/module/Kbuild.in b/module/Kbuild.in index 581d50e64b4..a39f9d9d050 100644 --- a/module/Kbuild.in +++ b/module/Kbuild.in @@ -42,6 +42,12 @@ endif asflags-y := $(ZFS_MODULE_CFLAGS) $(ZFS_MODULE_CPPFLAGS) ccflags-y := $(ZFS_MODULE_CFLAGS) $(ZFS_MODULE_CPPFLAGS) +ifeq ($(CONFIG_ARM64),y) +CFLAGS_REMOVE_zcommon/zfs_fletcher_aarch64_neon.o += -mgeneral-regs-only +CFLAGS_REMOVE_zfs/vdev_raidz_math_aarch64_neon.o += -mgeneral-regs-only +CFLAGS_REMOVE_zfs/vdev_raidz_math_aarch64_neonx2.o += -mgeneral-regs-only +endif + # Suppress unused-value warnings in sparc64 architecture headers ccflags-$(CONFIG_SPARC64) += -Wno-unused-value diff --git a/module/icp/algs/edonr/edonr.c b/module/icp/algs/edonr/edonr.c index 345133d7433..b1f710cc043 100644 --- a/module/icp/algs/edonr/edonr.c +++ b/module/icp/algs/edonr/edonr.c @@ -346,9 +346,11 @@ Q256(size_t bitlen, const uint32_t *data, uint32_t *restrict p) * which only goes over it by a hair (1248 bytes on ARM32). */ #include /* for _ILP32 */ -#ifdef _ILP32 /* We're 32-bit, assume small stack frames */ +#if defined(_ILP32) /* We're 32-bit, assume small stack frames */ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic ignored "-Wframe-larger-than=" #endif +#endif #if defined(__IBMC__) && defined(_AIX) && defined(__64BIT__) static inline size_t diff --git a/module/icp/algs/skein/skein_block.c b/module/icp/algs/skein/skein_block.c index 7ba165a4851..3ad52da5f6a 100644 --- a/module/icp/algs/skein/skein_block.c +++ b/module/icp/algs/skein/skein_block.c @@ -30,7 +30,9 @@ * the #pragma here to ignore the warning. */ #if defined(_ILP32) || defined(__powerpc) /* Assume small stack */ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic ignored "-Wframe-larger-than=" +#endif /* * We're running on 32-bit, don't unroll loops to save stack frame space * diff --git a/module/lua/ldo.c b/module/lua/ldo.c index e2a3d0279d7..291bca044e7 100644 --- a/module/lua/ldo.c +++ b/module/lua/ldo.c @@ -197,7 +197,8 @@ l_noret luaD_throw (lua_State *L, int errcode) { } } -#if defined(HAVE_INFINITE_RECURSION) +#if defined(__GNUC__) && !defined(__clang__) && \ + defined(HAVE_INFINITE_RECURSION) #pragma GCC diagnostic pop #endif diff --git a/module/os/linux/spl/spl-generic.c b/module/os/linux/spl/spl-generic.c index 71eedf635f7..38515023e4b 100644 --- a/module/os/linux/spl/spl-generic.c +++ b/module/os/linux/spl/spl-generic.c @@ -254,8 +254,10 @@ __div_u64(uint64_t u, uint32_t v) * replacements for libgcc-provided functions and will never be called * directly. */ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmissing-prototypes" +#endif /* * Implementation of 64-bit unsigned division for 32-bit machines. @@ -449,7 +451,9 @@ __aeabi_ldivmod(int64_t u, int64_t v) EXPORT_SYMBOL(__aeabi_ldivmod); #endif /* __arm || __arm__ */ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop +#endif #endif /* BITS_PER_LONG */ diff --git a/module/zfs/vdev_raidz_math_aarch64_neonx2.c b/module/zfs/vdev_raidz_math_aarch64_neonx2.c index 0a1f05fd666..bd9de91a4ba 100644 --- a/module/zfs/vdev_raidz_math_aarch64_neonx2.c +++ b/module/zfs/vdev_raidz_math_aarch64_neonx2.c @@ -210,9 +210,13 @@ DEFINE_GEN_METHODS(aarch64_neonx2); * If compiled with -O0, gcc doesn't do any stack frame coalescing * and -Wframe-larger-than=1024 is triggered in debug mode. */ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic ignored "-Wframe-larger-than=" +#endif DEFINE_REC_METHODS(aarch64_neonx2); +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop +#endif static boolean_t raidz_will_aarch64_neonx2_work(void) From db6ba8d7443a234e497264a1da3d197d5ca32777 Mon Sep 17 00:00:00 2001 From: Xinliang Liu Date: Sat, 3 Dec 2022 09:39:48 +0800 Subject: [PATCH 39/45] autoconf: add support for openEuler Add config support for openEuler, so that it set the right sysconfig dir for openEuler. And DEFAULT_INIT_SCRIPT is no longer needed since commit "2a34db1bd Base init scripts for SYSV systems". Reviewed-by: George Melikov Reviewed-by: Richard Yao Reviewed-by: Brian Behlendorf Signed-off-by: Xinliang Liu Closes #14241 --- config/zfs-build.m4 | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 index 6355952487f..bb3c81a647f 100644 --- a/config/zfs-build.m4 +++ b/config/zfs-build.m4 @@ -532,6 +532,8 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [ VENDOR=alpine ; elif test -f /bin/freebsd-version ; then VENDOR=freebsd ; + elif test -f /etc/openEuler-release ; then + VENDOR=openeuler ; else VENDOR= ; fi], @@ -556,6 +558,7 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [ ubuntu) DEFAULT_PACKAGE=deb ;; debian) DEFAULT_PACKAGE=deb ;; freebsd) DEFAULT_PACKAGE=pkg ;; + openeuler) DEFAULT_PACKAGE=rpm ;; *) DEFAULT_PACKAGE=rpm ;; esac AC_MSG_RESULT([$DEFAULT_PACKAGE]) @@ -569,31 +572,14 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [ AC_MSG_RESULT([$initdir]) AC_SUBST(initdir) - AC_MSG_CHECKING([default init script type and shell]) - case "$VENDOR" in - toss) DEFAULT_INIT_SCRIPT=redhat ;; - redhat) DEFAULT_INIT_SCRIPT=redhat ;; - fedora) DEFAULT_INIT_SCRIPT=fedora ;; - gentoo) DEFAULT_INIT_SCRIPT=openrc ;; - alpine) DEFAULT_INIT_SCRIPT=openrc ;; - arch) DEFAULT_INIT_SCRIPT=lsb ;; - sles) DEFAULT_INIT_SCRIPT=lsb ;; - slackware) DEFAULT_INIT_SCRIPT=lsb ;; - lunar) DEFAULT_INIT_SCRIPT=lunar ;; - ubuntu) DEFAULT_INIT_SCRIPT=lsb ;; - debian) DEFAULT_INIT_SCRIPT=lsb ;; - freebsd) DEFAULT_INIT_SCRIPT=freebsd;; - *) DEFAULT_INIT_SCRIPT=lsb ;; - esac - + AC_MSG_CHECKING([default shell]) case "$VENDOR" in gentoo) DEFAULT_INIT_SHELL="/sbin/openrc-run";; alpine) DEFAULT_INIT_SHELL="/sbin/openrc-run";; *) DEFAULT_INIT_SHELL="/bin/sh" ;; esac - AC_MSG_RESULT([$DEFAULT_INIT_SCRIPT:$DEFAULT_INIT_SHELL]) - AC_SUBST(DEFAULT_INIT_SCRIPT) + AC_MSG_RESULT([$DEFAULT_INIT_SHELL]) AC_SUBST(DEFAULT_INIT_SHELL) AC_MSG_CHECKING([default nfs server init script]) @@ -612,6 +598,7 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [ redhat) initconfdir=/etc/sysconfig ;; fedora) initconfdir=/etc/sysconfig ;; sles) initconfdir=/etc/sysconfig ;; + openeuler) initconfdir=/etc/sysconfig ;; ubuntu) initconfdir=/etc/default ;; debian) initconfdir=/etc/default ;; freebsd) initconfdir=$sysconfdir/rc.conf.d;; From 7a75f74cec06a57b327b351ae4184400ff4e7cb2 Mon Sep 17 00:00:00 2001 From: Rob Wing Date: Mon, 14 Nov 2022 07:40:38 +0000 Subject: [PATCH 40/45] Bump checksum error counter before reporting to ZED The checksum error counter is incremented after reporting to ZED. This leads ZED to receiving a checksum error report with 0 checksum errors. To avoid this, bump the checksum error counter before reporting to ZED. Sponsored-by: Seagate Technology LLC Reviewed-by: Richard Yao Reviewed-by: Brian Behlendorf Signed-off-by: Rob Wing Closes #14190 --- module/zfs/vdev_indirect.c | 6 +++--- module/zfs/vdev_raidz.c | 12 ++++++------ module/zfs/zio.c | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/module/zfs/vdev_indirect.c b/module/zfs/vdev_indirect.c index 814a1f0efe4..b70e8edfafd 100644 --- a/module/zfs/vdev_indirect.c +++ b/module/zfs/vdev_indirect.c @@ -1479,12 +1479,12 @@ vdev_indirect_all_checksum_errors(zio_t *zio) vdev_t *vd = ic->ic_vdev; - (void) zfs_ereport_post_checksum(zio->io_spa, vd, - NULL, zio, is->is_target_offset, is->is_size, - NULL, NULL, NULL); mutex_enter(&vd->vdev_stat_lock); vd->vdev_stat.vs_checksum_errors++; mutex_exit(&vd->vdev_stat_lock); + (void) zfs_ereport_post_checksum(zio->io_spa, vd, + NULL, zio, is->is_target_offset, is->is_size, + NULL, NULL, NULL); } } } diff --git a/module/zfs/vdev_raidz.c b/module/zfs/vdev_raidz.c index 5a44983e551..14b98a76b84 100644 --- a/module/zfs/vdev_raidz.c +++ b/module/zfs/vdev_raidz.c @@ -1769,12 +1769,12 @@ vdev_raidz_checksum_error(zio_t *zio, raidz_col_t *rc, abd_t *bad_data) zbc.zbc_has_cksum = 0; zbc.zbc_injected = rm->rm_ecksuminjected; - (void) zfs_ereport_post_checksum(zio->io_spa, vd, - &zio->io_bookmark, zio, rc->rc_offset, rc->rc_size, - rc->rc_abd, bad_data, &zbc); mutex_enter(&vd->vdev_stat_lock); vd->vdev_stat.vs_checksum_errors++; mutex_exit(&vd->vdev_stat_lock); + (void) zfs_ereport_post_checksum(zio->io_spa, vd, + &zio->io_bookmark, zio, rc->rc_offset, rc->rc_size, + rc->rc_abd, bad_data, &zbc); } } @@ -2380,12 +2380,12 @@ vdev_raidz_io_done_unrecoverable(zio_t *zio) zbc.zbc_has_cksum = 0; zbc.zbc_injected = rm->rm_ecksuminjected; - (void) zfs_ereport_start_checksum(zio->io_spa, - cvd, &zio->io_bookmark, zio, rc->rc_offset, - rc->rc_size, &zbc); mutex_enter(&cvd->vdev_stat_lock); cvd->vdev_stat.vs_checksum_errors++; mutex_exit(&cvd->vdev_stat_lock); + (void) zfs_ereport_start_checksum(zio->io_spa, + cvd, &zio->io_bookmark, zio, rc->rc_offset, + rc->rc_size, &zbc); } } } diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 928e2881393..46904b800b7 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -4311,12 +4311,12 @@ zio_checksum_verify(zio_t *zio) zio->io_error = error; if (error == ECKSUM && !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { - (void) zfs_ereport_start_checksum(zio->io_spa, - zio->io_vd, &zio->io_bookmark, zio, - zio->io_offset, zio->io_size, &info); mutex_enter(&zio->io_vd->vdev_stat_lock); zio->io_vd->vdev_stat.vs_checksum_errors++; mutex_exit(&zio->io_vd->vdev_stat_lock); + (void) zfs_ereport_start_checksum(zio->io_spa, + zio->io_vd, &zio->io_bookmark, zio, + zio->io_offset, zio->io_size, &info); } } From 2c590bdede78c5aca10c0cf4284b59c006f4a30d Mon Sep 17 00:00:00 2001 From: Rob Wing Date: Mon, 14 Nov 2022 07:57:53 +0000 Subject: [PATCH 41/45] ZTS: test reported checksum errors for ZED Test checksum error reporting to ZED via the call paths vdev_raidz_io_done_unrecoverable() and zio_checksum_verify(). Sponsored-by: Seagate Technology LLC Reviewed-by: Richard Yao Reviewed-by: Brian Behlendorf Signed-off-by: Rob Wing Closes #14190 --- tests/runfiles/linux.run | 3 +- tests/zfs-tests/tests/Makefile.am | 1 + .../functional/events/zed_cksum_reported.ksh | 124 ++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100755 tests/zfs-tests/tests/functional/events/zed_cksum_reported.ksh diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run index 52e824a888f..23292a4889a 100644 --- a/tests/runfiles/linux.run +++ b/tests/runfiles/linux.run @@ -86,7 +86,8 @@ tests = ['devices_001_pos', 'devices_002_neg', 'devices_003_pos'] tags = ['functional', 'devices'] [tests/functional/events:Linux] -tests = ['events_001_pos', 'events_002_pos', 'zed_rc_filter', 'zed_fd_spill'] +tests = ['events_001_pos', 'events_002_pos', 'zed_rc_filter', 'zed_fd_spill', + 'zed_cksum_reported'] tags = ['functional', 'events'] [tests/functional/fadvise:Linux] diff --git a/tests/zfs-tests/tests/Makefile.am b/tests/zfs-tests/tests/Makefile.am index c7aa4c7b89f..144a848cf3f 100644 --- a/tests/zfs-tests/tests/Makefile.am +++ b/tests/zfs-tests/tests/Makefile.am @@ -1367,6 +1367,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \ functional/events/events_001_pos.ksh \ functional/events/events_002_pos.ksh \ functional/events/setup.ksh \ + functional/events/zed_cksum_reported.ksh \ functional/events/zed_fd_spill.ksh \ functional/events/zed_rc_filter.ksh \ functional/exec/cleanup.ksh \ diff --git a/tests/zfs-tests/tests/functional/events/zed_cksum_reported.ksh b/tests/zfs-tests/tests/functional/events/zed_cksum_reported.ksh new file mode 100755 index 00000000000..78acd76c2ee --- /dev/null +++ b/tests/zfs-tests/tests/functional/events/zed_cksum_reported.ksh @@ -0,0 +1,124 @@ +#!/bin/ksh -p +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2022, Klara Inc. +# +# This software was developed by Rob Wing +# under sponsorship from Seagate Technology LLC and Klara Inc. + +# DESCRIPTION: +# Verify that checksum errors are accurately reported to ZED +# +# STRATEGY: +# 1. Create a mirrored/raidz pool +# 2. Inject checksum error +# 3. Verify checksum error count reported to ZED is not zero +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/events/events_common.kshlib + +verify_runnable "both" + +MOUNTDIR="$TEST_BASE_DIR/checksum_mount" +FILEPATH="$MOUNTDIR/checksum_file" +VDEV="$TEST_BASE_DIR/vdevfile.$$" +VDEV1="$TEST_BASE_DIR/vdevfile1.$$" +POOL="checksum_pool" +FILESIZE="10M" + +function cleanup +{ + log_must zed_stop + + log_must zinject -c all + if poolexists $POOL ; then + destroy_pool $POOL + fi + log_must rm -fd $VDEV $MOUNTDIR +} +log_onexit cleanup + +log_assert "Test reported checksum errors to ZED" + +function setup_pool +{ + type="$1" + + log_must zpool create -f -m $MOUNTDIR $POOL $type $VDEV $VDEV1 + log_must zpool events -c + log_must truncate -s 0 $ZED_DEBUG_LOG + log_must zfs set compression=off $POOL + log_must zfs set primarycache=none $POOL +} + +function do_clean +{ + log_must zinject -c all + log_must zpool destroy $POOL +} + +function do_checksum_error +{ + log_must mkfile $FILESIZE $FILEPATH + log_must zinject -a -t data -e checksum -T read -f 100 $FILEPATH + + dd if=$FILEPATH of=/dev/null bs=1 count=1 2>/dev/null + + log_must file_wait_event $ZED_DEBUG_LOG "ereport.fs.zfs.checksum" 10 + + # checksum error as reported from the vdev. + zpool_cksum=`zpool get -H -o value checksum_errors $POOL $VDEV` + + # first checksum error reported to ZED. + zed_cksum=$(awk '/ZEVENT_CLASS=ereport.fs.zfs.checksum/, \ + /ZEVENT_VDEV_CKSUM_ERRORS=/ { \ + if ($1 ~ "ZEVENT_VDEV_CKSUM_ERRORS") \ + { print $0; exit } }' $ZED_DEBUG_LOG) + + log_must [ $zpool_cksum -gt 0 ] + + log_mustnot [ "$zed_cksum" = "ZEVENT_VDEV_CKSUM_ERRORS=0" ] + + log_must [ "$zed_cksum" = "ZEVENT_VDEV_CKSUM_ERRORS=1" ] +} + +# Set checksum_n=1 +# fire 1 event, should degrade. +function checksum_error +{ + type=$1 + + setup_pool $type + do_checksum_error + do_clean +} + +log_must truncate -s $MINVDEVSIZE $VDEV +log_must truncate -s $MINVDEVSIZE $VDEV1 +log_must mkdir -p $MOUNTDIR + +log_must zed_start +checksum_error mirror +checksum_error raidz + +log_pass "Test reported checksum errors to ZED" From d7cf06a25d296a764c8548a02d96c3848e1f2141 Mon Sep 17 00:00:00 2001 From: George Wilson Date: Fri, 2 Dec 2022 19:45:33 -0600 Subject: [PATCH 42/45] nopwrites on dmu_sync-ed blocks can result in a panic After a device has been removed, any nopwrites for blocks on that indirect vdev should be ignored and a new block should be allocated. The original code attempted to handle this but used the wrong block pointer when checking for indirect vdevs and failed to check all DVAs. This change corrects both of these issues and modifies the test case to ensure that it properly tests nopwrites with device removal. Reviewed-by: Prakash Surya Reviewed-by: Matthew Ahrens Reviewed-by: Richard Yao Reviewed-by: Brian Behlendorf Signed-off-by: George Wilson Closes #14235 --- module/zfs/zio.c | 18 ++++---- .../tests/functional/nopwrite/nopwrite.shlib | 8 ++-- .../functional/removal/removal_nopwrite.ksh | 45 +++++++++++++++++-- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 46904b800b7..2ae42e2df4b 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2020 by Delphix. All rights reserved. + * Copyright (c) 2011, 2022 by Delphix. All rights reserved. * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2017, Intel Corporation. * Copyright (c) 2019, Klara Inc. @@ -2974,6 +2974,7 @@ zio_nop_write(zio_t *zio) blkptr_t *bp_orig = &zio->io_bp_orig; zio_prop_t *zp = &zio->io_prop; + ASSERT(BP_IS_HOLE(bp)); ASSERT(BP_GET_LEVEL(bp) == 0); ASSERT(!(zio->io_flags & ZIO_FLAG_IO_REWRITE)); ASSERT(zp->zp_nopwrite); @@ -3007,8 +3008,7 @@ zio_nop_write(zio_t *zio) ASSERT3U(BP_GET_PSIZE(bp), ==, BP_GET_PSIZE(bp_orig)); ASSERT3U(BP_GET_LSIZE(bp), ==, BP_GET_LSIZE(bp_orig)); ASSERT(zp->zp_compress != ZIO_COMPRESS_OFF); - ASSERT(memcmp(&bp->blk_prop, &bp_orig->blk_prop, - sizeof (uint64_t)) == 0); + ASSERT3U(bp->blk_prop, ==, bp_orig->blk_prop); /* * If we're overwriting a block that is currently on an @@ -3016,11 +3016,13 @@ zio_nop_write(zio_t *zio) * allow a new block to be allocated on a concrete vdev. */ spa_config_enter(zio->io_spa, SCL_VDEV, FTAG, RW_READER); - vdev_t *tvd = vdev_lookup_top(zio->io_spa, - DVA_GET_VDEV(&bp->blk_dva[0])); - if (tvd->vdev_ops == &vdev_indirect_ops) { - spa_config_exit(zio->io_spa, SCL_VDEV, FTAG); - return (zio); + for (int d = 0; d < BP_GET_NDVAS(bp_orig); d++) { + vdev_t *tvd = vdev_lookup_top(zio->io_spa, + DVA_GET_VDEV(&bp_orig->blk_dva[d])); + if (tvd->vdev_ops == &vdev_indirect_ops) { + spa_config_exit(zio->io_spa, SCL_VDEV, FTAG); + return (zio); + } } spa_config_exit(zio->io_spa, SCL_VDEV, FTAG); diff --git a/tests/zfs-tests/tests/functional/nopwrite/nopwrite.shlib b/tests/zfs-tests/tests/functional/nopwrite/nopwrite.shlib index 139b4b26e5e..a6d1eb2c769 100644 --- a/tests/zfs-tests/tests/functional/nopwrite/nopwrite.shlib +++ b/tests/zfs-tests/tests/functional/nopwrite/nopwrite.shlib @@ -57,12 +57,12 @@ function verify_nopwrite within_percent $origin_used $snap_refer $high || return 1 # - # The comparisons below should pass regardless of nopwrite. They're - # here for sanity. + # The comparisons below should be within 90% regardless of nopwrite. + # They're here for sanity. # typeset deadlist=$(zdb -Pddd $clone | awk '/Deadlist:/ {print $2}') - within_percent $deadlist $clone_written $high || return 1 - within_percent $snap_refer $snap_written $high || return 1 + within_percent $deadlist $clone_written 90 || return 1 + within_percent $snap_refer $snap_written 90 || return 1 return 0 } diff --git a/tests/zfs-tests/tests/functional/removal/removal_nopwrite.ksh b/tests/zfs-tests/tests/functional/removal/removal_nopwrite.ksh index cede81ad60c..3533c41cac2 100755 --- a/tests/zfs-tests/tests/functional/removal/removal_nopwrite.ksh +++ b/tests/zfs-tests/tests/functional/removal/removal_nopwrite.ksh @@ -15,7 +15,7 @@ # # -# Copyright (c) 2019 by Delphix. All rights reserved. +# Copyright (c) 2019, 2022 by Delphix. All rights reserved. # . $STF_SUITE/include/libtest.shlib @@ -24,19 +24,35 @@ default_setup_noexit "$DISKS" log_onexit default_cleanup_noexit -BLOCKSIZE=8192 + +# +# Randomly pick a device to remove +# +DISK_TOKENS=( $DISKS ) +DISK_INDEX_TO_REMOVE=$((RANDOM%${#DISK_TOKENS[@]})) +DISK_TO_REMOVE=${DISK_TOKENS[${DISK_INDEX_TO_REMOVE}]} origin="$TESTPOOL/$TESTFS" log_must zfs set compress=on $origin log_must zfs set checksum=skein $origin +log_must zfs set copies=1 $origin log_must zfs set recordsize=8k $origin dd if=/dev/urandom of=$TESTDIR/file_8k bs=1024k count=$MEGS oflag=sync \ conv=notrunc >/dev/null 2>&1 || log_fail "dd into $TESTDIR/file failed." +log_must zfs set copies=3 $origin +dd if=/dev/urandom of=$TESTDIR/file_8k_copies bs=1024k count=$MEGS oflag=sync \ + conv=notrunc >/dev/null 2>&1 || log_fail "dd into $TESTDIR/file failed." + +log_must zfs set copies=1 $origin log_must zfs set recordsize=128k $origin dd if=/dev/urandom of=$TESTDIR/file_128k bs=1024k count=$MEGS oflag=sync \ conv=notrunc >/dev/null 2>&1 || log_fail "dd into $TESTDIR/file failed." +log_must zfs set copies=3 $origin +dd if=/dev/urandom of=$TESTDIR/file_128k_copies bs=1024k \ + count=$MEGS oflag=sync conv=notrunc >/dev/null 2>&1 || \ + log_fail "dd into $TESTDIR/file failed." zfs snapshot $origin@a || log_fail "zfs snap failed" log_must zfs clone $origin@a $origin/clone @@ -44,22 +60,33 @@ log_must zfs clone $origin@a $origin/clone # # Verify that nopwrites work prior to removal # +log_must zfs set copies=1 $origin/clone log_must zfs set recordsize=8k $origin/clone dd if=/$TESTDIR/file_8k of=/$TESTDIR/clone/file_8k bs=1024k \ oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed." log_must verify_nopwrite $origin $origin@a $origin/clone +log_must zfs set copies=3 $origin/clone +dd if=/$TESTDIR/file_8k_copies of=/$TESTDIR/clone/file_8k_copies bs=1024k \ + oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed." +log_must verify_nopwrite $origin $origin@a $origin/clone +log_must zfs set copies=1 $origin/clone log_must zfs set recordsize=128k $origin/clone dd if=/$TESTDIR/file_128k of=/$TESTDIR/clone/file_128k bs=1024k \ oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed." log_must verify_nopwrite $origin $origin@a $origin/clone +log_must zfs set copies=3 $origin/clone +dd if=/$TESTDIR/file_128k_copies of=/$TESTDIR/clone/file_128k_copies bs=1024k \ + oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed." +log_must verify_nopwrite $origin $origin@a $origin/clone # # Remove a device before testing nopwrites again # -log_must zpool remove $TESTPOOL $REMOVEDISK +log_note "Removing: $DISK_TO_REMOVE" +log_must zpool remove $TESTPOOL $DISK_TO_REMOVE log_must wait_for_removal $TESTPOOL -log_mustnot vdevs_in_pool $TESTPOOL $REMOVEDISK +log_mustnot vdevs_in_pool $TESTPOOL $DISK_TO_REMOVE # # Normally, we expect nopwrites to avoid allocating new blocks, but @@ -71,17 +98,27 @@ log_mustnot vdevs_in_pool $TESTPOOL $REMOVEDISK # # Perform a direct zil nopwrite test # +log_must zfs set copies=1 $origin/clone log_must zfs set recordsize=8k $origin/clone dd if=/$TESTDIR/file_8k of=/$TESTDIR/clone/file_8k bs=1024k \ oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed." log_mustnot verify_nopwrite $origin $origin@a $origin/clone +log_must zfs set copies=3 $origin/clone +dd if=/$TESTDIR/file_8k_copies of=/$TESTDIR/clone/file_8k_copies bs=1024k \ + oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed." +log_mustnot verify_nopwrite $origin $origin@a $origin/clone # # Perform an indirect zil nopwrite test # +log_must zfs set copies=1 $origin/clone log_must zfs set recordsize=128k $origin/clone dd if=/$TESTDIR/file_128k of=/$TESTDIR/clone/file_128k bs=1024k \ oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed." log_mustnot verify_nopwrite $origin $origin@a $origin/clone +log_must zfs set copies=3 $origin/clone +dd if=/$TESTDIR/file_128k_copies of=/$TESTDIR/clone/file_128k_copies bs=1024k \ + oflag=sync conv=notrunc >/dev/null 2>&1 || log_fail "dd failed." +log_mustnot verify_nopwrite $origin $origin@a $origin/clone log_pass "Remove works with nopwrite." From ffd2e15d656e47f8d82ffbe46af1f0899ff889e5 Mon Sep 17 00:00:00 2001 From: George Wilson Date: Fri, 2 Dec 2022 19:46:29 -0600 Subject: [PATCH 43/45] zio can deadlock during device removal When doing a device removal on a pool with gang blocks, the zio pipeline can deadlock when trying to free blocks from a device which is being removed with a stack similar to this: 0xffff8ab9a13a1740 UNINTERRUPTIBLE 4 __schedule+0x2e5 __schedule+0x2e5 schedule+0x33 schedule_preempt_disabled+0xe __mutex_lock.isra.12+0x2a7 __mutex_lock.isra.12+0x2a7 __mutex_lock_slowpath+0x13 mutex_lock+0x2c free_from_removing_vdev+0x61 metaslab_free_impl+0xd6 metaslab_free_dva+0x5e metaslab_free+0x196 zio_free_sync+0xe4 zio_free_gang+0x38 zio_gang_tree_issue+0x42 zio_gang_tree_issue+0xa2 zio_gang_issue+0x6d zio_execute+0x94 zio_execute+0x94 taskq_thread+0x23b kthread+0x120 ret_from_fork+0x1f Since there are gang blocks we have to read the gang members as part of the free. This can be seen with a zio dependency tree that looks like this: sdb> echo 0xffff900c24f8a700 | zio -rc | zio ADDRESS TYPE STAGE WAITER 0xffff900c24f8a700 NULL CHECKSUM_VERIFY 0xffff900ddfd31740 0xffff900c24f8c920 FREE GANG_ASSEMBLE - 0xffff900d93d435a0 READ DONE In the illustration above we are processing frees but because of gang block we have to read the constituents blocks. Once we finish the READ in the zio pipeline we will execute the parent. In this case the parent is a FREE but the zio taskq is a READ and we continue to process the pipeline leading to the stack above. In the stack above, we are blocked waiting for the svr_lock so as a result a READ interrupt taskq thread is now consumed. Eventually, all of the READ taskq threads end up blocked and we're unable to complete any read requests. In zio_notify_parent there is an optimization to continue to use the taskq thread to exectue the parent's pipeline. To resolve the deadlock above, we only allow this optimization if the parent's zio type matches the child which just completed. Reviewed-by: Brian Behlendorf Reviewed-by: Matthew Ahrens Signed-off-by: George Wilson External-issue: DLPX-80130 Closes #14236 --- module/zfs/zio.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 2ae42e2df4b..9ae2458669f 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -724,7 +724,9 @@ zio_notify_parent(zio_t *pio, zio_t *zio, enum zio_wait_type wait, /* * If we can tell the caller to execute this parent next, do - * so. Otherwise dispatch the parent zio as its own task. + * so. We only do this if the parent's zio type matches the + * child's type. Otherwise dispatch the parent zio in its + * own taskq. * * Having the caller execute the parent when possible reduces * locking on the zio taskq's, reduces context switch @@ -743,7 +745,8 @@ zio_notify_parent(zio_t *pio, zio_t *zio, enum zio_wait_type wait, * parent-child relationships, as we do with the "mega zio" * of writes for spa_sync(), and the chain of ZIL blocks. */ - if (next_to_executep != NULL && *next_to_executep == NULL) { + if (next_to_executep != NULL && *next_to_executep == NULL && + pio->io_type == zio->io_type) { *next_to_executep = pio; } else { zio_taskq_dispatch(pio, type, B_FALSE); From 7b9a423076f4da36b68009ced22259cd243166f6 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Mon, 5 Dec 2022 13:16:50 -0500 Subject: [PATCH 44/45] FreeBSD: zfs_register_callbacks() must implement error check correctly I read the following article and noticed a couple of ZFS bugs mentioned: https://pvs-studio.com/en/blog/posts/cpp/0377/ I decided to search for them in the modern OpenZFS codebase and then found one that matched the description of the first one: V593 Consider reviewing the expression of the 'A = B != C' kind. The expression is calculated as following: 'A = (B != C)'. zfs_vfsops.c 498 The consequence of this is that the error value is replaced with `1` when there is an error. When there is no error, 0 is correctly passed. This is a very minor issue that is unlikely to cause any real problems. The incorrect error code would either be returned to the mount command on a failure or any of `zfs receive`, `zfs recv`, `zfs rollback` or `zfs upgrade`. The second one has already been fixed. Reviewed-by: Alexander Motin Reviewed-by: Damian Szuberski Signed-off-by: Richard Yao Closes #14261 --- module/os/freebsd/zfs/zfs_vfsops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/os/freebsd/zfs/zfs_vfsops.c b/module/os/freebsd/zfs/zfs_vfsops.c index 1063e6f7596..2820f10b5de 100644 --- a/module/os/freebsd/zfs/zfs_vfsops.c +++ b/module/os/freebsd/zfs/zfs_vfsops.c @@ -721,7 +721,7 @@ zfs_register_callbacks(vfs_t *vfsp) nbmand = B_FALSE; } else if (vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL)) { nbmand = B_TRUE; - } else if ((error = dsl_prop_get_int_ds(ds, "nbmand", &nbmand) != 0)) { + } else if ((error = dsl_prop_get_int_ds(ds, "nbmand", &nbmand)) != 0) { dsl_pool_config_exit(dmu_objset_pool(os), FTAG); return (error); } From 59493b63c18ea223857066218d6a58b67eb88159 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Mon, 5 Dec 2022 14:00:34 -0500 Subject: [PATCH 45/45] Micro-optimize fletcher4 calculations When processing abds, we execute 1 `kfpu_begin()`/`kfpu_end()` pair on every page in the abd. This is wasteful and slows down checksum performance versus what the benchmark claimed. We correct this by moving those calls to the init and fini functions. Also, we always check the buffer length against 0 before calling the non-scalar checksum functions. This means that we do not need to execute the loop condition for the first loop iteration. That allows us to micro-optimize the checksum calculations by switching to do-while loops. Note that we do not apply that micro-optimization to the scalar implementation because there is no check in `fletcher_4_incremental_native()`/`fletcher_4_incremental_byteswap()` against 0 sized buffers being passed. Reviewed-by: Alexander Motin Reviewed-by: Brian Behlendorf Signed-off-by: Richard Yao Closes #14247 --- module/zcommon/zfs_fletcher_aarch64_neon.c | 18 +++++---------- module/zcommon/zfs_fletcher_avx512.c | 26 +++++++--------------- module/zcommon/zfs_fletcher_intel.c | 18 +++++---------- module/zcommon/zfs_fletcher_sse.c | 26 +++++++--------------- module/zcommon/zfs_fletcher_superscalar.c | 8 +++---- module/zcommon/zfs_fletcher_superscalar4.c | 8 +++---- 6 files changed, 36 insertions(+), 68 deletions(-) diff --git a/module/zcommon/zfs_fletcher_aarch64_neon.c b/module/zcommon/zfs_fletcher_aarch64_neon.c index 3e14875d6c8..8f033972886 100644 --- a/module/zcommon/zfs_fletcher_aarch64_neon.c +++ b/module/zcommon/zfs_fletcher_aarch64_neon.c @@ -52,6 +52,7 @@ ZFS_NO_SANITIZE_UNDEFINED static void fletcher_4_aarch64_neon_init(fletcher_4_ctx_t *ctx) { + kfpu_begin(); memset(ctx->aarch64_neon, 0, 4 * sizeof (zfs_fletcher_aarch64_neon_t)); } @@ -69,6 +70,7 @@ fletcher_4_aarch64_neon_fini(fletcher_4_ctx_t *ctx, zio_cksum_t *zcp) 8 * ctx->aarch64_neon[3].v[1] - 8 * ctx->aarch64_neon[2].v[1] + ctx->aarch64_neon[1].v[1]; ZIO_SET_CHECKSUM(zcp, A, B, C, D); + kfpu_end(); } #define NEON_INIT_LOOP() \ @@ -146,17 +148,13 @@ unsigned char TMP2 __attribute__((vector_size(16))); unsigned char SRC __attribute__((vector_size(16))); #endif - kfpu_begin(); - NEON_INIT_LOOP(); - for (; ip < ipend; ip += 2) { + do { NEON_MAIN_LOOP(NEON_DONT_REVERSE); - } + } while ((ip += 2) < ipend); NEON_FINI_LOOP(); - - kfpu_end(); } static void @@ -185,17 +183,13 @@ unsigned char TMP2 __attribute__((vector_size(16))); unsigned char SRC __attribute__((vector_size(16))); #endif - kfpu_begin(); - NEON_INIT_LOOP(); - for (; ip < ipend; ip += 2) { + do { NEON_MAIN_LOOP(NEON_DO_REVERSE); - } + } while ((ip += 2) < ipend); NEON_FINI_LOOP(); - - kfpu_end(); } static boolean_t fletcher_4_aarch64_neon_valid(void) diff --git a/module/zcommon/zfs_fletcher_avx512.c b/module/zcommon/zfs_fletcher_avx512.c index 20c38d7e779..4a3d5cb24ab 100644 --- a/module/zcommon/zfs_fletcher_avx512.c +++ b/module/zcommon/zfs_fletcher_avx512.c @@ -39,6 +39,7 @@ ZFS_NO_SANITIZE_UNDEFINED static void fletcher_4_avx512f_init(fletcher_4_ctx_t *ctx) { + kfpu_begin(); memset(ctx->avx512, 0, 4 * sizeof (zfs_fletcher_avx512_t)); } @@ -72,6 +73,7 @@ fletcher_4_avx512f_fini(fletcher_4_ctx_t *ctx, zio_cksum_t *zcp) } ZIO_SET_CHECKSUM(zcp, A, B, C, D); + kfpu_end(); } #define FLETCHER_4_AVX512_RESTORE_CTX(ctx) \ @@ -96,21 +98,17 @@ fletcher_4_avx512f_native(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) const uint32_t *ip = buf; const uint32_t *ipend = (uint32_t *)((uint8_t *)ip + size); - kfpu_begin(); - FLETCHER_4_AVX512_RESTORE_CTX(ctx); - for (; ip < ipend; ip += 8) { + do { __asm("vpmovzxdq %0, %%zmm4"::"m" (*ip)); __asm("vpaddq %zmm4, %zmm0, %zmm0"); __asm("vpaddq %zmm0, %zmm1, %zmm1"); __asm("vpaddq %zmm1, %zmm2, %zmm2"); __asm("vpaddq %zmm2, %zmm3, %zmm3"); - } + } while ((ip += 8) < ipend); FLETCHER_4_AVX512_SAVE_CTX(ctx); - - kfpu_end(); } STACK_FRAME_NON_STANDARD(fletcher_4_avx512f_native); @@ -122,8 +120,6 @@ fletcher_4_avx512f_byteswap(fletcher_4_ctx_t *ctx, const void *buf, const uint32_t *ip = buf; const uint32_t *ipend = (uint32_t *)((uint8_t *)ip + size); - kfpu_begin(); - FLETCHER_4_AVX512_RESTORE_CTX(ctx); __asm("vpbroadcastq %0, %%zmm8" :: "r" (byteswap_mask)); @@ -131,7 +127,7 @@ fletcher_4_avx512f_byteswap(fletcher_4_ctx_t *ctx, const void *buf, __asm("vpsllq $16, %zmm8, %zmm10"); __asm("vpsllq $24, %zmm8, %zmm11"); - for (; ip < ipend; ip += 8) { + do { __asm("vpmovzxdq %0, %%zmm5"::"m" (*ip)); __asm("vpsrlq $24, %zmm5, %zmm6"); @@ -150,11 +146,9 @@ fletcher_4_avx512f_byteswap(fletcher_4_ctx_t *ctx, const void *buf, __asm("vpaddq %zmm0, %zmm1, %zmm1"); __asm("vpaddq %zmm1, %zmm2, %zmm2"); __asm("vpaddq %zmm2, %zmm3, %zmm3"); - } + } while ((ip += 8) < ipend); FLETCHER_4_AVX512_SAVE_CTX(ctx) - - kfpu_end(); } STACK_FRAME_NON_STANDARD(fletcher_4_avx512f_byteswap); @@ -189,13 +183,11 @@ fletcher_4_avx512bw_byteswap(fletcher_4_ctx_t *ctx, const void *buf, const uint32_t *ip = buf; const uint32_t *ipend = (uint32_t *)((uint8_t *)ip + size); - kfpu_begin(); - FLETCHER_4_AVX512_RESTORE_CTX(ctx); __asm("vmovdqu64 %0, %%zmm5" :: "m" (mask)); - for (; ip < ipend; ip += 8) { + do { __asm("vpmovzxdq %0, %%zmm4"::"m" (*ip)); __asm("vpshufb %zmm5, %zmm4, %zmm4"); @@ -204,11 +196,9 @@ fletcher_4_avx512bw_byteswap(fletcher_4_ctx_t *ctx, const void *buf, __asm("vpaddq %zmm0, %zmm1, %zmm1"); __asm("vpaddq %zmm1, %zmm2, %zmm2"); __asm("vpaddq %zmm2, %zmm3, %zmm3"); - } + } while ((ip += 8) < ipend); FLETCHER_4_AVX512_SAVE_CTX(ctx) - - kfpu_end(); } STACK_FRAME_NON_STANDARD(fletcher_4_avx512bw_byteswap); diff --git a/module/zcommon/zfs_fletcher_intel.c b/module/zcommon/zfs_fletcher_intel.c index 42b6309d360..c124d49280c 100644 --- a/module/zcommon/zfs_fletcher_intel.c +++ b/module/zcommon/zfs_fletcher_intel.c @@ -51,6 +51,7 @@ ZFS_NO_SANITIZE_UNDEFINED static void fletcher_4_avx2_init(fletcher_4_ctx_t *ctx) { + kfpu_begin(); memset(ctx->avx, 0, 4 * sizeof (zfs_fletcher_avx_t)); } @@ -81,6 +82,7 @@ fletcher_4_avx2_fini(fletcher_4_ctx_t *ctx, zio_cksum_t *zcp) 64 * ctx->avx[3].v[3]; ZIO_SET_CHECKSUM(zcp, A, B, C, D); + kfpu_end(); } #define FLETCHER_4_AVX2_RESTORE_CTX(ctx) \ @@ -106,22 +108,18 @@ fletcher_4_avx2_native(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) const uint64_t *ip = buf; const uint64_t *ipend = (uint64_t *)((uint8_t *)ip + size); - kfpu_begin(); - FLETCHER_4_AVX2_RESTORE_CTX(ctx); - for (; ip < ipend; ip += 2) { + do { asm volatile("vpmovzxdq %0, %%ymm4"::"m" (*ip)); asm volatile("vpaddq %ymm4, %ymm0, %ymm0"); asm volatile("vpaddq %ymm0, %ymm1, %ymm1"); asm volatile("vpaddq %ymm1, %ymm2, %ymm2"); asm volatile("vpaddq %ymm2, %ymm3, %ymm3"); - } + } while ((ip += 2) < ipend); FLETCHER_4_AVX2_SAVE_CTX(ctx); asm volatile("vzeroupper"); - - kfpu_end(); } static void @@ -134,13 +132,11 @@ fletcher_4_avx2_byteswap(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) const uint64_t *ip = buf; const uint64_t *ipend = (uint64_t *)((uint8_t *)ip + size); - kfpu_begin(); - FLETCHER_4_AVX2_RESTORE_CTX(ctx); asm volatile("vmovdqu %0, %%ymm5" :: "m" (mask)); - for (; ip < ipend; ip += 2) { + do { asm volatile("vpmovzxdq %0, %%ymm4"::"m" (*ip)); asm volatile("vpshufb %ymm5, %ymm4, %ymm4"); @@ -148,12 +144,10 @@ fletcher_4_avx2_byteswap(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) asm volatile("vpaddq %ymm0, %ymm1, %ymm1"); asm volatile("vpaddq %ymm1, %ymm2, %ymm2"); asm volatile("vpaddq %ymm2, %ymm3, %ymm3"); - } + } while ((ip += 2) < ipend); FLETCHER_4_AVX2_SAVE_CTX(ctx); asm volatile("vzeroupper"); - - kfpu_end(); } static boolean_t fletcher_4_avx2_valid(void) diff --git a/module/zcommon/zfs_fletcher_sse.c b/module/zcommon/zfs_fletcher_sse.c index 791bbd49f68..6c78830be99 100644 --- a/module/zcommon/zfs_fletcher_sse.c +++ b/module/zcommon/zfs_fletcher_sse.c @@ -53,6 +53,7 @@ ZFS_NO_SANITIZE_UNDEFINED static void fletcher_4_sse2_init(fletcher_4_ctx_t *ctx) { + kfpu_begin(); memset(ctx->sse, 0, 4 * sizeof (zfs_fletcher_sse_t)); } @@ -80,6 +81,7 @@ fletcher_4_sse2_fini(fletcher_4_ctx_t *ctx, zio_cksum_t *zcp) 8 * ctx->sse[2].v[1] + ctx->sse[1].v[1]; ZIO_SET_CHECKSUM(zcp, A, B, C, D); + kfpu_end(); } #define FLETCHER_4_SSE_RESTORE_CTX(ctx) \ @@ -104,13 +106,11 @@ fletcher_4_sse2_native(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) const uint64_t *ip = buf; const uint64_t *ipend = (uint64_t *)((uint8_t *)ip + size); - kfpu_begin(); - FLETCHER_4_SSE_RESTORE_CTX(ctx); asm volatile("pxor %xmm4, %xmm4"); - for (; ip < ipend; ip += 2) { + do { asm volatile("movdqu %0, %%xmm5" :: "m"(*ip)); asm volatile("movdqa %xmm5, %xmm6"); asm volatile("punpckldq %xmm4, %xmm5"); @@ -123,11 +123,9 @@ fletcher_4_sse2_native(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) asm volatile("paddq %xmm0, %xmm1"); asm volatile("paddq %xmm1, %xmm2"); asm volatile("paddq %xmm2, %xmm3"); - } + } while ((ip += 2) < ipend); FLETCHER_4_SSE_SAVE_CTX(ctx); - - kfpu_end(); } static void @@ -136,11 +134,9 @@ fletcher_4_sse2_byteswap(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) const uint32_t *ip = buf; const uint32_t *ipend = (uint32_t *)((uint8_t *)ip + size); - kfpu_begin(); - FLETCHER_4_SSE_RESTORE_CTX(ctx); - for (; ip < ipend; ip += 2) { + do { uint32_t scratch1 = BSWAP_32(ip[0]); uint32_t scratch2 = BSWAP_32(ip[1]); asm volatile("movd %0, %%xmm5" :: "r"(scratch1)); @@ -150,11 +146,9 @@ fletcher_4_sse2_byteswap(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) asm volatile("paddq %xmm0, %xmm1"); asm volatile("paddq %xmm1, %xmm2"); asm volatile("paddq %xmm2, %xmm3"); - } + } while ((ip += 2) < ipend); FLETCHER_4_SSE_SAVE_CTX(ctx); - - kfpu_end(); } static boolean_t fletcher_4_sse2_valid(void) @@ -186,14 +180,12 @@ fletcher_4_ssse3_byteswap(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) const uint64_t *ip = buf; const uint64_t *ipend = (uint64_t *)((uint8_t *)ip + size); - kfpu_begin(); - FLETCHER_4_SSE_RESTORE_CTX(ctx); asm volatile("movdqu %0, %%xmm7"::"m" (mask)); asm volatile("pxor %xmm4, %xmm4"); - for (; ip < ipend; ip += 2) { + do { asm volatile("movdqu %0, %%xmm5"::"m" (*ip)); asm volatile("pshufb %xmm7, %xmm5"); asm volatile("movdqa %xmm5, %xmm6"); @@ -207,11 +199,9 @@ fletcher_4_ssse3_byteswap(fletcher_4_ctx_t *ctx, const void *buf, uint64_t size) asm volatile("paddq %xmm0, %xmm1"); asm volatile("paddq %xmm1, %xmm2"); asm volatile("paddq %xmm2, %xmm3"); - } + } while ((ip += 2) < ipend); FLETCHER_4_SSE_SAVE_CTX(ctx); - - kfpu_end(); } static boolean_t fletcher_4_ssse3_valid(void) diff --git a/module/zcommon/zfs_fletcher_superscalar.c b/module/zcommon/zfs_fletcher_superscalar.c index ba3fb54cbcf..67dc095927f 100644 --- a/module/zcommon/zfs_fletcher_superscalar.c +++ b/module/zcommon/zfs_fletcher_superscalar.c @@ -89,7 +89,7 @@ fletcher_4_superscalar_native(fletcher_4_ctx_t *ctx, c2 = ctx->superscalar[2].v[1]; d2 = ctx->superscalar[3].v[1]; - for (; ip < ipend; ip += 2) { + do { a += ip[0]; a2 += ip[1]; b += a; @@ -98,7 +98,7 @@ fletcher_4_superscalar_native(fletcher_4_ctx_t *ctx, c2 += b2; d += c; d2 += c2; - } + } while ((ip += 2) < ipend); ctx->superscalar[0].v[0] = a; ctx->superscalar[1].v[0] = b; @@ -129,7 +129,7 @@ fletcher_4_superscalar_byteswap(fletcher_4_ctx_t *ctx, c2 = ctx->superscalar[2].v[1]; d2 = ctx->superscalar[3].v[1]; - for (; ip < ipend; ip += 2) { + do { a += BSWAP_32(ip[0]); a2 += BSWAP_32(ip[1]); b += a; @@ -138,7 +138,7 @@ fletcher_4_superscalar_byteswap(fletcher_4_ctx_t *ctx, c2 += b2; d += c; d2 += c2; - } + } while ((ip += 2) < ipend); ctx->superscalar[0].v[0] = a; ctx->superscalar[1].v[0] = b; diff --git a/module/zcommon/zfs_fletcher_superscalar4.c b/module/zcommon/zfs_fletcher_superscalar4.c index e3eda029590..d2067c12f85 100644 --- a/module/zcommon/zfs_fletcher_superscalar4.c +++ b/module/zcommon/zfs_fletcher_superscalar4.c @@ -113,7 +113,7 @@ fletcher_4_superscalar4_native(fletcher_4_ctx_t *ctx, c4 = ctx->superscalar[2].v[3]; d4 = ctx->superscalar[3].v[3]; - for (; ip < ipend; ip += 4) { + do { a += ip[0]; a2 += ip[1]; a3 += ip[2]; @@ -130,7 +130,7 @@ fletcher_4_superscalar4_native(fletcher_4_ctx_t *ctx, d2 += c2; d3 += c3; d4 += c4; - } + } while ((ip += 4) < ipend); ctx->superscalar[0].v[0] = a; ctx->superscalar[1].v[0] = b; @@ -179,7 +179,7 @@ fletcher_4_superscalar4_byteswap(fletcher_4_ctx_t *ctx, c4 = ctx->superscalar[2].v[3]; d4 = ctx->superscalar[3].v[3]; - for (; ip < ipend; ip += 4) { + do { a += BSWAP_32(ip[0]); a2 += BSWAP_32(ip[1]); a3 += BSWAP_32(ip[2]); @@ -196,7 +196,7 @@ fletcher_4_superscalar4_byteswap(fletcher_4_ctx_t *ctx, d2 += c2; d3 += c3; d4 += c4; - } + } while ((ip += 4) < ipend); ctx->superscalar[0].v[0] = a; ctx->superscalar[1].v[0] = b;