mirror of
https://github.com/openzfs/zfs.git
synced 2025-10-01 11:26:49 +00:00
Compare commits
196 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f3e4043a36 | ||
![]() |
91bc62642e | ||
![]() |
acfd6511cf | ||
![]() |
f741c841dd | ||
![]() |
637f918211 | ||
![]() |
7e72312eff | ||
![]() |
383256c329 | ||
![]() |
c2668b2d10 | ||
![]() |
b4ce059a76 | ||
![]() |
92d1686a2a | ||
![]() |
7ea899be04 | ||
![]() |
e085d66f7a | ||
![]() |
af062c480c | ||
![]() |
f2ab5b82da | ||
![]() |
1bdce0410c | ||
![]() |
55b21552d3 | ||
![]() |
c4fa9c2962 | ||
![]() |
8487b6c9b4 | ||
![]() |
0be3b266ed | ||
![]() |
001ab5941d | ||
![]() |
7784947923 | ||
![]() |
a0f8d3c584 | ||
![]() |
2adca179b6 | ||
![]() |
a77b6398ed | ||
![]() |
d1b0c4ec5a | ||
![]() |
3266d4d655 | ||
![]() |
51bec16060 | ||
![]() |
3b5c3f52d2 | ||
![]() |
67f0469f70 | ||
![]() |
1aa4351c1f | ||
![]() |
0e21e473a7 | ||
![]() |
6e9911212e | ||
![]() |
42bad93414 | ||
![]() |
a28f5a94f4 | ||
![]() |
0dfcfe023e | ||
![]() |
cf55fdea24 | ||
![]() |
6edbbe0646 | ||
![]() |
198621f910 | ||
![]() |
e6c98d11ec | ||
![]() |
083d322fa0 | ||
![]() |
c36faf668b | ||
![]() |
404254bacb | ||
![]() |
8eba6a5ba1 | ||
![]() |
fabdd502f4 | ||
![]() |
675b49d2a1 | ||
![]() |
54eec0fa59 | ||
![]() |
bc06d8164b | ||
![]() |
76745cf5b8 | ||
![]() |
0c88ae6187 | ||
![]() |
307fd0da1f | ||
![]() |
9f1c5e0b10 | ||
![]() |
5ba50c8135 | ||
![]() |
25565403aa | ||
![]() |
47b7dc976b | ||
![]() |
125731436d | ||
![]() |
4425a7bb85 | ||
![]() |
e47b033eae | ||
![]() |
cfec8f13a2 | ||
![]() |
997db7a7fc | ||
![]() |
e411081aa0 | ||
![]() |
a55b6fe94a | ||
![]() |
939e9f0b6a | ||
![]() |
679b164cd3 | ||
![]() |
c2d9494f99 | ||
![]() |
b952e061df | ||
![]() |
0fea7fc109 | ||
![]() |
0f6d955a35 | ||
![]() |
c3d2412b05 | ||
![]() |
74064cb175 | ||
![]() |
30b97ce218 | ||
![]() |
9519e7ebcc | ||
![]() |
f9b02fe7e3 | ||
![]() |
cb8da70329 | ||
![]() |
c944c46a98 | ||
![]() |
166a7bc602 | ||
![]() |
e90124a7c8 | ||
![]() |
18b3bea861 | ||
![]() |
d67eb17e27 | ||
![]() |
1862c1c0a8 | ||
![]() |
b57f53036d | ||
![]() |
4b8bf3c48a | ||
![]() |
696943533c | ||
![]() |
2284a61129 | ||
![]() |
e1833a72f9 | ||
![]() |
5bb034f533 | ||
![]() |
1e08e49a28 | ||
![]() |
6604fe9a06 | ||
![]() |
7cbe7bbbd4 | ||
![]() |
2dcc8fe035 | ||
![]() |
38875918d8 | ||
![]() |
0d51852ec7 | ||
![]() |
73a73cba71 | ||
![]() |
87947f2440 | ||
![]() |
0e87150b6c | ||
![]() |
7742e29387 | ||
![]() |
f54052a122 | ||
![]() |
d874f27776 | ||
![]() |
84d7d53e91 | ||
![]() |
d90042dedb | ||
![]() |
0e46085ee6 | ||
![]() |
3b0c1131ef | ||
![]() |
5988de77b0 | ||
![]() |
00debc1361 | ||
![]() |
af10714e42 | ||
![]() |
747781a345 | ||
![]() |
b17ea73f9d | ||
![]() |
17cdb7a2b1 | ||
![]() |
b673bcba4d | ||
![]() |
d8886275df | ||
![]() |
1aee375947 | ||
![]() |
a1907b038a | ||
![]() |
d359f7f547 | ||
![]() |
90603601b4 | ||
![]() |
ecd0b1528e | ||
![]() |
3ed1d608a8 | ||
![]() |
c165daa0b1 | ||
![]() |
1a5414ba2f | ||
![]() |
409aad3f33 | ||
![]() |
1917c26944 | ||
![]() |
2b64d41be8 | ||
![]() |
9753feaa63 | ||
![]() |
3c0b8da206 | ||
![]() |
d7abeef621 | ||
![]() |
7fb7eb9a63 | ||
![]() |
3f9af023f6 | ||
![]() |
f7675ae30f | ||
![]() |
920603990a | ||
![]() |
9a4b2f08d3 | ||
![]() |
8023d9d4b5 | ||
![]() |
23f063d2e6 | ||
![]() |
18474efeec | ||
![]() |
260065099e | ||
![]() |
4c9f2cec46 | ||
![]() |
ee3677d321 | ||
![]() |
0274a9a57d | ||
![]() |
025f8b2e74 | ||
![]() |
37e8f3ae17 | ||
![]() |
7313c6e382 | ||
![]() |
1c6b0302ef | ||
![]() |
7e3af4658b | ||
![]() |
1a54b13aaf | ||
![]() |
9061a4da0b | ||
![]() |
e12d76176d | ||
![]() |
8131793d6f | ||
![]() |
c82eb27b22 | ||
![]() |
661bb434e6 | ||
![]() |
ae48c2f6a9 | ||
![]() |
b96845b632 | ||
![]() |
55cbd1f9bd | ||
![]() |
880b73956b | ||
![]() |
d367ef2995 | ||
![]() |
7546fbd6e9 | ||
![]() |
903d3f9187 | ||
![]() |
86b5853cfb | ||
![]() |
19a8dd48e1 | ||
![]() |
8ac70aade7 | ||
![]() |
bbc0d34bfd | ||
![]() |
f3823a9ab2 | ||
![]() |
fd2cae969f | ||
![]() |
f7b4bca66a | ||
![]() |
7e3ce4efaa | ||
![]() |
77d81974b6 | ||
![]() |
5237760b17 | ||
![]() |
ede715d1e4 | ||
![]() |
e30c69365d | ||
![]() |
78d39d91fa | ||
![]() |
2b359c7824 | ||
![]() |
ace2e17a9b | ||
![]() |
b4cd10ce5b | ||
![]() |
f52d7aaaac | ||
![]() |
d5db840260 | ||
![]() |
bcd61d9579 | ||
![]() |
36a67b50a2 | ||
![]() |
3d9129a7b6 | ||
![]() |
0409c47fe0 | ||
![]() |
b5a3825244 | ||
![]() |
77df762a1b | ||
![]() |
56871e465a | ||
![]() |
c645b07eaa | ||
![]() |
5bc27acf51 | ||
![]() |
7f830d783b | ||
![]() |
58162960a1 | ||
![]() |
666903610d | ||
![]() |
26ecd8b993 | ||
![]() |
774dcba86d | ||
![]() |
09f6b2ebe3 | ||
![]() |
2609d93b65 | ||
![]() |
10f46d2aba | ||
![]() |
0df10dc911 | ||
![]() |
0fbe9d352c | ||
![]() |
84f44ec07f | ||
![]() |
fc9608e2e6 | ||
![]() |
d32c05949a | ||
![]() |
1ebb6b866f | ||
![]() |
f019b445f3 | ||
![]() |
03822a61be |
2
.github/workflows/checkstyle.yaml
vendored
2
.github/workflows/checkstyle.yaml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
run: |
|
||||
# for x in lxd core20 snapd; do sudo snap remove $x; done
|
||||
sudo apt-get purge -y snapd google-chrome-stable firefox
|
||||
ONLY_DEPS=1 .github/workflows/scripts/qemu-3-deps.sh ubuntu22
|
||||
ONLY_DEPS=1 .github/workflows/scripts/qemu-3-deps-vm.sh ubuntu22
|
||||
sudo apt-get install -y cppcheck devscripts mandoc pax-utils shellcheck
|
||||
sudo python -m pipx install --quiet flake8
|
||||
# confirm that the tools are installed
|
||||
|
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@ -11,7 +11,7 @@ concurrency:
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
|
16
.github/workflows/scripts/qemu-1-setup.sh
vendored
16
.github/workflows/scripts/qemu-1-setup.sh
vendored
@ -18,19 +18,21 @@ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -q -N ""
|
||||
|
||||
# we expect RAM shortage
|
||||
cat << EOF | sudo tee /etc/ksmtuned.conf > /dev/null
|
||||
# /etc/ksmtuned.conf - Configuration file for ksmtuned
|
||||
# https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/virtualization_tuning_and_optimization_guide/chap-ksm
|
||||
KSM_MONITOR_INTERVAL=60
|
||||
|
||||
# Millisecond sleep between ksm scans for 16Gb server.
|
||||
# Smaller servers sleep more, bigger sleep less.
|
||||
KSM_SLEEP_MSEC=10
|
||||
KSM_NPAGES_BOOST=300
|
||||
KSM_NPAGES_DECAY=-50
|
||||
KSM_NPAGES_MIN=64
|
||||
KSM_NPAGES_MAX=2048
|
||||
KSM_SLEEP_MSEC=30
|
||||
|
||||
KSM_THRES_COEF=25
|
||||
KSM_THRES_CONST=2048
|
||||
KSM_NPAGES_BOOST=0
|
||||
KSM_NPAGES_DECAY=0
|
||||
KSM_NPAGES_MIN=1000
|
||||
KSM_NPAGES_MAX=25000
|
||||
|
||||
KSM_THRES_COEF=80
|
||||
KSM_THRES_CONST=8192
|
||||
|
||||
LOGFILE=/var/log/ksmtuned.log
|
||||
DEBUG=1
|
||||
|
66
.github/workflows/scripts/qemu-2-start.sh
vendored
66
.github/workflows/scripts/qemu-2-start.sh
vendored
@ -14,7 +14,7 @@ OSv=$OS
|
||||
|
||||
# compressed with .zst extension
|
||||
REPO="https://github.com/mcmilk/openzfs-freebsd-images"
|
||||
FREEBSD="$REPO/releases/download/v2024-09-16"
|
||||
FREEBSD="$REPO/releases/download/v2024-12-14"
|
||||
URLzs=""
|
||||
|
||||
# Ubuntu mirrors
|
||||
@ -40,6 +40,12 @@ case "$OS" in
|
||||
# dns sometimes fails with that url :/
|
||||
echo "89.187.191.12 geo.mirror.pkgbuild.com" | sudo tee /etc/hosts > /dev/null
|
||||
;;
|
||||
centos-stream10)
|
||||
OSNAME="CentOS Stream 10"
|
||||
# TODO: #16903 Overwrite OSv to stream9 for virt-install until it's added to osinfo
|
||||
OSv="centos-stream9"
|
||||
URL="https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2"
|
||||
;;
|
||||
centos-stream9)
|
||||
OSNAME="CentOS Stream 9"
|
||||
URL="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
|
||||
@ -52,43 +58,56 @@ case "$OS" in
|
||||
OSNAME="Debian 12"
|
||||
URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
|
||||
;;
|
||||
fedora39)
|
||||
OSNAME="Fedora 39"
|
||||
OSv="fedora39"
|
||||
URL="https://download.fedoraproject.org/pub/fedora/linux/releases/39/Cloud/x86_64/images/Fedora-Cloud-Base-39-1.5.x86_64.qcow2"
|
||||
;;
|
||||
fedora40)
|
||||
OSNAME="Fedora 40"
|
||||
OSv="fedora39"
|
||||
OSv="fedora-unknown"
|
||||
URL="https://download.fedoraproject.org/pub/fedora/linux/releases/40/Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2"
|
||||
;;
|
||||
freebsd13r)
|
||||
fedora41)
|
||||
OSNAME="Fedora 41"
|
||||
OSv="fedora-unknown"
|
||||
URL="https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2"
|
||||
;;
|
||||
freebsd13-3r)
|
||||
OSNAME="FreeBSD 13.3-RELEASE"
|
||||
OSv="freebsd13.0"
|
||||
URLzs="$FREEBSD/amd64-freebsd-13.3-RELEASE.qcow2.zst"
|
||||
BASH="/usr/local/bin/bash"
|
||||
NIC="rtl8139"
|
||||
;;
|
||||
freebsd13-4r)
|
||||
OSNAME="FreeBSD 13.4-RELEASE"
|
||||
OSv="freebsd13.0"
|
||||
URLzs="$FREEBSD/amd64-freebsd-13.4-RELEASE.qcow2.zst"
|
||||
BASH="/usr/local/bin/bash"
|
||||
NIC="rtl8139"
|
||||
;;
|
||||
freebsd13)
|
||||
freebsd14-1r)
|
||||
OSNAME="FreeBSD 14.1-RELEASE"
|
||||
OSv="freebsd14.0"
|
||||
URLzs="$FREEBSD/amd64-freebsd-14.1-RELEASE.qcow2.zst"
|
||||
BASH="/usr/local/bin/bash"
|
||||
;;
|
||||
freebsd14-2r)
|
||||
OSNAME="FreeBSD 14.2-RELEASE"
|
||||
OSv="freebsd14.0"
|
||||
URLzs="$FREEBSD/amd64-freebsd-14.2-RELEASE.qcow2.zst"
|
||||
BASH="/usr/local/bin/bash"
|
||||
;;
|
||||
freebsd13-4s)
|
||||
OSNAME="FreeBSD 13.4-STABLE"
|
||||
OSv="freebsd13.0"
|
||||
URLzs="$FREEBSD/amd64-freebsd-13.4-STABLE.qcow2.zst"
|
||||
BASH="/usr/local/bin/bash"
|
||||
NIC="rtl8139"
|
||||
;;
|
||||
freebsd14r)
|
||||
OSNAME="FreeBSD 14.1-RELEASE"
|
||||
freebsd14-2s)
|
||||
OSNAME="FreeBSD 14.2-STABLE"
|
||||
OSv="freebsd14.0"
|
||||
URLzs="$FREEBSD/amd64-freebsd-14.1-RELEASE.qcow2.zst"
|
||||
URLzs="$FREEBSD/amd64-freebsd-14.2-STABLE.qcow2.zst"
|
||||
BASH="/usr/local/bin/bash"
|
||||
;;
|
||||
freebsd14)
|
||||
OSNAME="FreeBSD 14.1-STABLE"
|
||||
OSv="freebsd14.0"
|
||||
URLzs="$FREEBSD/amd64-freebsd-14.1-STABLE.qcow2.zst"
|
||||
BASH="/usr/local/bin/bash"
|
||||
;;
|
||||
freebsd15)
|
||||
freebsd15-0c)
|
||||
OSNAME="FreeBSD 15.0-CURRENT"
|
||||
OSv="freebsd14.0"
|
||||
URLzs="$FREEBSD/amd64-freebsd-15.0-CURRENT.qcow2.zst"
|
||||
@ -201,6 +220,15 @@ sudo virt-install \
|
||||
--disk $DISK,bus=virtio,cache=none,format=$FORMAT,driver.discard=unmap \
|
||||
--import --noautoconsole >/dev/null
|
||||
|
||||
# Give the VMs hostnames so we don't have to refer to them with
|
||||
# hardcoded IP addresses.
|
||||
#
|
||||
# vm0: Initial VM we install dependencies and build ZFS on.
|
||||
# vm1..2 Testing VMs
|
||||
for i in {0..9} ; do
|
||||
echo "192.168.122.1$i vm$i" | sudo tee -a /etc/hosts
|
||||
done
|
||||
|
||||
# in case the directory isn't there already
|
||||
mkdir -p $HOME/.ssh
|
||||
|
||||
|
232
.github/workflows/scripts/qemu-3-deps-vm.sh
vendored
Executable file
232
.github/workflows/scripts/qemu-3-deps-vm.sh
vendored
Executable file
@ -0,0 +1,232 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
######################################################################
|
||||
# 3) install dependencies for compiling and loading
|
||||
#
|
||||
# $1: OS name (like 'fedora41')
|
||||
######################################################################
|
||||
|
||||
set -eu
|
||||
|
||||
function archlinux() {
|
||||
echo "##[group]Running pacman -Syu"
|
||||
sudo btrfs filesystem resize max /
|
||||
sudo pacman -Syu --noconfirm
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install Development Tools"
|
||||
sudo pacman -Sy --noconfirm base-devel bc cpio cryptsetup dhclient dkms \
|
||||
fakeroot fio gdb inetutils jq less linux linux-headers lsscsi nfs-utils \
|
||||
parted pax perf python-packaging python-setuptools qemu-guest-agent ksh \
|
||||
samba sysstat rng-tools rsync wget xxhash
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function debian() {
|
||||
export DEBIAN_FRONTEND="noninteractive"
|
||||
|
||||
echo "##[group]Running apt-get update+upgrade"
|
||||
sudo apt-get update -y
|
||||
sudo apt-get upgrade -y
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install Development Tools"
|
||||
sudo apt-get install -y \
|
||||
acl alien attr autoconf bc cpio cryptsetup curl dbench dh-python dkms \
|
||||
fakeroot fio gdb gdebi git ksh lcov isc-dhcp-client jq libacl1-dev \
|
||||
libaio-dev libattr1-dev libblkid-dev libcurl4-openssl-dev libdevmapper-dev \
|
||||
libelf-dev libffi-dev libmount-dev libpam0g-dev libselinux-dev libssl-dev \
|
||||
libtool libtool-bin libudev-dev libunwind-dev linux-headers-$(uname -r) \
|
||||
lsscsi nfs-kernel-server pamtester parted python3 python3-all-dev \
|
||||
python3-cffi python3-dev python3-distlib python3-packaging \
|
||||
python3-setuptools python3-sphinx qemu-guest-agent rng-tools rpm2cpio \
|
||||
rsync samba sysstat uuid-dev watchdog wget xfslibs-dev xxhash zlib1g-dev
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function freebsd() {
|
||||
export ASSUME_ALWAYS_YES="YES"
|
||||
|
||||
echo "##[group]Install Development Tools"
|
||||
sudo pkg install -y autoconf automake autotools base64 checkbashisms fio \
|
||||
gdb gettext gettext-runtime git gmake gsed jq ksh93 lcov libtool lscpu \
|
||||
pkgconf python python3 pamtester pamtester qemu-guest-agent rsync xxhash
|
||||
sudo pkg install -xy \
|
||||
'^samba4[[:digit:]]+$' \
|
||||
'^py3[[:digit:]]+-cffi$' \
|
||||
'^py3[[:digit:]]+-sysctl$' \
|
||||
'^py3[[:digit:]]+-packaging$'
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
# common packages for: almalinux, centos, redhat
|
||||
function rhel() {
|
||||
echo "##[group]Running dnf update"
|
||||
echo "max_parallel_downloads=10" | sudo -E tee -a /etc/dnf/dnf.conf
|
||||
sudo dnf clean all
|
||||
sudo dnf update -y --setopt=fastestmirror=1 --refresh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install Development Tools"
|
||||
|
||||
# Alma wants "Development Tools", Fedora 41 wants "development-tools"
|
||||
if ! sudo dnf group install -y "Development Tools" ; then
|
||||
echo "Trying 'development-tools' instead of 'Development Tools'"
|
||||
sudo dnf group install -y development-tools
|
||||
fi
|
||||
|
||||
sudo dnf install -y \
|
||||
acl attr bc bzip2 cryptsetup curl dbench dkms elfutils-libelf-devel fio \
|
||||
gdb git jq kernel-rpm-macros ksh libacl-devel libaio-devel \
|
||||
libargon2-devel libattr-devel libblkid-devel libcurl-devel libffi-devel \
|
||||
ncompress libselinux-devel libtirpc-devel libtool libudev-devel \
|
||||
libuuid-devel lsscsi mdadm nfs-utils openssl-devel pam-devel pamtester \
|
||||
parted perf python3 python3-cffi python3-devel python3-packaging \
|
||||
kernel-devel python3-setuptools qemu-guest-agent rng-tools rpcgen \
|
||||
rpm-build rsync samba sysstat systemd watchdog wget xfsprogs-devel xxhash \
|
||||
zlib-devel
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function tumbleweed() {
|
||||
echo "##[group]Running zypper is TODO!"
|
||||
sleep 23456
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
# Install dependencies
|
||||
case "$1" in
|
||||
almalinux8)
|
||||
echo "##[group]Enable epel and powertools repositories"
|
||||
sudo dnf config-manager -y --set-enabled powertools
|
||||
sudo dnf install -y epel-release
|
||||
echo "##[endgroup]"
|
||||
rhel
|
||||
echo "##[group]Install kernel-abi-whitelists"
|
||||
sudo dnf install -y kernel-abi-whitelists
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
almalinux9|centos-stream9|centos-stream10)
|
||||
echo "##[group]Enable epel and crb repositories"
|
||||
sudo dnf config-manager -y --set-enabled crb
|
||||
sudo dnf install -y epel-release
|
||||
echo "##[endgroup]"
|
||||
rhel
|
||||
echo "##[group]Install kernel-abi-stablelists"
|
||||
sudo dnf install -y kernel-abi-stablelists
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
archlinux)
|
||||
archlinux
|
||||
;;
|
||||
debian*)
|
||||
echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
|
||||
debian
|
||||
echo "##[group]Install Debian specific"
|
||||
sudo apt-get install -yq linux-perf dh-sequence-dkms
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
fedora*)
|
||||
rhel
|
||||
sudo dnf install -y libunwind-devel
|
||||
;;
|
||||
freebsd*)
|
||||
freebsd
|
||||
;;
|
||||
tumbleweed)
|
||||
tumbleweed
|
||||
;;
|
||||
ubuntu*)
|
||||
debian
|
||||
echo "##[group]Install Ubuntu specific"
|
||||
sudo apt-get install -yq linux-tools-common libtirpc-dev \
|
||||
linux-modules-extra-$(uname -r)
|
||||
if [ "$1" != "ubuntu20" ]; then
|
||||
sudo apt-get install -yq dh-sequence-dkms
|
||||
fi
|
||||
echo "##[endgroup]"
|
||||
echo "##[group]Delete Ubuntu OpenZFS modules"
|
||||
for i in $(find /lib/modules -name zfs -type d); do sudo rm -rvf $i; done
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
esac
|
||||
|
||||
# This script is used for checkstyle + zloop deps also.
|
||||
# Install only the needed packages and exit - when used this way.
|
||||
test -z "${ONLY_DEPS:-}" || exit 0
|
||||
|
||||
# Start services
|
||||
echo "##[group]Enable services"
|
||||
case "$1" in
|
||||
freebsd*)
|
||||
# add virtio things
|
||||
echo 'virtio_load="YES"' | sudo -E tee -a /boot/loader.conf
|
||||
for i in balloon blk console random scsi; do
|
||||
echo "virtio_${i}_load=\"YES\"" | sudo -E tee -a /boot/loader.conf
|
||||
done
|
||||
echo "fdescfs /dev/fd fdescfs rw 0 0" | sudo -E tee -a /etc/fstab
|
||||
sudo -E mount /dev/fd
|
||||
sudo -E touch /etc/zfs/exports
|
||||
sudo -E sysrc mountd_flags="/etc/zfs/exports"
|
||||
echo '[global]' | sudo -E tee /usr/local/etc/smb4.conf >/dev/null
|
||||
sudo -E service nfsd enable
|
||||
sudo -E service qemu-guest-agent enable
|
||||
sudo -E service samba_server enable
|
||||
;;
|
||||
debian*|ubuntu*)
|
||||
sudo -E systemctl enable nfs-kernel-server
|
||||
sudo -E systemctl enable qemu-guest-agent
|
||||
sudo -E systemctl enable smbd
|
||||
;;
|
||||
*)
|
||||
# All other linux distros
|
||||
sudo -E systemctl enable nfs-server
|
||||
sudo -E systemctl enable qemu-guest-agent
|
||||
sudo -E systemctl enable smb
|
||||
;;
|
||||
esac
|
||||
echo "##[endgroup]"
|
||||
|
||||
# Setup Kernel cmdline
|
||||
CMDLINE="console=tty0 console=ttyS0,115200n8"
|
||||
CMDLINE="$CMDLINE selinux=0"
|
||||
CMDLINE="$CMDLINE random.trust_cpu=on"
|
||||
CMDLINE="$CMDLINE no_timer_check"
|
||||
case "$1" in
|
||||
almalinux*|centos*|fedora*)
|
||||
GRUB_CFG="/boot/grub2/grub.cfg"
|
||||
GRUB_MKCONFIG="grub2-mkconfig"
|
||||
CMDLINE="$CMDLINE biosdevname=0 net.ifnames=0"
|
||||
echo 'GRUB_SERIAL_COMMAND="serial --speed=115200"' \
|
||||
| sudo tee -a /etc/default/grub >/dev/null
|
||||
;;
|
||||
ubuntu24)
|
||||
GRUB_CFG="/boot/grub/grub.cfg"
|
||||
GRUB_MKCONFIG="grub-mkconfig"
|
||||
echo 'GRUB_DISABLE_OS_PROBER="false"' \
|
||||
| sudo tee -a /etc/default/grub >/dev/null
|
||||
;;
|
||||
*)
|
||||
GRUB_CFG="/boot/grub/grub.cfg"
|
||||
GRUB_MKCONFIG="grub-mkconfig"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
archlinux|freebsd*)
|
||||
true
|
||||
;;
|
||||
*)
|
||||
echo "##[group]Edit kernel cmdline"
|
||||
sudo sed -i -e '/^GRUB_CMDLINE_LINUX/d' /etc/default/grub || true
|
||||
echo "GRUB_CMDLINE_LINUX=\"$CMDLINE\"" \
|
||||
| sudo tee -a /etc/default/grub >/dev/null
|
||||
sudo $GRUB_MKCONFIG -o $GRUB_CFG
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
esac
|
||||
|
||||
# reset cloud-init configuration and poweroff
|
||||
sudo cloud-init clean --logs
|
||||
sleep 2 && sudo poweroff &
|
||||
exit 0
|
230
.github/workflows/scripts/qemu-3-deps.sh
vendored
230
.github/workflows/scripts/qemu-3-deps.sh
vendored
@ -1,221 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
######################################################################
|
||||
# 3) install dependencies for compiling and loading
|
||||
# 3) Wait for VM to boot from previous step and launch dependencies
|
||||
# script on it.
|
||||
#
|
||||
# $1: OS name (like 'fedora41')
|
||||
######################################################################
|
||||
|
||||
set -eu
|
||||
|
||||
function archlinux() {
|
||||
echo "##[group]Running pacman -Syu"
|
||||
sudo btrfs filesystem resize max /
|
||||
sudo pacman -Syu --noconfirm
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install Development Tools"
|
||||
sudo pacman -Sy --noconfirm base-devel bc cpio dhclient dkms fakeroot \
|
||||
fio gdb inetutils jq less linux linux-headers lsscsi nfs-utils parted \
|
||||
pax perf python-packaging python-setuptools qemu-guest-agent ksh samba \
|
||||
sysstat rng-tools rsync wget xxhash
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function debian() {
|
||||
export DEBIAN_FRONTEND="noninteractive"
|
||||
|
||||
echo "##[group]Running apt-get update+upgrade"
|
||||
sudo apt-get update -y
|
||||
sudo apt-get upgrade -y
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install Development Tools"
|
||||
sudo apt-get install -y \
|
||||
acl alien attr autoconf bc cpio curl dbench dh-python dkms fakeroot \
|
||||
fio gdb gdebi git ksh lcov isc-dhcp-client jq libacl1-dev libaio-dev \
|
||||
libattr1-dev libblkid-dev libcurl4-openssl-dev libdevmapper-dev libelf-dev \
|
||||
libffi-dev libmount-dev libpam0g-dev libselinux-dev libssl-dev libtool \
|
||||
libtool-bin libudev-dev libunwind-dev linux-headers-$(uname -r) \
|
||||
lsscsi nfs-kernel-server pamtester parted python3 python3-all-dev \
|
||||
python3-cffi python3-dev python3-distlib python3-packaging \
|
||||
python3-setuptools python3-sphinx qemu-guest-agent rng-tools rpm2cpio \
|
||||
rsync samba sysstat uuid-dev watchdog wget xfslibs-dev xxhash zlib1g-dev
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function freebsd() {
|
||||
export ASSUME_ALWAYS_YES="YES"
|
||||
|
||||
echo "##[group]Install Development Tools"
|
||||
sudo pkg install -y autoconf automake autotools base64 checkbashisms fio \
|
||||
gdb gettext gettext-runtime git gmake gsed jq ksh93 lcov libtool lscpu \
|
||||
pkgconf python python3 pamtester pamtester qemu-guest-agent rsync xxhash
|
||||
sudo pkg install -xy \
|
||||
'^samba4[[:digit:]]+$' \
|
||||
'^py3[[:digit:]]+-cffi$' \
|
||||
'^py3[[:digit:]]+-sysctl$' \
|
||||
'^py3[[:digit:]]+-packaging$'
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
# common packages for: almalinux, centos, redhat
|
||||
function rhel() {
|
||||
echo "##[group]Running dnf update"
|
||||
echo "max_parallel_downloads=10" | sudo -E tee -a /etc/dnf/dnf.conf
|
||||
sudo dnf clean all
|
||||
sudo dnf update -y --setopt=fastestmirror=1 --refresh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install Development Tools"
|
||||
sudo dnf group install -y "Development Tools"
|
||||
sudo dnf install -y \
|
||||
acl attr bc bzip2 curl dbench dkms elfutils-libelf-devel fio gdb git \
|
||||
jq kernel-rpm-macros ksh libacl-devel libaio-devel libargon2-devel \
|
||||
libattr-devel libblkid-devel libcurl-devel libffi-devel ncompress \
|
||||
libselinux-devel libtirpc-devel libtool libudev-devel libuuid-devel \
|
||||
lsscsi mdadm nfs-utils openssl-devel pam-devel pamtester parted perf \
|
||||
python3 python3-cffi python3-devel python3-packaging kernel-devel \
|
||||
python3-setuptools qemu-guest-agent rng-tools rpcgen rpm-build rsync \
|
||||
samba sysstat systemd watchdog wget xfsprogs-devel xxhash zlib-devel
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function tumbleweed() {
|
||||
echo "##[group]Running zypper is TODO!"
|
||||
sleep 23456
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
# Install dependencies
|
||||
case "$1" in
|
||||
almalinux8)
|
||||
echo "##[group]Enable epel and powertools repositories"
|
||||
sudo dnf config-manager -y --set-enabled powertools
|
||||
sudo dnf install -y epel-release
|
||||
echo "##[endgroup]"
|
||||
rhel
|
||||
echo "##[group]Install kernel-abi-whitelists"
|
||||
sudo dnf install -y kernel-abi-whitelists
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
almalinux9|centos-stream9)
|
||||
echo "##[group]Enable epel and crb repositories"
|
||||
sudo dnf config-manager -y --set-enabled crb
|
||||
sudo dnf install -y epel-release
|
||||
echo "##[endgroup]"
|
||||
rhel
|
||||
echo "##[group]Install kernel-abi-stablelists"
|
||||
sudo dnf install -y kernel-abi-stablelists
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
archlinux)
|
||||
archlinux
|
||||
;;
|
||||
debian*)
|
||||
debian
|
||||
echo "##[group]Install Debian specific"
|
||||
sudo apt-get install -yq linux-perf dh-sequence-dkms
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
fedora*)
|
||||
rhel
|
||||
;;
|
||||
freebsd*)
|
||||
freebsd
|
||||
;;
|
||||
tumbleweed)
|
||||
tumbleweed
|
||||
;;
|
||||
ubuntu*)
|
||||
debian
|
||||
echo "##[group]Install Ubuntu specific"
|
||||
sudo apt-get install -yq linux-tools-common libtirpc-dev \
|
||||
linux-modules-extra-$(uname -r)
|
||||
if [ "$1" != "ubuntu20" ]; then
|
||||
sudo apt-get install -yq dh-sequence-dkms
|
||||
fi
|
||||
echo "##[endgroup]"
|
||||
echo "##[group]Delete Ubuntu OpenZFS modules"
|
||||
for i in $(find /lib/modules -name zfs -type d); do sudo rm -rvf $i; done
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
esac
|
||||
|
||||
# This script is used for checkstyle + zloop deps also.
|
||||
# Install only the needed packages and exit - when used this way.
|
||||
test -z "${ONLY_DEPS:-}" || exit 0
|
||||
|
||||
# Start services
|
||||
echo "##[group]Enable services"
|
||||
case "$1" in
|
||||
freebsd*)
|
||||
# add virtio things
|
||||
echo 'virtio_load="YES"' | sudo -E tee -a /boot/loader.conf
|
||||
for i in balloon blk console random scsi; do
|
||||
echo "virtio_${i}_load=\"YES\"" | sudo -E tee -a /boot/loader.conf
|
||||
done
|
||||
echo "fdescfs /dev/fd fdescfs rw 0 0" | sudo -E tee -a /etc/fstab
|
||||
sudo -E mount /dev/fd
|
||||
sudo -E touch /etc/zfs/exports
|
||||
sudo -E sysrc mountd_flags="/etc/zfs/exports"
|
||||
echo '[global]' | sudo -E tee /usr/local/etc/smb4.conf >/dev/null
|
||||
sudo -E service nfsd enable
|
||||
sudo -E service qemu-guest-agent enable
|
||||
sudo -E service samba_server enable
|
||||
;;
|
||||
debian*|ubuntu*)
|
||||
sudo -E systemctl enable nfs-kernel-server
|
||||
sudo -E systemctl enable qemu-guest-agent
|
||||
sudo -E systemctl enable smbd
|
||||
;;
|
||||
*)
|
||||
# All other linux distros
|
||||
sudo -E systemctl enable nfs-server
|
||||
sudo -E systemctl enable qemu-guest-agent
|
||||
sudo -E systemctl enable smb
|
||||
;;
|
||||
esac
|
||||
echo "##[endgroup]"
|
||||
|
||||
# Setup Kernel cmdline
|
||||
CMDLINE="console=tty0 console=ttyS0,115200n8"
|
||||
CMDLINE="$CMDLINE selinux=0"
|
||||
CMDLINE="$CMDLINE random.trust_cpu=on"
|
||||
CMDLINE="$CMDLINE no_timer_check"
|
||||
case "$1" in
|
||||
almalinux*|centos*|fedora*)
|
||||
GRUB_CFG="/boot/grub2/grub.cfg"
|
||||
GRUB_MKCONFIG="grub2-mkconfig"
|
||||
CMDLINE="$CMDLINE biosdevname=0 net.ifnames=0"
|
||||
echo 'GRUB_SERIAL_COMMAND="serial --speed=115200"' \
|
||||
| sudo tee -a /etc/default/grub >/dev/null
|
||||
;;
|
||||
ubuntu24)
|
||||
GRUB_CFG="/boot/grub/grub.cfg"
|
||||
GRUB_MKCONFIG="grub-mkconfig"
|
||||
echo 'GRUB_DISABLE_OS_PROBER="false"' \
|
||||
| sudo tee -a /etc/default/grub >/dev/null
|
||||
;;
|
||||
*)
|
||||
GRUB_CFG="/boot/grub/grub.cfg"
|
||||
GRUB_MKCONFIG="grub-mkconfig"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
archlinux|freebsd*)
|
||||
true
|
||||
;;
|
||||
*)
|
||||
echo "##[group]Edit kernel cmdline"
|
||||
sudo sed -i -e '/^GRUB_CMDLINE_LINUX/d' /etc/default/grub || true
|
||||
echo "GRUB_CMDLINE_LINUX=\"$CMDLINE\"" \
|
||||
| sudo tee -a /etc/default/grub >/dev/null
|
||||
sudo $GRUB_MKCONFIG -o $GRUB_CFG
|
||||
echo "##[endgroup]"
|
||||
;;
|
||||
esac
|
||||
|
||||
# reset cloud-init configuration and poweroff
|
||||
sudo cloud-init clean --logs
|
||||
sleep 2 && sudo poweroff &
|
||||
exit 0
|
||||
.github/workflows/scripts/qemu-wait-for-vm.sh vm0
|
||||
scp .github/workflows/scripts/qemu-3-deps-vm.sh zfs@vm0:qemu-3-deps-vm.sh
|
||||
PID=`pidof /usr/bin/qemu-system-x86_64`
|
||||
ssh zfs@vm0 '$HOME/qemu-3-deps-vm.sh' $1
|
||||
# wait for poweroff to succeed
|
||||
tail --pid=$PID -f /dev/null
|
||||
sleep 5 # avoid this: "error: Domain is already active"
|
||||
rm -f $HOME/.ssh/known_hosts
|
||||
|
370
.github/workflows/scripts/qemu-4-build-vm.sh
vendored
Executable file
370
.github/workflows/scripts/qemu-4-build-vm.sh
vendored
Executable file
@ -0,0 +1,370 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
######################################################################
|
||||
# 4) configure and build openzfs modules. This is run on the VMs.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# qemu-4-build-vm.sh OS [--enable-debug][--dkms][--poweroff]
|
||||
# [--release][--repo][--tarball]
|
||||
#
|
||||
# OS: OS name like 'fedora41'
|
||||
# --enable-debug: Build RPMs with '--enable-debug' (for testing)
|
||||
# --dkms: Build DKMS RPMs as well
|
||||
# --poweroff: Power-off the VM after building
|
||||
# --release Build zfs-release*.rpm as well
|
||||
# --repo After building everything, copy RPMs into /tmp/repo
|
||||
# in the ZFS RPM repository file structure. Also
|
||||
# copy tarballs if they were built.
|
||||
# --tarball: Also build a tarball of ZFS source
|
||||
######################################################################
|
||||
|
||||
ENABLE_DEBUG=""
|
||||
DKMS=""
|
||||
POWEROFF=""
|
||||
RELEASE=""
|
||||
REPO=""
|
||||
TARBALL=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--enable-debug)
|
||||
ENABLE_DEBUG=1
|
||||
shift
|
||||
;;
|
||||
--dkms)
|
||||
DKMS=1
|
||||
shift
|
||||
;;
|
||||
--poweroff)
|
||||
POWEROFF=1
|
||||
shift
|
||||
;;
|
||||
--release)
|
||||
RELEASE=1
|
||||
shift
|
||||
;;
|
||||
--repo)
|
||||
REPO=1
|
||||
shift
|
||||
;;
|
||||
--tarball)
|
||||
TARBALL=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
OS=$1
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
set -eu
|
||||
|
||||
function run() {
|
||||
LOG="/var/tmp/build-stderr.txt"
|
||||
echo "****************************************************"
|
||||
echo "$(date) ($*)"
|
||||
echo "****************************************************"
|
||||
($@ || echo $? > /tmp/rv) 3>&1 1>&2 2>&3 | stdbuf -eL -oL tee -a $LOG
|
||||
if [ -f /tmp/rv ]; then
|
||||
RV=$(cat /tmp/rv)
|
||||
echo "****************************************************"
|
||||
echo "exit with value=$RV ($*)"
|
||||
echo "****************************************************"
|
||||
echo 1 > /var/tmp/build-exitcode.txt
|
||||
exit $RV
|
||||
fi
|
||||
}
|
||||
|
||||
# Look at the RPMs in the current directory and copy/move them to
|
||||
# /tmp/repo, using the directory structure we use for the ZFS RPM repos.
|
||||
#
|
||||
# For example:
|
||||
# /tmp/repo/epel-testing/9.5
|
||||
# /tmp/repo/epel-testing/9.5/SRPMS
|
||||
# /tmp/repo/epel-testing/9.5/SRPMS/zfs-2.3.99-1.el9.src.rpm
|
||||
# /tmp/repo/epel-testing/9.5/SRPMS/zfs-kmod-2.3.99-1.el9.src.rpm
|
||||
# /tmp/repo/epel-testing/9.5/kmod
|
||||
# /tmp/repo/epel-testing/9.5/kmod/x86_64
|
||||
# /tmp/repo/epel-testing/9.5/kmod/x86_64/debug
|
||||
# /tmp/repo/epel-testing/9.5/kmod/x86_64/debug/kmod-zfs-debuginfo-2.3.99-1.el9.x86_64.rpm
|
||||
# /tmp/repo/epel-testing/9.5/kmod/x86_64/debug/libnvpair3-debuginfo-2.3.99-1.el9.x86_64.rpm
|
||||
# /tmp/repo/epel-testing/9.5/kmod/x86_64/debug/libuutil3-debuginfo-2.3.99-1.el9.x86_64.rpm
|
||||
# ...
|
||||
function copy_rpms_to_repo {
|
||||
# Pick a RPM to query. It doesn't matter which one - we just want to extract
|
||||
# the 'Build Host' value from it.
|
||||
rpm=$(ls zfs-*.rpm | head -n 1)
|
||||
|
||||
# Get zfs version '2.2.99'
|
||||
zfs_ver=$(rpm -qpi $rpm | awk '/Version/{print $3}')
|
||||
|
||||
# Get "2.1" or "2.2"
|
||||
zfs_major=$(echo $zfs_ver | grep -Eo [0-9]+\.[0-9]+)
|
||||
|
||||
# Get 'almalinux9.5' or 'fedora41' type string
|
||||
build_host=$(rpm -qpi $rpm | awk '/Build Host/{print $4}')
|
||||
|
||||
# Get '9.5' or '41' OS version
|
||||
os_ver=$(echo $build_host | grep -Eo '[0-9\.]+$')
|
||||
|
||||
# Our ZFS version and OS name will determine which repo the RPMs
|
||||
# will go in (regular or testing). Fedora always gets the newest
|
||||
# releases, and Alma gets the older releases.
|
||||
case $build_host in
|
||||
almalinux*)
|
||||
case $zfs_major in
|
||||
2.2)
|
||||
d="epel"
|
||||
;;
|
||||
*)
|
||||
d="epel-testing"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
fedora*)
|
||||
d="fedora"
|
||||
;;
|
||||
esac
|
||||
|
||||
prefix=/tmp/repo
|
||||
dst="$prefix/$d/$os_ver"
|
||||
|
||||
# Special case: move zfs-release*.rpm out of the way first (if we built them).
|
||||
# This will make filtering the other RPMs easier.
|
||||
mkdir -p $dst
|
||||
mv zfs-release*.rpm $dst || true
|
||||
|
||||
# Copy source RPMs
|
||||
mkdir -p $dst/SRPMS
|
||||
cp $(ls *.src.rpm) $dst/SRPMS/
|
||||
|
||||
if [[ "$build_host" =~ "almalinux" ]] ; then
|
||||
# Copy kmods+userspace
|
||||
mkdir -p $dst/kmod/x86_64/debug
|
||||
cp $(ls *.rpm | grep -Ev 'src.rpm|dkms|debuginfo') $dst/kmod/x86_64
|
||||
cp *debuginfo*.rpm $dst/kmod/x86_64/debug
|
||||
fi
|
||||
|
||||
if [ -n "$DKMS" ] ; then
|
||||
# Copy dkms+userspace
|
||||
mkdir -p $dst/x86_64
|
||||
cp $(ls *.rpm | grep -Ev 'src.rpm|kmod|debuginfo') $dst/x86_64
|
||||
fi
|
||||
|
||||
# Copy debug
|
||||
mkdir -p $dst/x86_64/debug
|
||||
cp $(ls *debuginfo*.rpm | grep -v kmod) $dst/x86_64/debug
|
||||
}
|
||||
|
||||
function freebsd() {
|
||||
extra="${1:-}"
|
||||
|
||||
export MAKE="gmake"
|
||||
echo "##[group]Autogen.sh"
|
||||
run ./autogen.sh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Configure"
|
||||
run ./configure \
|
||||
--prefix=/usr/local \
|
||||
--with-libintl-prefix=/usr/local \
|
||||
--enable-pyzfs \
|
||||
--enable-debuginfo $extra
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Build"
|
||||
run gmake -j$(sysctl -n hw.ncpu)
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install"
|
||||
run sudo gmake install
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function linux() {
|
||||
extra="${1:-}"
|
||||
|
||||
echo "##[group]Autogen.sh"
|
||||
run ./autogen.sh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Configure"
|
||||
run ./configure \
|
||||
--prefix=/usr \
|
||||
--enable-pyzfs \
|
||||
--enable-debuginfo $extra
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Build"
|
||||
run make -j$(nproc)
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install"
|
||||
run sudo make install
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function rpm_build_and_install() {
|
||||
extra="${1:-}"
|
||||
|
||||
# Build RPMs with XZ compression by default (since gzip decompression is slow)
|
||||
echo "%_binary_payload w7.xzdio" >> ~/.rpmmacros
|
||||
|
||||
echo "##[group]Autogen.sh"
|
||||
run ./autogen.sh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Configure"
|
||||
run ./configure --enable-debuginfo $extra
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Build"
|
||||
run make pkg-kmod pkg-utils
|
||||
echo "##[endgroup]"
|
||||
|
||||
if [ -n "$DKMS" ] ; then
|
||||
echo "##[group]DKMS"
|
||||
make rpm-dkms
|
||||
echo "##[endgroup]"
|
||||
fi
|
||||
|
||||
if [ -n "$REPO" ] ; then
|
||||
echo "Skipping install since we're only building RPMs and nothing else"
|
||||
else
|
||||
echo "##[group]Install"
|
||||
run sudo dnf -y --nobest install $(ls *.rpm | grep -Ev 'dkms|src.rpm')
|
||||
echo "##[endgroup]"
|
||||
fi
|
||||
|
||||
# Optionally build the zfs-release.*.rpm
|
||||
if [ -n "$RELEASE" ] ; then
|
||||
echo "##[group]Release"
|
||||
pushd ~
|
||||
sudo dnf -y install rpm-build || true
|
||||
# Check out a sparse copy of zfsonlinux.github.com.git so we don't get
|
||||
# all the binaries. We just need a few kilobytes of files to build RPMs.
|
||||
git clone --depth 1 --no-checkout \
|
||||
https://github.com/zfsonlinux/zfsonlinux.github.com.git
|
||||
|
||||
cd zfsonlinux.github.com
|
||||
git sparse-checkout set zfs-release
|
||||
git checkout
|
||||
cd zfs-release
|
||||
|
||||
mkdir -p ~/rpmbuild/{BUILDROOT,SPECS,RPMS,SRPMS,SOURCES,BUILD}
|
||||
cp RPM-GPG-KEY-openzfs* *.repo ~/rpmbuild/SOURCES
|
||||
cp zfs-release.spec ~/rpmbuild/SPECS/
|
||||
rpmbuild -ba ~/rpmbuild/SPECS/zfs-release.spec
|
||||
|
||||
# ZFS release RPMs are built. Copy them to the ~/zfs directory just to
|
||||
# keep all the RPMs in the same place.
|
||||
cp ~/rpmbuild/RPMS/noarch/*.rpm .
|
||||
cp ~/rpmbuild/SRPMS/*.rpm .
|
||||
popd
|
||||
rm -fr ~/rpmbuild
|
||||
echo "##[endgroup]"
|
||||
fi
|
||||
|
||||
if [ -n "$REPO" ] ; then
|
||||
echo "##[group]Repo"
|
||||
copy_rpms_to_repo
|
||||
echo "##[endgroup]"
|
||||
fi
|
||||
}
|
||||
|
||||
function deb_build_and_install() {
|
||||
extra="${1:-}"
|
||||
|
||||
echo "##[group]Autogen.sh"
|
||||
run ./autogen.sh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Configure"
|
||||
run ./configure \
|
||||
--prefix=/usr \
|
||||
--enable-pyzfs \
|
||||
--enable-debuginfo $extra
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Build"
|
||||
run make native-deb-kmod native-deb-utils
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install"
|
||||
# Do kmod install. Note that when you build the native debs, the
|
||||
# packages themselves are placed in parent directory '../' rather than
|
||||
# in the source directory like the rpms are.
|
||||
run sudo apt-get -y install $(find ../ | grep -E '\.deb$' \
|
||||
| grep -Ev 'dkms|dracut')
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
# Debug: show kernel cmdline
|
||||
if [ -f /proc/cmdline ] ; then
|
||||
cat /proc/cmdline || true
|
||||
fi
|
||||
|
||||
# Set our hostname to our OS name and version number. Specifically, we set the
|
||||
# major and minor number so that when we query the Build Host field in the RPMs
|
||||
# we build, we can see what specific version of Fedora/Almalinux we were using
|
||||
# to build them. This is helpful for matching up KMOD versions.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# rhel8.10
|
||||
# almalinux9.5
|
||||
# fedora40
|
||||
source /etc/os-release
|
||||
sudo hostname "$ID$VERSION_ID"
|
||||
|
||||
# save some sysinfo
|
||||
uname -a > /var/tmp/uname.txt
|
||||
|
||||
cd $HOME/zfs
|
||||
export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"
|
||||
|
||||
extra=""
|
||||
if [ -n "$ENABLE_DEBUG" ] ; then
|
||||
extra="--enable-debug"
|
||||
fi
|
||||
|
||||
# build
|
||||
case "$OS" in
|
||||
freebsd*)
|
||||
freebsd "$extra"
|
||||
;;
|
||||
alma*|centos*)
|
||||
rpm_build_and_install "--with-spec=redhat $extra"
|
||||
;;
|
||||
fedora*)
|
||||
rpm_build_and_install "$extra"
|
||||
;;
|
||||
debian*|ubuntu*)
|
||||
deb_build_and_install "$extra"
|
||||
;;
|
||||
*)
|
||||
linux "$extra"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Optionally build tarballs. The tarball's root directory name will be named
|
||||
# after the current tag, like 'zfs-2.3.0' or 'master'.
|
||||
if [ -n "$TARBALL" ] ; then
|
||||
tag="$(git symbolic-ref -q --short HEAD || git describe --tags --exact-match)"
|
||||
git archive --format=tar.gz -o $tag.tar.gz $tag
|
||||
if [ -n "$REPO" ] ; then
|
||||
mkdir -p /tmp/repo/releases
|
||||
cp $tag.tar.gz /tmp/repo/releases
|
||||
fi
|
||||
fi
|
||||
|
||||
# building the zfs module was ok
|
||||
echo 0 > /var/tmp/build-exitcode.txt
|
||||
|
||||
# reset cloud-init configuration and poweroff
|
||||
if [ -n "$POWEROFF" ] ; then
|
||||
sudo cloud-init clean --logs
|
||||
sync && sleep 2 && sudo poweroff &
|
||||
fi
|
||||
exit 0
|
150
.github/workflows/scripts/qemu-4-build.sh
vendored
150
.github/workflows/scripts/qemu-4-build.sh
vendored
@ -3,151 +3,9 @@
|
||||
######################################################################
|
||||
# 4) configure and build openzfs modules
|
||||
######################################################################
|
||||
echo "Build modules in QEMU machine"
|
||||
|
||||
set -eu
|
||||
# Bring our VM back up and copy over ZFS source
|
||||
.github/workflows/scripts/qemu-prepare-for-build.sh
|
||||
|
||||
function run() {
|
||||
LOG="/var/tmp/build-stderr.txt"
|
||||
echo "****************************************************"
|
||||
echo "$(date) ($*)"
|
||||
echo "****************************************************"
|
||||
($@ || echo $? > /tmp/rv) 3>&1 1>&2 2>&3 | stdbuf -eL -oL tee -a $LOG
|
||||
if [ -f /tmp/rv ]; then
|
||||
RV=$(cat /tmp/rv)
|
||||
echo "****************************************************"
|
||||
echo "exit with value=$RV ($*)"
|
||||
echo "****************************************************"
|
||||
echo 1 > /var/tmp/build-exitcode.txt
|
||||
exit $RV
|
||||
fi
|
||||
}
|
||||
|
||||
function freebsd() {
|
||||
export MAKE="gmake"
|
||||
echo "##[group]Autogen.sh"
|
||||
run ./autogen.sh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Configure"
|
||||
run ./configure \
|
||||
--prefix=/usr/local \
|
||||
--with-libintl-prefix=/usr/local \
|
||||
--enable-pyzfs \
|
||||
--enable-debug \
|
||||
--enable-debuginfo
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Build"
|
||||
run gmake -j$(sysctl -n hw.ncpu)
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install"
|
||||
run sudo gmake install
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function linux() {
|
||||
echo "##[group]Autogen.sh"
|
||||
run ./autogen.sh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Configure"
|
||||
run ./configure \
|
||||
--prefix=/usr \
|
||||
--enable-pyzfs \
|
||||
--enable-debug \
|
||||
--enable-debuginfo
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Build"
|
||||
run make -j$(nproc)
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install"
|
||||
run sudo make install
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
function rpm_build_and_install() {
|
||||
EXTRA_CONFIG="${1:-}"
|
||||
echo "##[group]Autogen.sh"
|
||||
run ./autogen.sh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Configure"
|
||||
run ./configure --enable-debug --enable-debuginfo $EXTRA_CONFIG
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Build"
|
||||
run make pkg-kmod pkg-utils
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install"
|
||||
run sudo dnf -y --skip-broken localinstall $(ls *.rpm | grep -v src.rpm)
|
||||
echo "##[endgroup]"
|
||||
|
||||
}
|
||||
|
||||
function deb_build_and_install() {
|
||||
echo "##[group]Autogen.sh"
|
||||
run ./autogen.sh
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Configure"
|
||||
run ./configure \
|
||||
--prefix=/usr \
|
||||
--enable-pyzfs \
|
||||
--enable-debug \
|
||||
--enable-debuginfo
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Build"
|
||||
run make native-deb-kmod native-deb-utils
|
||||
echo "##[endgroup]"
|
||||
|
||||
echo "##[group]Install"
|
||||
# Do kmod install. Note that when you build the native debs, the
|
||||
# packages themselves are placed in parent directory '../' rather than
|
||||
# in the source directory like the rpms are.
|
||||
run sudo apt-get -y install $(find ../ | grep -E '\.deb$' \
|
||||
| grep -Ev 'dkms|dracut')
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
# Debug: show kernel cmdline
|
||||
if [ -f /proc/cmdline ] ; then
|
||||
cat /proc/cmdline || true
|
||||
fi
|
||||
|
||||
# save some sysinfo
|
||||
uname -a > /var/tmp/uname.txt
|
||||
|
||||
cd $HOME/zfs
|
||||
export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"
|
||||
|
||||
# build
|
||||
case "$1" in
|
||||
freebsd*)
|
||||
freebsd
|
||||
;;
|
||||
alma*|centos*)
|
||||
rpm_build_and_install "--with-spec=redhat"
|
||||
;;
|
||||
fedora*)
|
||||
rpm_build_and_install
|
||||
;;
|
||||
debian*|ubuntu*)
|
||||
deb_build_and_install
|
||||
;;
|
||||
*)
|
||||
linux
|
||||
;;
|
||||
esac
|
||||
|
||||
# building the zfs module was ok
|
||||
echo 0 > /var/tmp/build-exitcode.txt
|
||||
|
||||
# reset cloud-init configuration and poweroff
|
||||
sudo cloud-init clean --logs
|
||||
sync && sleep 2 && sudo poweroff &
|
||||
exit 0
|
||||
ssh zfs@vm0 '$HOME/zfs/.github/workflows/scripts/qemu-4-build-vm.sh' $@
|
||||
|
21
.github/workflows/scripts/qemu-5-setup.sh
vendored
21
.github/workflows/scripts/qemu-5-setup.sh
vendored
@ -14,17 +14,21 @@ PID=$(pidof /usr/bin/qemu-system-x86_64)
|
||||
tail --pid=$PID -f /dev/null
|
||||
sudo virsh undefine openzfs
|
||||
|
||||
# definitions of per operating system
|
||||
# default values per test vm:
|
||||
VMs=2
|
||||
CPU=2
|
||||
|
||||
# cpu pinning
|
||||
CPUSET=("0,1" "2,3")
|
||||
|
||||
case "$OS" in
|
||||
freebsd*)
|
||||
VMs=2
|
||||
CPU=3
|
||||
# FreeBSD can't be optimized via ksmtuned
|
||||
RAM=6
|
||||
;;
|
||||
*)
|
||||
VMs=2
|
||||
CPU=3
|
||||
RAM=7
|
||||
# Linux can be optimized via ksmtuned
|
||||
RAM=8
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -73,6 +77,7 @@ EOF
|
||||
--cpu host-passthrough \
|
||||
--virt-type=kvm --hvm \
|
||||
--vcpus=$CPU,sockets=1 \
|
||||
--cpuset=${CPUSET[$((i-1))]} \
|
||||
--memory $((1024*RAM)) \
|
||||
--memballoon model=virtio \
|
||||
--graphics none \
|
||||
@ -104,9 +109,7 @@ rm crontab.txt
|
||||
# check if the machines are okay
|
||||
echo "Waiting for vm's to come up... (${VMs}x CPU=$CPU RAM=$RAM)"
|
||||
for i in $(seq 1 $VMs); do
|
||||
while true; do
|
||||
ssh 2>/dev/null zfs@192.168.122.1$i "uname -a" && break
|
||||
done
|
||||
.github/workflows/scripts/qemu-wait-for-vm.sh vm$i
|
||||
done
|
||||
echo "All $VMs VMs are up now."
|
||||
|
||||
|
5
.github/workflows/scripts/qemu-7-prepare.sh
vendored
5
.github/workflows/scripts/qemu-7-prepare.sh
vendored
@ -29,8 +29,9 @@ MERGE="$BASE/.github/workflows/scripts/merge_summary.awk"
|
||||
|
||||
# catch result files of testings (vm's should be there)
|
||||
for i in $(seq 1 $VMs); do
|
||||
rsync -arL zfs@192.168.122.1$i:$RESPATH/current $RESPATH/vm$i || true
|
||||
scp zfs@192.168.122.1$i:"/var/tmp/*.txt" $RESPATH/vm$i || true
|
||||
rsync -arL zfs@vm$i:$RESPATH/current $RESPATH/vm$i || true
|
||||
scp zfs@vm$i:"/var/tmp/*.txt" $RESPATH/vm$i || true
|
||||
scp zfs@vm$i:"/var/tmp/*.rpm" $RESPATH/vm$i || true
|
||||
done
|
||||
cp -f /var/tmp/*.txt $RESPATH || true
|
||||
cd $RESPATH
|
||||
|
@ -11,12 +11,10 @@ function output() {
|
||||
}
|
||||
|
||||
function outfile() {
|
||||
test -s "$1" || return
|
||||
cat "$1" >> "out-$logfile.md"
|
||||
}
|
||||
|
||||
function outfile_plain() {
|
||||
test -s "$1" || return
|
||||
output "<pre>"
|
||||
cat "$1" >> "out-$logfile.md"
|
||||
output "</pre>"
|
||||
@ -45,6 +43,8 @@ if [ ! -f out-1.md ]; then
|
||||
tar xf "$tarfile"
|
||||
test -s env.txt || continue
|
||||
source env.txt
|
||||
# when uname.txt is there, the other files are also ok
|
||||
test -s uname.txt || continue
|
||||
output "\n## Functional Tests: $OSNAME\n"
|
||||
outfile_plain uname.txt
|
||||
outfile_plain summary.txt
|
||||
|
8
.github/workflows/scripts/qemu-prepare-for-build.sh
vendored
Executable file
8
.github/workflows/scripts/qemu-prepare-for-build.sh
vendored
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Helper script to run after installing dependencies. This brings the VM back
|
||||
# up and copies over the zfs source directory.
|
||||
echo "Build modules in QEMU machine"
|
||||
sudo virsh start openzfs
|
||||
.github/workflows/scripts/qemu-wait-for-vm.sh vm0
|
||||
rsync -ar $HOME/work/zfs/zfs zfs@vm0:./
|
90
.github/workflows/scripts/qemu-test-repo-vm.sh
vendored
Executable file
90
.github/workflows/scripts/qemu-test-repo-vm.sh
vendored
Executable file
@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Do a test install of ZFS from an external repository.
|
||||
#
|
||||
# USAGE:
|
||||
#
|
||||
# ./qemu-test-repo-vm [URL]
|
||||
#
|
||||
# URL: URL to use instead of http://download.zfsonlinux.org
|
||||
# If blank, use the default repo from zfs-release RPM.
|
||||
|
||||
set -e
|
||||
|
||||
source /etc/os-release
|
||||
OS="$ID"
|
||||
VERSION="$VERSION_ID"
|
||||
|
||||
ALTHOST=""
|
||||
if [ -n "$1" ] ; then
|
||||
ALTHOST="$1"
|
||||
fi
|
||||
|
||||
# Write summary to /tmp/repo so our artifacts scripts pick it up
|
||||
mkdir /tmp/repo
|
||||
SUMMARY=/tmp/repo/$OS-$VERSION-summary.txt
|
||||
|
||||
# $1: Repo 'zfs' 'zfs-kmod' 'zfs-testing' 'zfs-testing-kmod'
|
||||
# $2: (optional) Alternate host than 'http://download.zfsonlinux.org' to
|
||||
# install from. Blank means use default from zfs-release RPM.
|
||||
function test_install {
|
||||
repo=$1
|
||||
host=""
|
||||
if [ -n "$2" ] ; then
|
||||
host=$2
|
||||
fi
|
||||
|
||||
args="--disablerepo=zfs --enablerepo=$repo"
|
||||
|
||||
# If we supplied an alternate repo URL, and have not already edited
|
||||
# zfs.repo, then update the repo file.
|
||||
if [ -n "$host" ] && ! grep -q $host /etc/yum.repos.d/zfs.repo ; then
|
||||
sudo sed -i "s;baseurl=http://download.zfsonlinux.org;baseurl=$host;g" /etc/yum.repos.d/zfs.repo
|
||||
fi
|
||||
|
||||
sudo dnf -y install $args zfs zfs-test
|
||||
|
||||
# Load modules and create a simple pool as a sanity test.
|
||||
sudo /usr/share/zfs/zfs.sh -r
|
||||
truncate -s 100M /tmp/file
|
||||
sudo zpool create tank /tmp/file
|
||||
sudo zpool status
|
||||
|
||||
# Print out repo name, rpm installed (kmod or dkms), and repo URL
|
||||
baseurl=$(grep -A 5 "\[$repo\]" /etc/yum.repos.d/zfs.repo | awk -F'=' '/baseurl=/{print $2; exit}')
|
||||
package=$(sudo rpm -qa | grep zfs | grep -E 'kmod|dkms')
|
||||
|
||||
echo "$repo $package $baseurl" >> $SUMMARY
|
||||
|
||||
sudo zpool destroy tank
|
||||
sudo rm /tmp/file
|
||||
sudo dnf -y remove zfs
|
||||
}
|
||||
|
||||
echo "##[group]Installing from repo"
|
||||
# The openzfs docs are the authoritative instructions for the install. Use
|
||||
# the specific version of zfs-release RPM it recommends.
|
||||
case $OS in
|
||||
almalinux*)
|
||||
url='https://raw.githubusercontent.com/openzfs/openzfs-docs/refs/heads/master/docs/Getting%20Started/RHEL-based%20distro/index.rst'
|
||||
name=$(curl -Ls $url | grep 'dnf install' | grep -Eo 'zfs-release-[0-9]+-[0-9]+')
|
||||
sudo dnf -y install https://zfsonlinux.org/epel/$name$(rpm --eval "%{dist}").noarch.rpm 2>&1
|
||||
sudo rpm -qi zfs-release
|
||||
test_install zfs $ALTHOST
|
||||
test_install zfs-kmod $ALTHOST
|
||||
test_install zfs-testing $ALTHOST
|
||||
test_install zfs-testing-kmod $ALTHOST
|
||||
;;
|
||||
fedora*)
|
||||
url='https://raw.githubusercontent.com/openzfs/openzfs-docs/refs/heads/master/docs/Getting%20Started/Fedora/index.rst'
|
||||
name=$(curl -Ls $url | grep 'dnf install' | grep -Eo 'zfs-release-[0-9]+-[0-9]+')
|
||||
sudo dnf -y install -y https://zfsonlinux.org/fedora/$name$(rpm --eval "%{dist}").noarch.rpm
|
||||
test_install zfs $ALTHOST
|
||||
;;
|
||||
esac
|
||||
echo "##[endgroup]"
|
||||
|
||||
# Write out a simple version of the summary here. Later on we will collate all
|
||||
# the summaries and put them into a nice table in the workflow Summary page.
|
||||
echo "Summary: "
|
||||
cat $SUMMARY
|
10
.github/workflows/scripts/qemu-wait-for-vm.sh
vendored
Executable file
10
.github/workflows/scripts/qemu-wait-for-vm.sh
vendored
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Wait for a VM to boot up and become active. This is used in a number of our
|
||||
# scripts.
|
||||
#
|
||||
# $1: VM hostname or IP address
|
||||
|
||||
while pidof /usr/bin/qemu-system-x86_64 >/dev/null; do
|
||||
ssh 2>/dev/null zfs@$1 "uname -a" && break
|
||||
done
|
32
.github/workflows/scripts/replace-dupes-with-symlinks.sh
vendored
Executable file
32
.github/workflows/scripts/replace-dupes-with-symlinks.sh
vendored
Executable file
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Recursively go though a directory structure and replace duplicate files with
|
||||
# symlinks. This cuts down our RPM repo size by ~25%.
|
||||
#
|
||||
# replace-dupes-with-symlinks.sh [DIR]
|
||||
#
|
||||
# DIR: Directory to traverse. Defaults to current directory if not specified.
|
||||
#
|
||||
|
||||
src="$1"
|
||||
if [ -z "$src" ] ; then
|
||||
src="."
|
||||
fi
|
||||
|
||||
declare -A db
|
||||
|
||||
pushd "$src"
|
||||
while read line ; do
|
||||
bn="$(basename $line)"
|
||||
if [ -z "${db[$bn]}" ] ; then
|
||||
# First time this file has been seen
|
||||
db[$bn]="$line"
|
||||
else
|
||||
if diff -b "$line" "${db[$bn]}" &>/dev/null ; then
|
||||
# Files are the same, make a symlink
|
||||
rm "$line"
|
||||
ln -sr "${db[$bn]}" "$line"
|
||||
fi
|
||||
fi
|
||||
done <<< "$(find . -type f)"
|
||||
popd
|
140
.github/workflows/zfs-qemu-packages.yml
vendored
Normal file
140
.github/workflows/zfs-qemu-packages.yml
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
# This workflow is used to build and test RPM packages. It is a
|
||||
# 'workflow_dispatch' workflow, which means it gets run manually.
|
||||
#
|
||||
# The workflow has a dropdown menu with two options:
|
||||
#
|
||||
# Build RPMs - Build release RPMs and tarballs and put them into an artifact
|
||||
# ZIP file. The directory structure used in the ZIP file mirrors
|
||||
# the ZFS yum repo.
|
||||
#
|
||||
# Test repo - Test install the ZFS RPMs from the ZFS repo. On EL distos, this
|
||||
# will do a DKMS and KMOD test install from both the regular and
|
||||
# testing repos. On Fedora, it will do a DKMS install from the
|
||||
# regular repo. All test install results will be displayed in the
|
||||
# Summary page. Note that the workflow provides an optional text
|
||||
# text box where you can specify the full URL to an alternate repo.
|
||||
# If left blank, it will install from the default repo from the
|
||||
# zfs-release RPM (http://download.zfsonlinux.org).
|
||||
#
|
||||
# Most users will never need to use this workflow. It will be used primary by
|
||||
# ZFS admins for building and testing releases.
|
||||
#
|
||||
name: zfs-qemu-packages
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
test_type:
|
||||
type: choice
|
||||
required: false
|
||||
default: "Build RPMs"
|
||||
description: "Build RPMs or test the repo?"
|
||||
options:
|
||||
- "Build RPMs"
|
||||
- "Test repo"
|
||||
repo_url:
|
||||
type: string
|
||||
required: false
|
||||
default: ""
|
||||
description: "(optional) repo URL (blank: use http://download.zfsonlinux.org)"
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
zfs-qemu-packages-jobs:
|
||||
name: qemu-VMs
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ['almalinux8', 'almalinux9', 'fedora40', 'fedora41']
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Setup QEMU
|
||||
timeout-minutes: 10
|
||||
run: .github/workflows/scripts/qemu-1-setup.sh
|
||||
|
||||
- name: Start build machine
|
||||
timeout-minutes: 10
|
||||
run: .github/workflows/scripts/qemu-2-start.sh ${{ matrix.os }}
|
||||
|
||||
- name: Install dependencies
|
||||
timeout-minutes: 20
|
||||
run: |
|
||||
.github/workflows/scripts/qemu-3-deps.sh ${{ matrix.os }}
|
||||
|
||||
- name: Build modules or Test repo
|
||||
timeout-minutes: 30
|
||||
run: |
|
||||
set -e
|
||||
if [ "${{ github.event.inputs.test_type }}" == "Test repo" ] ; then
|
||||
# Bring VM back up and copy over zfs source
|
||||
.github/workflows/scripts/qemu-prepare-for-build.sh
|
||||
|
||||
mkdir -p /tmp/repo
|
||||
ssh zfs@vm0 '$HOME/zfs/.github/workflows/scripts/qemu-test-repo-vm.sh' ${{ github.event.inputs.repo_url }}
|
||||
else
|
||||
.github/workflows/scripts/qemu-4-build.sh --repo --release --dkms --tarball ${{ matrix.os }}
|
||||
fi
|
||||
|
||||
- name: Prepare artifacts
|
||||
if: always()
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
rsync -a zfs@vm0:/tmp/repo /tmp || true
|
||||
.github/workflows/scripts/replace-dupes-with-symlinks.sh /tmp/repo
|
||||
tar -cf ${{ matrix.os }}-repo.tar -C /tmp repo
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
id: artifact-upload
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ matrix.os }}-repo
|
||||
path: ${{ matrix.os }}-repo.tar
|
||||
compression-level: 0
|
||||
retention-days: 2
|
||||
if-no-files-found: ignore
|
||||
|
||||
combine_repos:
|
||||
if: always()
|
||||
needs: [zfs-qemu-packages-jobs]
|
||||
name: "Results"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
id: artifact-download
|
||||
if: always()
|
||||
- name: Test Summary
|
||||
if: always()
|
||||
run: |
|
||||
for i in $(find . -type f -iname "*.tar") ; do
|
||||
tar -xf $i -C /tmp
|
||||
done
|
||||
tar -cf all-repo.tar -C /tmp repo
|
||||
|
||||
# If we're installing from a repo, print out the summary of the versions
|
||||
# that got installed using Markdown.
|
||||
if [ "${{ github.event.inputs.test_type }}" == "Test repo" ] ; then
|
||||
cd /tmp/repo
|
||||
for i in $(ls *.txt) ; do
|
||||
nicename="$(echo $i | sed 's/.txt//g; s/-/ /g')"
|
||||
echo "### $nicename" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|repo|RPM|URL|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|:---|:---|:---|" >> $GITHUB_STEP_SUMMARY
|
||||
awk '{print "|"$1"|"$2"|"$3"|"}' $i >> $GITHUB_STEP_SUMMARY
|
||||
done
|
||||
fi
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
id: artifact-upload2
|
||||
if: always()
|
||||
with:
|
||||
name: all-repo
|
||||
path: all-repo.tar
|
||||
compression-level: 0
|
||||
retention-days: 5
|
||||
if-no-files-found: ignore
|
61
.github/workflows/zfs-qemu.yml
vendored
61
.github/workflows/zfs-qemu.yml
vendored
@ -3,6 +3,18 @@ name: zfs-qemu
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
include_stream9:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
description: 'Test on CentOS 9 stream'
|
||||
include_stream10:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
description: 'Test on CentOS 10 stream'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
@ -22,8 +34,8 @@ jobs:
|
||||
- name: Generate OS config and CI type
|
||||
id: os
|
||||
run: |
|
||||
FULL_OS='["almalinux8", "almalinux9", "centos-stream9", "debian11", "debian12", "fedora39", "fedora40", "freebsd13", "freebsd13r", "freebsd14", "freebsd14r", "ubuntu20", "ubuntu22", "ubuntu24"]'
|
||||
QUICK_OS='["almalinux8", "almalinux9", "debian12", "fedora40", "freebsd13", "freebsd14", "ubuntu24"]'
|
||||
FULL_OS='["almalinux8", "almalinux9", "debian11", "debian12", "fedora40", "fedora41", "freebsd13-3r", "freebsd13-4s", "freebsd14-1r", "freebsd14-2s", "freebsd15-0c", "ubuntu20", "ubuntu22", "ubuntu24"]'
|
||||
QUICK_OS='["almalinux8", "almalinux9", "debian12", "fedora41", "freebsd13-3r", "freebsd14-2r", "ubuntu24"]'
|
||||
# determine CI type when running on PR
|
||||
ci_type="full"
|
||||
if ${{ github.event_name == 'pull_request' }}; then
|
||||
@ -37,6 +49,16 @@ jobs:
|
||||
os_selection="$FULL_OS"
|
||||
fi
|
||||
os_json=$(echo ${os_selection} | jq -c)
|
||||
|
||||
# Add optional runners
|
||||
if [ "${{ github.event.inputs.include_stream9 }}" == 'true' ]; then
|
||||
os_json=$(echo $os_json | jq -c '. += ["centos-stream9"]')
|
||||
fi
|
||||
if [ "${{ github.event.inputs.include_stream10 }}" == 'true' ]; then
|
||||
os_json=$(echo $os_json | jq -c '. += ["centos-stream10"]')
|
||||
fi
|
||||
|
||||
echo $os_json
|
||||
echo "os=$os_json" >> $GITHUB_OUTPUT
|
||||
echo "ci_type=$ci_type" >> $GITHUB_OUTPUT
|
||||
|
||||
@ -46,10 +68,13 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# all:
|
||||
# os: [almalinux8, almalinux9, archlinux, centos-stream9, fedora39, fedora40, debian11, debian12, freebsd13, freebsd13r, freebsd14, freebsd14r, freebsd15, ubuntu20, ubuntu22, ubuntu24]
|
||||
# openzfs:
|
||||
# os: [almalinux8, almalinux9, centos-stream9, debian11, debian12, fedora39, fedora40, freebsd13, freebsd13r, freebsd14, freebsd14r, ubuntu20, ubuntu22, ubuntu24]
|
||||
# rhl: almalinux8, almalinux9, centos-stream9, fedora40, fedora41
|
||||
# debian: debian11, debian12, ubuntu20, ubuntu22, ubuntu24
|
||||
# misc: archlinux, tumbleweed
|
||||
# FreeBSD variants of 2024-12:
|
||||
# FreeBSD Release: freebsd13-3r, freebsd13-4r, freebsd14-1r, freebsd14-2r
|
||||
# FreeBSD Stable: freebsd13-4s, freebsd14-2s
|
||||
# FreeBSD Current: freebsd15-0c
|
||||
os: ${{ fromJson(needs.test-config.outputs.test_os) }}
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
@ -67,31 +92,11 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
timeout-minutes: 20
|
||||
run: |
|
||||
echo "Install dependencies in QEMU machine"
|
||||
IP=192.168.122.10
|
||||
while pidof /usr/bin/qemu-system-x86_64 >/dev/null; do
|
||||
ssh 2>/dev/null zfs@$IP "uname -a" && break
|
||||
done
|
||||
scp .github/workflows/scripts/qemu-3-deps.sh zfs@$IP:qemu-3-deps.sh
|
||||
PID=`pidof /usr/bin/qemu-system-x86_64`
|
||||
ssh zfs@$IP '$HOME/qemu-3-deps.sh' ${{ matrix.os }}
|
||||
# wait for poweroff to succeed
|
||||
tail --pid=$PID -f /dev/null
|
||||
sleep 5 # avoid this: "error: Domain is already active"
|
||||
rm -f $HOME/.ssh/known_hosts
|
||||
run: .github/workflows/scripts/qemu-3-deps.sh ${{ matrix.os }}
|
||||
|
||||
- name: Build modules
|
||||
timeout-minutes: 30
|
||||
run: |
|
||||
echo "Build modules in QEMU machine"
|
||||
sudo virsh start openzfs
|
||||
IP=192.168.122.10
|
||||
while pidof /usr/bin/qemu-system-x86_64 >/dev/null; do
|
||||
ssh 2>/dev/null zfs@$IP "uname -a" && break
|
||||
done
|
||||
rsync -ar $HOME/work/zfs/zfs zfs@$IP:./
|
||||
ssh zfs@$IP '$HOME/zfs/.github/workflows/scripts/qemu-4-build.sh' ${{ matrix.os }}
|
||||
run: .github/workflows/scripts/qemu-4-build.sh --poweroff --enable-debug ${{ matrix.os }}
|
||||
|
||||
- name: Setup testing machines
|
||||
timeout-minutes: 5
|
||||
|
2
.github/workflows/zloop.yml
vendored
2
.github/workflows/zloop.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get purge -y snapd google-chrome-stable firefox
|
||||
ONLY_DEPS=1 .github/workflows/scripts/qemu-3-deps.sh ubuntu24
|
||||
ONLY_DEPS=1 .github/workflows/scripts/qemu-3-deps-vm.sh ubuntu24
|
||||
- name: Autogen.sh
|
||||
run: |
|
||||
sed -i '/DEBUG_CFLAGS="-Werror"/s/^/#/' config/zfs-build.m4
|
||||
|
2
.mailmap
2
.mailmap
@ -70,6 +70,7 @@ Rob Norris <robn@despairlabs.com>
|
||||
Rob Norris <rob.norris@klarasystems.com>
|
||||
Sam Lunt <samuel.j.lunt@gmail.com>
|
||||
Sanjeev Bagewadi <sanjeev.bagewadi@gmail.com>
|
||||
Sebastian Wuerl <s.wuerl@mailbox.org>
|
||||
Stoiko Ivanov <github@nomore.at>
|
||||
Tamas TEVESZ <ice@extreme.hu>
|
||||
WHR <msl0000023508@gmail.com>
|
||||
@ -78,6 +79,7 @@ Youzhong Yang <youzhong@gmail.com>
|
||||
|
||||
# Signed-off-by: overriding Author:
|
||||
Ryan <errornointernet@envs.net> <error.nointernet@gmail.com>
|
||||
Sietse <sietse@wizdom.nu> <uglymotha@wizdom.nu>
|
||||
Qiuhao Chen <chenqiuhao1997@gmail.com> <haohao0924@126.com>
|
||||
Yuxin Wang <yuxinwang9999@gmail.com> <Bi11gates9999@gmail.com>
|
||||
Zhenlei Huang <zlei@FreeBSD.org> <zlei.huang@gmail.com>
|
||||
|
4
AUTHORS
4
AUTHORS
@ -423,6 +423,7 @@ CONTRIBUTORS:
|
||||
Mathieu Velten <matmaul@gmail.com>
|
||||
Matt Fiddaman <github@m.fiddaman.uk>
|
||||
Matthew Ahrens <matt@delphix.com>
|
||||
Matthew Heller <matthew.f.heller@gmail.com>
|
||||
Matthew Thode <mthode@mthode.org>
|
||||
Matthias Blankertz <matthias@blankertz.org>
|
||||
Matt Johnston <matt@fugro-fsi.com.au>
|
||||
@ -562,6 +563,7 @@ CONTRIBUTORS:
|
||||
Scot W. Stevenson <scot.stevenson@gmail.com>
|
||||
Sean Eric Fagan <sef@ixsystems.com>
|
||||
Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
||||
Sebastian Wuerl <s.wuerl@mailbox.org>
|
||||
Sebastien Roy <seb@delphix.com>
|
||||
Sen Haerens <sen@senhaerens.be>
|
||||
Serapheim Dimitropoulos <serapheim@delphix.com>
|
||||
@ -574,6 +576,7 @@ CONTRIBUTORS:
|
||||
Shawn Bayern <sbayern@law.fsu.edu>
|
||||
Shengqi Chen <harry-chen@outlook.com>
|
||||
Shen Yan <shenyanxxxy@qq.com>
|
||||
Sietse <sietse@wizdom.nu>
|
||||
Simon Guest <simon.guest@tesujimath.org>
|
||||
Simon Klinkert <simon.klinkert@gmail.com>
|
||||
Sowrabha Gopal <sowrabha.gopal@delphix.com>
|
||||
@ -629,6 +632,7 @@ CONTRIBUTORS:
|
||||
Trevor Bautista <trevrb@trevrb.net>
|
||||
Trey Dockendorf <treydock@gmail.com>
|
||||
Troels Nørgaard <tnn@tradeshift.com>
|
||||
tstabrawa <tstabrawa@users.noreply.github.com>
|
||||
Tulsi Jain <tulsi.jain@delphix.com>
|
||||
Turbo Fredriksson <turbo@bayour.com>
|
||||
Tyler J. Stachecki <stachecki.tyler@gmail.com>
|
||||
|
6
META
6
META
@ -1,10 +1,10 @@
|
||||
Meta: 1
|
||||
Name: zfs
|
||||
Branch: 1.0
|
||||
Version: 2.3.0
|
||||
Release: rc1
|
||||
Version: 2.3.1
|
||||
Release: 1
|
||||
Release-Tags: relext
|
||||
License: CDDL
|
||||
Author: OpenZFS
|
||||
Linux-Maximum: 6.11
|
||||
Linux-Maximum: 6.13
|
||||
Linux-Minimum: 4.18
|
||||
|
@ -28,7 +28,7 @@ Two release branches are maintained for OpenZFS, they are:
|
||||
Minor changes to support these distribution kernels will be applied as
|
||||
needed. New kernel versions released after the OpenZFS LTS release are
|
||||
not supported. LTS releases will receive patches for at least 2 years.
|
||||
The current LTS release is OpenZFS 2.1.
|
||||
The current LTS release is OpenZFS 2.2.
|
||||
|
||||
* OpenZFS current - Tracks the newest MAJOR.MINOR release. This branch
|
||||
includes support for the latest OpenZFS features and recently releases
|
||||
|
@ -662,10 +662,7 @@ def section_arc(kstats_dict):
|
||||
print()
|
||||
|
||||
print('ARC hash breakdown:')
|
||||
prt_i1('Elements max:', f_hits(arc_stats['hash_elements_max']))
|
||||
prt_i2('Elements current:',
|
||||
f_perc(arc_stats['hash_elements'], arc_stats['hash_elements_max']),
|
||||
f_hits(arc_stats['hash_elements']))
|
||||
prt_i1('Elements:', f_hits(arc_stats['hash_elements']))
|
||||
prt_i1('Collisions:', f_hits(arc_stats['hash_collisions']))
|
||||
|
||||
prt_i1('Chain max:', f_hits(arc_stats['hash_chain_max']))
|
||||
|
293
cmd/zdb/zdb.c
293
cmd/zdb/zdb.c
@ -122,7 +122,7 @@ static int flagbits[256];
|
||||
|
||||
static uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */
|
||||
static int leaked_objects = 0;
|
||||
static range_tree_t *mos_refd_objs;
|
||||
static zfs_range_tree_t *mos_refd_objs;
|
||||
static spa_t *spa;
|
||||
static objset_t *os;
|
||||
static boolean_t kernel_init_done;
|
||||
@ -325,7 +325,7 @@ typedef struct metaslab_verify {
|
||||
/*
|
||||
* What's currently allocated for this metaslab.
|
||||
*/
|
||||
range_tree_t *mv_allocated;
|
||||
zfs_range_tree_t *mv_allocated;
|
||||
} metaslab_verify_t;
|
||||
|
||||
typedef void ll_iter_t(dsl_deadlist_t *ll, void *arg);
|
||||
@ -417,7 +417,7 @@ metaslab_spacemap_validation_cb(space_map_entry_t *sme, void *arg)
|
||||
uint64_t txg = sme->sme_txg;
|
||||
|
||||
if (sme->sme_type == SM_ALLOC) {
|
||||
if (range_tree_contains(mv->mv_allocated,
|
||||
if (zfs_range_tree_contains(mv->mv_allocated,
|
||||
offset, size)) {
|
||||
(void) printf("ERROR: DOUBLE ALLOC: "
|
||||
"%llu [%llx:%llx] "
|
||||
@ -426,11 +426,11 @@ metaslab_spacemap_validation_cb(space_map_entry_t *sme, void *arg)
|
||||
(u_longlong_t)size, (u_longlong_t)mv->mv_vdid,
|
||||
(u_longlong_t)mv->mv_msid);
|
||||
} else {
|
||||
range_tree_add(mv->mv_allocated,
|
||||
zfs_range_tree_add(mv->mv_allocated,
|
||||
offset, size);
|
||||
}
|
||||
} else {
|
||||
if (!range_tree_contains(mv->mv_allocated,
|
||||
if (!zfs_range_tree_contains(mv->mv_allocated,
|
||||
offset, size)) {
|
||||
(void) printf("ERROR: DOUBLE FREE: "
|
||||
"%llu [%llx:%llx] "
|
||||
@ -439,7 +439,7 @@ metaslab_spacemap_validation_cb(space_map_entry_t *sme, void *arg)
|
||||
(u_longlong_t)size, (u_longlong_t)mv->mv_vdid,
|
||||
(u_longlong_t)mv->mv_msid);
|
||||
} else {
|
||||
range_tree_remove(mv->mv_allocated,
|
||||
zfs_range_tree_remove(mv->mv_allocated,
|
||||
offset, size);
|
||||
}
|
||||
}
|
||||
@ -614,11 +614,11 @@ livelist_metaslab_validate(spa_t *spa)
|
||||
(longlong_t)vd->vdev_ms_count);
|
||||
|
||||
uint64_t shift, start;
|
||||
range_seg_type_t type =
|
||||
zfs_range_seg_type_t type =
|
||||
metaslab_calculate_range_tree_type(vd, m,
|
||||
&start, &shift);
|
||||
metaslab_verify_t mv;
|
||||
mv.mv_allocated = range_tree_create(NULL,
|
||||
mv.mv_allocated = zfs_range_tree_create(NULL,
|
||||
type, NULL, start, shift);
|
||||
mv.mv_vdid = vd->vdev_id;
|
||||
mv.mv_msid = m->ms_id;
|
||||
@ -633,8 +633,8 @@ livelist_metaslab_validate(spa_t *spa)
|
||||
spacemap_check_ms_sm(m->ms_sm, &mv);
|
||||
spacemap_check_sm_log(spa, &mv);
|
||||
|
||||
range_tree_vacate(mv.mv_allocated, NULL, NULL);
|
||||
range_tree_destroy(mv.mv_allocated);
|
||||
zfs_range_tree_vacate(mv.mv_allocated, NULL, NULL);
|
||||
zfs_range_tree_destroy(mv.mv_allocated);
|
||||
zfs_btree_clear(&mv.mv_livelist_allocs);
|
||||
zfs_btree_destroy(&mv.mv_livelist_allocs);
|
||||
}
|
||||
@ -1131,7 +1131,7 @@ dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
|
||||
!!(zap_getflags(zc.zc_zap) & ZAP_FLAG_UINT64_KEY);
|
||||
|
||||
if (key64)
|
||||
(void) printf("\t\t0x%010lx = ",
|
||||
(void) printf("\t\t0x%010" PRIu64 "x = ",
|
||||
*(uint64_t *)attrp->za_name);
|
||||
else
|
||||
(void) printf("\t\t%s = ", attrp->za_name);
|
||||
@ -1633,9 +1633,9 @@ static void
|
||||
dump_metaslab_stats(metaslab_t *msp)
|
||||
{
|
||||
char maxbuf[32];
|
||||
range_tree_t *rt = msp->ms_allocatable;
|
||||
zfs_range_tree_t *rt = msp->ms_allocatable;
|
||||
zfs_btree_t *t = &msp->ms_allocatable_by_size;
|
||||
int free_pct = range_tree_space(rt) * 100 / msp->ms_size;
|
||||
int free_pct = zfs_range_tree_space(rt) * 100 / msp->ms_size;
|
||||
|
||||
/* max sure nicenum has enough space */
|
||||
_Static_assert(sizeof (maxbuf) >= NN_NUMBUF_SZ, "maxbuf truncated");
|
||||
@ -1646,7 +1646,7 @@ dump_metaslab_stats(metaslab_t *msp)
|
||||
"segments", zfs_btree_numnodes(t), "maxsize", maxbuf,
|
||||
"freepct", free_pct);
|
||||
(void) printf("\tIn-memory histogram:\n");
|
||||
dump_histogram(rt->rt_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
|
||||
dump_histogram(rt->rt_histogram, ZFS_RANGE_TREE_HISTOGRAM_SIZE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1668,7 +1668,7 @@ dump_metaslab(metaslab_t *msp)
|
||||
if (dump_opt['m'] > 2 && !dump_opt['L']) {
|
||||
mutex_enter(&msp->ms_lock);
|
||||
VERIFY0(metaslab_load(msp));
|
||||
range_tree_stat_verify(msp->ms_allocatable);
|
||||
zfs_range_tree_stat_verify(msp->ms_allocatable);
|
||||
dump_metaslab_stats(msp);
|
||||
metaslab_unload(msp);
|
||||
mutex_exit(&msp->ms_lock);
|
||||
@ -1769,7 +1769,8 @@ dump_metaslab_groups(spa_t *spa, boolean_t show_special)
|
||||
(void) printf("%3llu%%\n",
|
||||
(u_longlong_t)mg->mg_fragmentation);
|
||||
}
|
||||
dump_histogram(mg->mg_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
|
||||
dump_histogram(mg->mg_histogram,
|
||||
ZFS_RANGE_TREE_HISTOGRAM_SIZE, 0);
|
||||
}
|
||||
|
||||
(void) printf("\tpool %s\tfragmentation", spa_name(spa));
|
||||
@ -1778,7 +1779,7 @@ dump_metaslab_groups(spa_t *spa, boolean_t show_special)
|
||||
(void) printf("\t%3s\n", "-");
|
||||
else
|
||||
(void) printf("\t%3llu%%\n", (u_longlong_t)fragmentation);
|
||||
dump_histogram(mc->mc_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
|
||||
dump_histogram(mc->mc_histogram, ZFS_RANGE_TREE_HISTOGRAM_SIZE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1967,17 +1968,53 @@ dump_dedup_ratio(const ddt_stat_t *dds)
|
||||
static void
|
||||
dump_ddt_log(ddt_t *ddt)
|
||||
{
|
||||
if (ddt->ddt_version != DDT_VERSION_FDT ||
|
||||
!(ddt->ddt_flags & DDT_FLAG_LOG))
|
||||
return;
|
||||
|
||||
for (int n = 0; n < 2; n++) {
|
||||
ddt_log_t *ddl = &ddt->ddt_log[n];
|
||||
|
||||
char flagstr[64] = {0};
|
||||
if (ddl->ddl_flags > 0) {
|
||||
flagstr[0] = ' ';
|
||||
int c = 1;
|
||||
if (ddl->ddl_flags & DDL_FLAG_FLUSHING)
|
||||
c += strlcpy(&flagstr[c], " FLUSHING",
|
||||
sizeof (flagstr) - c);
|
||||
if (ddl->ddl_flags & DDL_FLAG_CHECKPOINT)
|
||||
c += strlcpy(&flagstr[c], " CHECKPOINT",
|
||||
sizeof (flagstr) - c);
|
||||
if (ddl->ddl_flags &
|
||||
~(DDL_FLAG_FLUSHING|DDL_FLAG_CHECKPOINT))
|
||||
c += strlcpy(&flagstr[c], " UNKNOWN",
|
||||
sizeof (flagstr) - c);
|
||||
flagstr[1] = '[';
|
||||
flagstr[c++] = ']';
|
||||
}
|
||||
|
||||
uint64_t count = avl_numnodes(&ddl->ddl_tree);
|
||||
if (count == 0)
|
||||
continue;
|
||||
|
||||
printf(DMU_POOL_DDT_LOG ": %lu log entries\n",
|
||||
zio_checksum_table[ddt->ddt_checksum].ci_name, n, count);
|
||||
printf(DMU_POOL_DDT_LOG ": flags=0x%02x%s; obj=%llu; "
|
||||
"len=%llu; txg=%llu; entries=%llu\n",
|
||||
zio_checksum_table[ddt->ddt_checksum].ci_name, n,
|
||||
ddl->ddl_flags, flagstr,
|
||||
(u_longlong_t)ddl->ddl_object,
|
||||
(u_longlong_t)ddl->ddl_length,
|
||||
(u_longlong_t)ddl->ddl_first_txg, (u_longlong_t)count);
|
||||
|
||||
if (dump_opt['D'] < 4)
|
||||
if (ddl->ddl_flags & DDL_FLAG_CHECKPOINT) {
|
||||
const ddt_key_t *ddk = &ddl->ddl_checkpoint;
|
||||
printf(" checkpoint: "
|
||||
"%016llx:%016llx:%016llx:%016llx:%016llx\n",
|
||||
(u_longlong_t)ddk->ddk_cksum.zc_word[0],
|
||||
(u_longlong_t)ddk->ddk_cksum.zc_word[1],
|
||||
(u_longlong_t)ddk->ddk_cksum.zc_word[2],
|
||||
(u_longlong_t)ddk->ddk_cksum.zc_word[3],
|
||||
(u_longlong_t)ddk->ddk_prop);
|
||||
}
|
||||
|
||||
if (count == 0 || dump_opt['D'] < 4)
|
||||
continue;
|
||||
|
||||
ddt_lightweight_entry_t ddlwe;
|
||||
@ -1991,7 +2028,7 @@ dump_ddt_log(ddt_t *ddt)
|
||||
}
|
||||
|
||||
static void
|
||||
dump_ddt(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
|
||||
dump_ddt_object(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
|
||||
{
|
||||
char name[DDT_NAMELEN];
|
||||
ddt_lightweight_entry_t ddlwe;
|
||||
@ -2016,11 +2053,8 @@ dump_ddt(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
|
||||
|
||||
ddt_object_name(ddt, type, class, name);
|
||||
|
||||
(void) printf("%s: %llu entries, size %llu on disk, %llu in core\n",
|
||||
name,
|
||||
(u_longlong_t)count,
|
||||
(u_longlong_t)dspace,
|
||||
(u_longlong_t)mspace);
|
||||
(void) printf("%s: dspace=%llu; mspace=%llu; entries=%llu\n", name,
|
||||
(u_longlong_t)dspace, (u_longlong_t)mspace, (u_longlong_t)count);
|
||||
|
||||
if (dump_opt['D'] < 3)
|
||||
return;
|
||||
@ -2043,24 +2077,52 @@ dump_ddt(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
|
||||
(void) printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
dump_ddt(ddt_t *ddt)
|
||||
{
|
||||
if (!ddt || ddt->ddt_version == DDT_VERSION_UNCONFIGURED)
|
||||
return;
|
||||
|
||||
char flagstr[64] = {0};
|
||||
if (ddt->ddt_flags > 0) {
|
||||
flagstr[0] = ' ';
|
||||
int c = 1;
|
||||
if (ddt->ddt_flags & DDT_FLAG_FLAT)
|
||||
c += strlcpy(&flagstr[c], " FLAT",
|
||||
sizeof (flagstr) - c);
|
||||
if (ddt->ddt_flags & DDT_FLAG_LOG)
|
||||
c += strlcpy(&flagstr[c], " LOG",
|
||||
sizeof (flagstr) - c);
|
||||
if (ddt->ddt_flags & ~DDT_FLAG_MASK)
|
||||
c += strlcpy(&flagstr[c], " UNKNOWN",
|
||||
sizeof (flagstr) - c);
|
||||
flagstr[1] = '[';
|
||||
flagstr[c] = ']';
|
||||
}
|
||||
|
||||
printf("DDT-%s: version=%llu [%s]; flags=0x%02llx%s; rootobj=%llu\n",
|
||||
zio_checksum_table[ddt->ddt_checksum].ci_name,
|
||||
(u_longlong_t)ddt->ddt_version,
|
||||
(ddt->ddt_version == 0) ? "LEGACY" :
|
||||
(ddt->ddt_version == 1) ? "FDT" : "UNKNOWN",
|
||||
(u_longlong_t)ddt->ddt_flags, flagstr,
|
||||
(u_longlong_t)ddt->ddt_dir_object);
|
||||
|
||||
for (ddt_type_t type = 0; type < DDT_TYPES; type++)
|
||||
for (ddt_class_t class = 0; class < DDT_CLASSES; class++)
|
||||
dump_ddt_object(ddt, type, class);
|
||||
|
||||
dump_ddt_log(ddt);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_all_ddts(spa_t *spa)
|
||||
{
|
||||
ddt_histogram_t ddh_total = {{{0}}};
|
||||
ddt_stat_t dds_total = {0};
|
||||
|
||||
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
|
||||
ddt_t *ddt = spa->spa_ddt[c];
|
||||
if (!ddt || ddt->ddt_version == DDT_VERSION_UNCONFIGURED)
|
||||
continue;
|
||||
for (ddt_type_t type = 0; type < DDT_TYPES; type++) {
|
||||
for (ddt_class_t class = 0; class < DDT_CLASSES;
|
||||
class++) {
|
||||
dump_ddt(ddt, type, class);
|
||||
}
|
||||
}
|
||||
dump_ddt_log(ddt);
|
||||
}
|
||||
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++)
|
||||
dump_ddt(spa->spa_ddt[c]);
|
||||
|
||||
ddt_get_dedup_stats(spa, &dds_total);
|
||||
|
||||
@ -2119,9 +2181,6 @@ dump_brt(spa_t *spa)
|
||||
return;
|
||||
}
|
||||
|
||||
brt_t *brt = spa->spa_brt;
|
||||
VERIFY(brt);
|
||||
|
||||
char count[32], used[32], saved[32];
|
||||
zdb_nicebytes(brt_get_used(spa), used, sizeof (used));
|
||||
zdb_nicebytes(brt_get_saved(spa), saved, sizeof (saved));
|
||||
@ -2132,11 +2191,8 @@ dump_brt(spa_t *spa)
|
||||
if (dump_opt['T'] < 2)
|
||||
return;
|
||||
|
||||
for (uint64_t vdevid = 0; vdevid < brt->brt_nvdevs; vdevid++) {
|
||||
brt_vdev_t *brtvd = &brt->brt_vdevs[vdevid];
|
||||
if (brtvd == NULL)
|
||||
continue;
|
||||
|
||||
for (uint64_t vdevid = 0; vdevid < spa->spa_brt_nvdevs; vdevid++) {
|
||||
brt_vdev_t *brtvd = spa->spa_brt_vdevs[vdevid];
|
||||
if (!brtvd->bv_initiated) {
|
||||
printf("BRT: vdev %" PRIu64 ": empty\n", vdevid);
|
||||
continue;
|
||||
@ -2152,34 +2208,54 @@ dump_brt(spa_t *spa)
|
||||
if (dump_opt['T'] < 3)
|
||||
return;
|
||||
|
||||
char dva[64];
|
||||
printf("\n%-16s %-10s\n", "DVA", "REFCNT");
|
||||
/* -TTT shows a per-vdev histograms; -TTTT shows all entries */
|
||||
boolean_t do_histo = dump_opt['T'] == 3;
|
||||
|
||||
for (uint64_t vdevid = 0; vdevid < brt->brt_nvdevs; vdevid++) {
|
||||
brt_vdev_t *brtvd = &brt->brt_vdevs[vdevid];
|
||||
if (brtvd == NULL || !brtvd->bv_initiated)
|
||||
char dva[64];
|
||||
|
||||
if (!do_histo)
|
||||
printf("\n%-16s %-10s\n", "DVA", "REFCNT");
|
||||
|
||||
for (uint64_t vdevid = 0; vdevid < spa->spa_brt_nvdevs; vdevid++) {
|
||||
brt_vdev_t *brtvd = spa->spa_brt_vdevs[vdevid];
|
||||
if (!brtvd->bv_initiated)
|
||||
continue;
|
||||
|
||||
uint64_t counts[64] = {};
|
||||
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, brt->brt_mos, brtvd->bv_mos_entries);
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset,
|
||||
brtvd->bv_mos_entries);
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
uint64_t refcnt;
|
||||
VERIFY0(zap_lookup_uint64(brt->brt_mos,
|
||||
VERIFY0(zap_lookup_uint64(spa->spa_meta_objset,
|
||||
brtvd->bv_mos_entries,
|
||||
(const uint64_t *)za->za_name, 1,
|
||||
za->za_integer_length, za->za_num_integers,
|
||||
&refcnt));
|
||||
|
||||
uint64_t offset = *(const uint64_t *)za->za_name;
|
||||
if (do_histo)
|
||||
counts[highbit64(refcnt)]++;
|
||||
else {
|
||||
uint64_t offset =
|
||||
*(const uint64_t *)za->za_name;
|
||||
|
||||
snprintf(dva, sizeof (dva), "%" PRIu64 ":%llx", vdevid,
|
||||
(u_longlong_t)offset);
|
||||
printf("%-16s %-10llu\n", dva, (u_longlong_t)refcnt);
|
||||
snprintf(dva, sizeof (dva), "%" PRIu64 ":%llx",
|
||||
vdevid, (u_longlong_t)offset);
|
||||
printf("%-16s %-10llu\n", dva,
|
||||
(u_longlong_t)refcnt);
|
||||
}
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
|
||||
if (do_histo) {
|
||||
printf("\nBRT: vdev %" PRIu64
|
||||
": DVAs with 2^n refcnts:\n", vdevid);
|
||||
dump_histogram(counts, 64, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2217,12 +2293,12 @@ dump_dtl(vdev_t *vd, int indent)
|
||||
required ? "DTL-required" : "DTL-expendable");
|
||||
|
||||
for (int t = 0; t < DTL_TYPES; t++) {
|
||||
range_tree_t *rt = vd->vdev_dtl[t];
|
||||
if (range_tree_space(rt) == 0)
|
||||
zfs_range_tree_t *rt = vd->vdev_dtl[t];
|
||||
if (zfs_range_tree_space(rt) == 0)
|
||||
continue;
|
||||
(void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
|
||||
indent + 2, "", name[t]);
|
||||
range_tree_walk(rt, dump_dtl_seg, prefix);
|
||||
zfs_range_tree_walk(rt, dump_dtl_seg, prefix);
|
||||
if (dump_opt['d'] > 5 && vd->vdev_children == 0)
|
||||
dump_spacemap(spa->spa_meta_objset,
|
||||
vd->vdev_dtl_sm);
|
||||
@ -4266,6 +4342,10 @@ dump_uberblock(uberblock_t *ub, const char *header, const char *footer)
|
||||
(void) printf("\ttimestamp = %llu UTC = %s",
|
||||
(u_longlong_t)ub->ub_timestamp, ctime(×tamp));
|
||||
|
||||
char blkbuf[BP_SPRINTF_LEN];
|
||||
snprintf_blkptr(blkbuf, sizeof (blkbuf), &ub->ub_rootbp);
|
||||
(void) printf("\tbp = %s\n", blkbuf);
|
||||
|
||||
(void) printf("\tmmp_magic = %016llx\n",
|
||||
(u_longlong_t)ub->ub_mmp_magic);
|
||||
if (MMP_VALID(ub)) {
|
||||
@ -6179,9 +6259,9 @@ load_unflushed_svr_segs_cb(spa_t *spa, space_map_entry_t *sme,
|
||||
return (0);
|
||||
|
||||
if (sme->sme_type == SM_ALLOC)
|
||||
range_tree_add(svr->svr_allocd_segs, offset, size);
|
||||
zfs_range_tree_add(svr->svr_allocd_segs, offset, size);
|
||||
else
|
||||
range_tree_remove(svr->svr_allocd_segs, offset, size);
|
||||
zfs_range_tree_remove(svr->svr_allocd_segs, offset, size);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -6235,18 +6315,20 @@ zdb_claim_removing(spa_t *spa, zdb_cb_t *zcb)
|
||||
vdev_t *vd = vdev_lookup_top(spa, svr->svr_vdev_id);
|
||||
vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping;
|
||||
|
||||
ASSERT0(range_tree_space(svr->svr_allocd_segs));
|
||||
ASSERT0(zfs_range_tree_space(svr->svr_allocd_segs));
|
||||
|
||||
range_tree_t *allocs = range_tree_create(NULL, RANGE_SEG64, NULL, 0, 0);
|
||||
zfs_range_tree_t *allocs = zfs_range_tree_create(NULL, ZFS_RANGE_SEG64,
|
||||
NULL, 0, 0);
|
||||
for (uint64_t msi = 0; msi < vd->vdev_ms_count; msi++) {
|
||||
metaslab_t *msp = vd->vdev_ms[msi];
|
||||
|
||||
ASSERT0(range_tree_space(allocs));
|
||||
ASSERT0(zfs_range_tree_space(allocs));
|
||||
if (msp->ms_sm != NULL)
|
||||
VERIFY0(space_map_load(msp->ms_sm, allocs, SM_ALLOC));
|
||||
range_tree_vacate(allocs, range_tree_add, svr->svr_allocd_segs);
|
||||
zfs_range_tree_vacate(allocs, zfs_range_tree_add,
|
||||
svr->svr_allocd_segs);
|
||||
}
|
||||
range_tree_destroy(allocs);
|
||||
zfs_range_tree_destroy(allocs);
|
||||
|
||||
iterate_through_spacemap_logs(spa, load_unflushed_svr_segs_cb, svr);
|
||||
|
||||
@ -6255,12 +6337,12 @@ zdb_claim_removing(spa_t *spa, zdb_cb_t *zcb)
|
||||
* because we have not allocated mappings for
|
||||
* it yet.
|
||||
*/
|
||||
range_tree_clear(svr->svr_allocd_segs,
|
||||
zfs_range_tree_clear(svr->svr_allocd_segs,
|
||||
vdev_indirect_mapping_max_offset(vim),
|
||||
vd->vdev_asize - vdev_indirect_mapping_max_offset(vim));
|
||||
|
||||
zcb->zcb_removing_size += range_tree_space(svr->svr_allocd_segs);
|
||||
range_tree_vacate(svr->svr_allocd_segs, claim_segment_cb, vd);
|
||||
zcb->zcb_removing_size += zfs_range_tree_space(svr->svr_allocd_segs);
|
||||
zfs_range_tree_vacate(svr->svr_allocd_segs, claim_segment_cb, vd);
|
||||
|
||||
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
||||
}
|
||||
@ -6363,7 +6445,8 @@ checkpoint_sm_exclude_entry_cb(space_map_entry_t *sme, void *arg)
|
||||
* also verify that the entry is there to begin with.
|
||||
*/
|
||||
mutex_enter(&ms->ms_lock);
|
||||
range_tree_remove(ms->ms_allocatable, sme->sme_offset, sme->sme_run);
|
||||
zfs_range_tree_remove(ms->ms_allocatable, sme->sme_offset,
|
||||
sme->sme_run);
|
||||
mutex_exit(&ms->ms_lock);
|
||||
|
||||
cseea->cseea_checkpoint_size += sme->sme_run;
|
||||
@ -6494,9 +6577,9 @@ load_unflushed_cb(spa_t *spa, space_map_entry_t *sme, uint64_t txg, void *arg)
|
||||
return (0);
|
||||
|
||||
if (*uic_maptype == sme->sme_type)
|
||||
range_tree_add(ms->ms_allocatable, offset, size);
|
||||
zfs_range_tree_add(ms->ms_allocatable, offset, size);
|
||||
else
|
||||
range_tree_remove(ms->ms_allocatable, offset, size);
|
||||
zfs_range_tree_remove(ms->ms_allocatable, offset, size);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -6530,7 +6613,7 @@ load_concrete_ms_allocatable_trees(spa_t *spa, maptype_t maptype)
|
||||
(longlong_t)vd->vdev_ms_count);
|
||||
|
||||
mutex_enter(&msp->ms_lock);
|
||||
range_tree_vacate(msp->ms_allocatable, NULL, NULL);
|
||||
zfs_range_tree_vacate(msp->ms_allocatable, NULL, NULL);
|
||||
|
||||
/*
|
||||
* We don't want to spend the CPU manipulating the
|
||||
@ -6563,7 +6646,7 @@ load_indirect_ms_allocatable_tree(vdev_t *vd, metaslab_t *msp,
|
||||
vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping;
|
||||
|
||||
mutex_enter(&msp->ms_lock);
|
||||
range_tree_vacate(msp->ms_allocatable, NULL, NULL);
|
||||
zfs_range_tree_vacate(msp->ms_allocatable, NULL, NULL);
|
||||
|
||||
/*
|
||||
* We don't want to spend the CPU manipulating the
|
||||
@ -6587,7 +6670,7 @@ load_indirect_ms_allocatable_tree(vdev_t *vd, metaslab_t *msp,
|
||||
*/
|
||||
ASSERT3U(ent_offset + ent_len, <=,
|
||||
msp->ms_start + msp->ms_size);
|
||||
range_tree_add(msp->ms_allocatable, ent_offset, ent_len);
|
||||
zfs_range_tree_add(msp->ms_allocatable, ent_offset, ent_len);
|
||||
}
|
||||
|
||||
if (!msp->ms_loaded)
|
||||
@ -6733,7 +6816,7 @@ zdb_check_for_obsolete_leaks(vdev_t *vd, zdb_cb_t *zcb)
|
||||
for (uint64_t inner_offset = 0;
|
||||
inner_offset < DVA_GET_ASIZE(&vimep->vimep_dst);
|
||||
inner_offset += 1ULL << vd->vdev_ashift) {
|
||||
if (range_tree_contains(msp->ms_allocatable,
|
||||
if (zfs_range_tree_contains(msp->ms_allocatable,
|
||||
offset + inner_offset, 1ULL << vd->vdev_ashift)) {
|
||||
obsolete_bytes += 1ULL << vd->vdev_ashift;
|
||||
}
|
||||
@ -6816,10 +6899,10 @@ zdb_leak_fini(spa_t *spa, zdb_cb_t *zcb)
|
||||
* not referenced, which is not a bug.
|
||||
*/
|
||||
if (vd->vdev_ops == &vdev_indirect_ops) {
|
||||
range_tree_vacate(msp->ms_allocatable,
|
||||
zfs_range_tree_vacate(msp->ms_allocatable,
|
||||
NULL, NULL);
|
||||
} else {
|
||||
range_tree_vacate(msp->ms_allocatable,
|
||||
zfs_range_tree_vacate(msp->ms_allocatable,
|
||||
zdb_leak, vd);
|
||||
}
|
||||
if (msp->ms_loaded) {
|
||||
@ -6874,7 +6957,7 @@ iterate_deleted_livelists(spa_t *spa, ll_iter_t func, void *arg)
|
||||
for (zap_cursor_init(&zc, mos, zap_obj);
|
||||
zap_cursor_retrieve(&zc, attrp) == 0;
|
||||
(void) zap_cursor_advance(&zc)) {
|
||||
dsl_deadlist_open(&ll, mos, attrp->za_first_integer);
|
||||
VERIFY0(dsl_deadlist_open(&ll, mos, attrp->za_first_integer));
|
||||
func(&ll, arg);
|
||||
dsl_deadlist_close(&ll);
|
||||
}
|
||||
@ -7717,7 +7800,7 @@ verify_checkpoint_sm_entry_cb(space_map_entry_t *sme, void *arg)
|
||||
* their respective ms_allocateable trees should not contain them.
|
||||
*/
|
||||
mutex_enter(&ms->ms_lock);
|
||||
range_tree_verify_not_present(ms->ms_allocatable,
|
||||
zfs_range_tree_verify_not_present(ms->ms_allocatable,
|
||||
sme->sme_offset, sme->sme_run);
|
||||
mutex_exit(&ms->ms_lock);
|
||||
|
||||
@ -7868,8 +7951,9 @@ verify_checkpoint_ms_spacemaps(spa_t *checkpoint, spa_t *current)
|
||||
* This way we ensure that none of the blocks that
|
||||
* are part of the checkpoint were freed by mistake.
|
||||
*/
|
||||
range_tree_walk(ckpoint_msp->ms_allocatable,
|
||||
(range_tree_func_t *)range_tree_verify_not_present,
|
||||
zfs_range_tree_walk(ckpoint_msp->ms_allocatable,
|
||||
(zfs_range_tree_func_t *)
|
||||
zfs_range_tree_verify_not_present,
|
||||
current_msp->ms_allocatable);
|
||||
}
|
||||
}
|
||||
@ -8009,7 +8093,7 @@ static void
|
||||
mos_obj_refd(uint64_t obj)
|
||||
{
|
||||
if (obj != 0 && mos_refd_objs != NULL)
|
||||
range_tree_add(mos_refd_objs, obj, 1);
|
||||
zfs_range_tree_add(mos_refd_objs, obj, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -8019,8 +8103,8 @@ static void
|
||||
mos_obj_refd_multiple(uint64_t obj)
|
||||
{
|
||||
if (obj != 0 && mos_refd_objs != NULL &&
|
||||
!range_tree_contains(mos_refd_objs, obj, 1))
|
||||
range_tree_add(mos_refd_objs, obj, 1);
|
||||
!zfs_range_tree_contains(mos_refd_objs, obj, 1))
|
||||
zfs_range_tree_add(mos_refd_objs, obj, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -8204,14 +8288,11 @@ dump_mos_leaks(spa_t *spa)
|
||||
}
|
||||
}
|
||||
|
||||
if (spa->spa_brt != NULL) {
|
||||
brt_t *brt = spa->spa_brt;
|
||||
for (uint64_t vdevid = 0; vdevid < brt->brt_nvdevs; vdevid++) {
|
||||
brt_vdev_t *brtvd = &brt->brt_vdevs[vdevid];
|
||||
if (brtvd != NULL && brtvd->bv_initiated) {
|
||||
mos_obj_refd(brtvd->bv_mos_brtvdev);
|
||||
mos_obj_refd(brtvd->bv_mos_entries);
|
||||
}
|
||||
for (uint64_t vdevid = 0; vdevid < spa->spa_brt_nvdevs; vdevid++) {
|
||||
brt_vdev_t *brtvd = spa->spa_brt_vdevs[vdevid];
|
||||
if (brtvd->bv_initiated) {
|
||||
mos_obj_refd(brtvd->bv_mos_brtvdev);
|
||||
mos_obj_refd(brtvd->bv_mos_entries);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8220,8 +8301,8 @@ dump_mos_leaks(spa_t *spa)
|
||||
*/
|
||||
uint64_t object = 0;
|
||||
while (dmu_object_next(mos, &object, B_FALSE, 0) == 0) {
|
||||
if (range_tree_contains(mos_refd_objs, object, 1)) {
|
||||
range_tree_remove(mos_refd_objs, object, 1);
|
||||
if (zfs_range_tree_contains(mos_refd_objs, object, 1)) {
|
||||
zfs_range_tree_remove(mos_refd_objs, object, 1);
|
||||
} else {
|
||||
dmu_object_info_t doi;
|
||||
const char *name;
|
||||
@ -8239,11 +8320,11 @@ dump_mos_leaks(spa_t *spa)
|
||||
rv = 2;
|
||||
}
|
||||
}
|
||||
(void) range_tree_walk(mos_refd_objs, mos_leaks_cb, NULL);
|
||||
if (!range_tree_is_empty(mos_refd_objs))
|
||||
(void) zfs_range_tree_walk(mos_refd_objs, mos_leaks_cb, NULL);
|
||||
if (!zfs_range_tree_is_empty(mos_refd_objs))
|
||||
rv = 2;
|
||||
range_tree_vacate(mos_refd_objs, NULL, NULL);
|
||||
range_tree_destroy(mos_refd_objs);
|
||||
zfs_range_tree_vacate(mos_refd_objs, NULL, NULL);
|
||||
zfs_range_tree_destroy(mos_refd_objs);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
@ -8365,8 +8446,8 @@ dump_zpool(spa_t *spa)
|
||||
|
||||
if (dump_opt['d'] || dump_opt['i']) {
|
||||
spa_feature_t f;
|
||||
mos_refd_objs = range_tree_create(NULL, RANGE_SEG64, NULL, 0,
|
||||
0);
|
||||
mos_refd_objs = zfs_range_tree_create(NULL, ZFS_RANGE_SEG64,
|
||||
NULL, 0, 0);
|
||||
dump_objset(dp->dp_meta_objset);
|
||||
|
||||
if (dump_opt['d'] >= 3) {
|
||||
@ -8962,7 +9043,7 @@ zdb_read_block(char *thing, spa_t *spa)
|
||||
const blkptr_t *b = (const blkptr_t *)(void *)
|
||||
((uintptr_t)buf + (uintptr_t)blkptr_offset);
|
||||
if (zfs_blkptr_verify(spa, b,
|
||||
BLK_CONFIG_NEEDED, BLK_VERIFY_ONLY) == B_FALSE) {
|
||||
BLK_CONFIG_NEEDED, BLK_VERIFY_ONLY)) {
|
||||
abd_return_buf_copy(pabd, buf, lsize);
|
||||
borrowed = B_FALSE;
|
||||
buf = lbuf;
|
||||
@ -8971,7 +9052,7 @@ zdb_read_block(char *thing, spa_t *spa)
|
||||
b = (const blkptr_t *)(void *)
|
||||
((uintptr_t)buf + (uintptr_t)blkptr_offset);
|
||||
if (lsize == -1 || zfs_blkptr_verify(spa, b,
|
||||
BLK_CONFIG_NEEDED, BLK_VERIFY_LOG) == B_FALSE) {
|
||||
BLK_CONFIG_NEEDED, BLK_VERIFY_LOG)) {
|
||||
printf("invalid block pointer at this DVA\n");
|
||||
goto out;
|
||||
}
|
||||
|
@ -67,19 +67,19 @@ zil_prt_rec_create(zilog_t *zilog, int txtype, const void *arg)
|
||||
const lr_create_t *lrc = arg;
|
||||
const _lr_create_t *lr = &lrc->lr_create;
|
||||
time_t crtime = lr->lr_crtime[0];
|
||||
char *name, *link;
|
||||
const char *name, *link;
|
||||
lr_attr_t *lrattr;
|
||||
|
||||
name = (char *)(lr + 1);
|
||||
name = (const char *)&lrc->lr_data[0];
|
||||
|
||||
if (lr->lr_common.lrc_txtype == TX_CREATE_ATTR ||
|
||||
lr->lr_common.lrc_txtype == TX_MKDIR_ATTR) {
|
||||
lrattr = (lr_attr_t *)(lr + 1);
|
||||
lrattr = (lr_attr_t *)&lrc->lr_data[0];
|
||||
name += ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
|
||||
}
|
||||
|
||||
if (txtype == TX_SYMLINK) {
|
||||
link = name + strlen(name) + 1;
|
||||
link = (const char *)&lrc->lr_data[strlen(name) + 1];
|
||||
(void) printf("%s%s -> %s\n", tab_prefix, name, link);
|
||||
} else if (txtype != TX_MKXATTR) {
|
||||
(void) printf("%s%s\n", tab_prefix, name);
|
||||
@ -104,7 +104,7 @@ zil_prt_rec_remove(zilog_t *zilog, int txtype, const void *arg)
|
||||
const lr_remove_t *lr = arg;
|
||||
|
||||
(void) printf("%sdoid %llu, name %s\n", tab_prefix,
|
||||
(u_longlong_t)lr->lr_doid, (char *)(lr + 1));
|
||||
(u_longlong_t)lr->lr_doid, (const char *)&lr->lr_data[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -115,7 +115,7 @@ zil_prt_rec_link(zilog_t *zilog, int txtype, const void *arg)
|
||||
|
||||
(void) printf("%sdoid %llu, link_obj %llu, name %s\n", tab_prefix,
|
||||
(u_longlong_t)lr->lr_doid, (u_longlong_t)lr->lr_link_obj,
|
||||
(char *)(lr + 1));
|
||||
(const char *)&lr->lr_data[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -124,8 +124,8 @@ zil_prt_rec_rename(zilog_t *zilog, int txtype, const void *arg)
|
||||
(void) zilog, (void) txtype;
|
||||
const lr_rename_t *lrr = arg;
|
||||
const _lr_rename_t *lr = &lrr->lr_rename;
|
||||
char *snm = (char *)(lr + 1);
|
||||
char *tnm = snm + strlen(snm) + 1;
|
||||
const char *snm = (const char *)&lrr->lr_data[0];
|
||||
const char *tnm = (const char *)&lrr->lr_data[strlen(snm) + 1];
|
||||
|
||||
(void) printf("%ssdoid %llu, tdoid %llu\n", tab_prefix,
|
||||
(u_longlong_t)lr->lr_sdoid, (u_longlong_t)lr->lr_tdoid);
|
||||
@ -211,7 +211,7 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
|
||||
|
||||
/* data is stored after the end of the lr_write record */
|
||||
data = abd_alloc(lr->lr_length, B_FALSE);
|
||||
abd_copy_from_buf(data, lr + 1, lr->lr_length);
|
||||
abd_copy_from_buf(data, &lr->lr_data[0], lr->lr_length);
|
||||
}
|
||||
|
||||
(void) printf("%s", tab_prefix);
|
||||
@ -309,7 +309,7 @@ zil_prt_rec_setsaxattr(zilog_t *zilog, int txtype, const void *arg)
|
||||
(void) zilog, (void) txtype;
|
||||
const lr_setsaxattr_t *lr = arg;
|
||||
|
||||
char *name = (char *)(lr + 1);
|
||||
const char *name = (const char *)&lr->lr_data[0];
|
||||
(void) printf("%sfoid %llu\n", tab_prefix,
|
||||
(u_longlong_t)lr->lr_foid);
|
||||
|
||||
@ -318,7 +318,7 @@ zil_prt_rec_setsaxattr(zilog_t *zilog, int txtype, const void *arg)
|
||||
(void) printf("%sXAT_VALUE NULL\n", tab_prefix);
|
||||
} else {
|
||||
(void) printf("%sXAT_VALUE ", tab_prefix);
|
||||
char *val = name + (strlen(name) + 1);
|
||||
const char *val = (const char *)&lr->lr_data[strlen(name) + 1];
|
||||
for (int i = 0; i < lr->lr_size; i++) {
|
||||
(void) printf("%c", *val);
|
||||
val++;
|
||||
|
@ -445,8 +445,8 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
||||
* its a loopback event from spa_async_remove(). Just
|
||||
* ignore it.
|
||||
*/
|
||||
if (vs->vs_state == VDEV_STATE_REMOVED &&
|
||||
state == VDEV_STATE_REMOVED)
|
||||
if ((vs->vs_state == VDEV_STATE_REMOVED && state ==
|
||||
VDEV_STATE_REMOVED) || vs->vs_state == VDEV_STATE_OFFLINE)
|
||||
return;
|
||||
|
||||
/* Remove the vdev since device is unplugged */
|
||||
|
@ -139,7 +139,8 @@ dev_event_nvlist(struct udev_device *dev)
|
||||
* is /dev/sda.
|
||||
*/
|
||||
struct udev_device *parent_dev = udev_device_get_parent(dev);
|
||||
if ((value = udev_device_get_sysattr_value(parent_dev, "size"))
|
||||
if (parent_dev != NULL &&
|
||||
(value = udev_device_get_sysattr_value(parent_dev, "size"))
|
||||
!= NULL) {
|
||||
uint64_t numval = DEV_BSIZE;
|
||||
|
||||
|
@ -500,7 +500,7 @@ usage_prop_cb(int prop, void *cb)
|
||||
{
|
||||
FILE *fp = cb;
|
||||
|
||||
(void) fprintf(fp, "\t%-15s ", zfs_prop_to_name(prop));
|
||||
(void) fprintf(fp, "\t%-22s ", zfs_prop_to_name(prop));
|
||||
|
||||
if (zfs_prop_readonly(prop))
|
||||
(void) fprintf(fp, " NO ");
|
||||
@ -561,40 +561,40 @@ usage(boolean_t requested)
|
||||
(void) fprintf(fp, "%s",
|
||||
gettext("\nThe following properties are supported:\n"));
|
||||
|
||||
(void) fprintf(fp, "\n\t%-14s %s %s %s\n\n",
|
||||
(void) fprintf(fp, "\n\t%-21s %s %s %s\n\n",
|
||||
"PROPERTY", "EDIT", "INHERIT", "VALUES");
|
||||
|
||||
/* Iterate over all properties */
|
||||
(void) zprop_iter(usage_prop_cb, fp, B_FALSE, B_TRUE,
|
||||
ZFS_TYPE_DATASET);
|
||||
|
||||
(void) fprintf(fp, "\t%-15s ", "userused@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "userused@...");
|
||||
(void) fprintf(fp, " NO NO <size>\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "groupused@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "groupused@...");
|
||||
(void) fprintf(fp, " NO NO <size>\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "projectused@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "projectused@...");
|
||||
(void) fprintf(fp, " NO NO <size>\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "userobjused@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "userobjused@...");
|
||||
(void) fprintf(fp, " NO NO <size>\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "groupobjused@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "groupobjused@...");
|
||||
(void) fprintf(fp, " NO NO <size>\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "projectobjused@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "projectobjused@...");
|
||||
(void) fprintf(fp, " NO NO <size>\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "userquota@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "userquota@...");
|
||||
(void) fprintf(fp, "YES NO <size> | none\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "groupquota@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "groupquota@...");
|
||||
(void) fprintf(fp, "YES NO <size> | none\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "projectquota@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "projectquota@...");
|
||||
(void) fprintf(fp, "YES NO <size> | none\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "userobjquota@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "userobjquota@...");
|
||||
(void) fprintf(fp, "YES NO <size> | none\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "groupobjquota@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "groupobjquota@...");
|
||||
(void) fprintf(fp, "YES NO <size> | none\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "projectobjquota@...");
|
||||
(void) fprintf(fp, "\t%-22s ", "projectobjquota@...");
|
||||
(void) fprintf(fp, "YES NO <size> | none\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "written@<snap>");
|
||||
(void) fprintf(fp, "\t%-22s ", "written@<snap>");
|
||||
(void) fprintf(fp, " NO NO <size>\n");
|
||||
(void) fprintf(fp, "\t%-15s ", "written#<bookmark>");
|
||||
(void) fprintf(fp, "\t%-22s ", "written#<bookmark>");
|
||||
(void) fprintf(fp, " NO NO <size>\n");
|
||||
|
||||
(void) fprintf(fp, gettext("\nSizes are specified in bytes "
|
||||
@ -2162,6 +2162,7 @@ zfs_do_get(int argc, char **argv)
|
||||
cb.cb_type = ZFS_TYPE_DATASET;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"json", no_argument, NULL, 'j'},
|
||||
{"json-int", no_argument, NULL, ZFS_OPTION_JSON_NUMS_AS_INT},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
@ -3760,8 +3761,13 @@ collect_dataset(zfs_handle_t *zhp, list_cbdata_t *cb)
|
||||
if (cb->cb_json) {
|
||||
if (pl->pl_prop == ZFS_PROP_NAME)
|
||||
continue;
|
||||
const char *prop_name;
|
||||
if (pl->pl_prop != ZPROP_USERPROP)
|
||||
prop_name = zfs_prop_to_name(pl->pl_prop);
|
||||
else
|
||||
prop_name = pl->pl_user_prop;
|
||||
if (zprop_nvlist_one_property(
|
||||
zfs_prop_to_name(pl->pl_prop), propstr,
|
||||
prop_name, propstr,
|
||||
sourcetype, source, NULL, props,
|
||||
cb->cb_json_as_int) != 0)
|
||||
nomem();
|
||||
@ -3852,6 +3858,7 @@ zfs_do_list(int argc, char **argv)
|
||||
nvlist_t *data = NULL;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"json", no_argument, NULL, 'j'},
|
||||
{"json-int", no_argument, NULL, ZFS_OPTION_JSON_NUMS_AS_INT},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
@ -7436,9 +7443,15 @@ share_mount(int op, int argc, char **argv)
|
||||
uint_t nthr;
|
||||
jsobj = data = item = NULL;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"json", no_argument, NULL, 'j'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, op == OP_MOUNT ? ":ajRlvo:Of" : "al"))
|
||||
!= -1) {
|
||||
while ((c = getopt_long(argc, argv,
|
||||
op == OP_MOUNT ? ":ajRlvo:Of" : "al",
|
||||
op == OP_MOUNT ? long_options : NULL, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
do_all = 1;
|
||||
@ -8374,8 +8387,14 @@ zfs_do_channel_program(int argc, char **argv)
|
||||
boolean_t sync_flag = B_TRUE, json_output = B_FALSE;
|
||||
zpool_handle_t *zhp;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"json", no_argument, NULL, 'j'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "nt:m:j")) != -1) {
|
||||
while ((c = getopt_long(argc, argv, "nt:m:j", long_options,
|
||||
NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 't':
|
||||
case 'm': {
|
||||
@ -9083,7 +9102,13 @@ zfs_do_version(int argc, char **argv)
|
||||
int c;
|
||||
nvlist_t *jsobj = NULL, *zfs_ver = NULL;
|
||||
boolean_t json = B_FALSE;
|
||||
while ((c = getopt(argc, argv, "j")) != -1) {
|
||||
|
||||
struct option long_options[] = {
|
||||
{"json", no_argument, NULL, 'j'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
while ((c = getopt_long(argc, argv, "j", long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'j':
|
||||
json = B_TRUE;
|
||||
@ -9187,7 +9212,7 @@ main(int argc, char **argv)
|
||||
* Special case '-V|--version'
|
||||
*/
|
||||
if ((strcmp(cmdname, "-V") == 0) || (strcmp(cmdname, "--version") == 0))
|
||||
return (zfs_do_version(argc, argv));
|
||||
return (zfs_version_print() != 0);
|
||||
|
||||
/*
|
||||
* Special case 'help'
|
||||
|
@ -22,7 +22,7 @@
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2017, Intel Corporation.
|
||||
* Copyright (c) 2023-2024, Klara Inc.
|
||||
* Copyright (c) 2023-2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -242,6 +242,36 @@ err_to_str(int err)
|
||||
return ("[unknown]");
|
||||
}
|
||||
|
||||
static const char *const iotypestrtable[ZINJECT_IOTYPES] = {
|
||||
[ZINJECT_IOTYPE_NULL] = "null",
|
||||
[ZINJECT_IOTYPE_READ] = "read",
|
||||
[ZINJECT_IOTYPE_WRITE] = "write",
|
||||
[ZINJECT_IOTYPE_FREE] = "free",
|
||||
[ZINJECT_IOTYPE_CLAIM] = "claim",
|
||||
[ZINJECT_IOTYPE_FLUSH] = "flush",
|
||||
[ZINJECT_IOTYPE_TRIM] = "trim",
|
||||
[ZINJECT_IOTYPE_ALL] = "all",
|
||||
[ZINJECT_IOTYPE_PROBE] = "probe",
|
||||
};
|
||||
|
||||
static zinject_iotype_t
|
||||
str_to_iotype(const char *arg)
|
||||
{
|
||||
for (uint_t iotype = 0; iotype < ZINJECT_IOTYPES; iotype++)
|
||||
if (iotypestrtable[iotype] != NULL &&
|
||||
strcasecmp(iotypestrtable[iotype], arg) == 0)
|
||||
return (iotype);
|
||||
return (ZINJECT_IOTYPES);
|
||||
}
|
||||
|
||||
static const char *
|
||||
iotype_to_str(zinject_iotype_t iotype)
|
||||
{
|
||||
if (iotype >= ZINJECT_IOTYPES || iotypestrtable[iotype] == NULL)
|
||||
return ("[unknown]");
|
||||
return (iotypestrtable[iotype]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print usage message.
|
||||
*/
|
||||
@ -404,27 +434,30 @@ print_data_handler(int id, const char *pool, zinject_record_t *record,
|
||||
|
||||
if (*count == 0) {
|
||||
(void) printf("%3s %-15s %-6s %-6s %-8s %3s %-4s "
|
||||
"%-15s\n", "ID", "POOL", "OBJSET", "OBJECT", "TYPE",
|
||||
"LVL", "DVAs", "RANGE");
|
||||
"%-15s %-6s %-15s\n", "ID", "POOL", "OBJSET", "OBJECT",
|
||||
"TYPE", "LVL", "DVAs", "RANGE", "MATCH", "INJECT");
|
||||
(void) printf("--- --------------- ------ "
|
||||
"------ -------- --- ---- ---------------\n");
|
||||
"------ -------- --- ---- --------------- "
|
||||
"------ ------\n");
|
||||
}
|
||||
|
||||
*count += 1;
|
||||
|
||||
(void) printf("%3d %-15s %-6llu %-6llu %-8s %-3d 0x%02x ",
|
||||
id, pool, (u_longlong_t)record->zi_objset,
|
||||
(u_longlong_t)record->zi_object, type_to_name(record->zi_type),
|
||||
record->zi_level, record->zi_dvas);
|
||||
|
||||
|
||||
if (record->zi_start == 0 &&
|
||||
record->zi_end == -1ULL)
|
||||
(void) printf("all\n");
|
||||
char rangebuf[32];
|
||||
if (record->zi_start == 0 && record->zi_end == -1ULL)
|
||||
snprintf(rangebuf, sizeof (rangebuf), "all");
|
||||
else
|
||||
(void) printf("[%llu, %llu]\n", (u_longlong_t)record->zi_start,
|
||||
snprintf(rangebuf, sizeof (rangebuf), "[%llu, %llu]",
|
||||
(u_longlong_t)record->zi_start,
|
||||
(u_longlong_t)record->zi_end);
|
||||
|
||||
|
||||
(void) printf("%3d %-15s %-6llu %-6llu %-8s %-3d 0x%02x %-15s "
|
||||
"%6lu %6lu\n", id, pool, (u_longlong_t)record->zi_objset,
|
||||
(u_longlong_t)record->zi_object, type_to_name(record->zi_type),
|
||||
record->zi_level, record->zi_dvas, rangebuf,
|
||||
record->zi_match_count, record->zi_inject_count);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -432,10 +465,6 @@ static int
|
||||
print_device_handler(int id, const char *pool, zinject_record_t *record,
|
||||
void *data)
|
||||
{
|
||||
static const char *iotypestr[] = {
|
||||
"null", "read", "write", "free", "claim", "flush", "trim", "all",
|
||||
};
|
||||
|
||||
int *count = data;
|
||||
|
||||
if (record->zi_guid == 0 || record->zi_func[0] != '\0')
|
||||
@ -445,11 +474,14 @@ print_device_handler(int id, const char *pool, zinject_record_t *record,
|
||||
return (0);
|
||||
|
||||
if (*count == 0) {
|
||||
(void) printf("%3s %-15s %-16s %-5s %-10s %-9s\n",
|
||||
"ID", "POOL", "GUID", "TYPE", "ERROR", "FREQ");
|
||||
(void) printf("%3s %-15s %-16s %-5s %-10s %-9s "
|
||||
"%-6s %-6s\n",
|
||||
"ID", "POOL", "GUID", "TYPE", "ERROR", "FREQ",
|
||||
"MATCH", "INJECT");
|
||||
(void) printf(
|
||||
"--- --------------- ---------------- "
|
||||
"----- ---------- ---------\n");
|
||||
"----- ---------- --------- "
|
||||
"------ ------\n");
|
||||
}
|
||||
|
||||
*count += 1;
|
||||
@ -457,9 +489,10 @@ print_device_handler(int id, const char *pool, zinject_record_t *record,
|
||||
double freq = record->zi_freq == 0 ? 100.0f :
|
||||
(((double)record->zi_freq) / ZI_PERCENTAGE_MAX) * 100.0f;
|
||||
|
||||
(void) printf("%3d %-15s %llx %-5s %-10s %8.4f%%\n", id, pool,
|
||||
(u_longlong_t)record->zi_guid, iotypestr[record->zi_iotype],
|
||||
err_to_str(record->zi_error), freq);
|
||||
(void) printf("%3d %-15s %llx %-5s %-10s %8.4f%% "
|
||||
"%6lu %6lu\n", id, pool, (u_longlong_t)record->zi_guid,
|
||||
iotype_to_str(record->zi_iotype), err_to_str(record->zi_error),
|
||||
freq, record->zi_match_count, record->zi_inject_count);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -477,18 +510,25 @@ print_delay_handler(int id, const char *pool, zinject_record_t *record,
|
||||
return (0);
|
||||
|
||||
if (*count == 0) {
|
||||
(void) printf("%3s %-15s %-15s %-15s %s\n",
|
||||
"ID", "POOL", "DELAY (ms)", "LANES", "GUID");
|
||||
(void) printf("--- --------------- --------------- "
|
||||
"--------------- ----------------\n");
|
||||
(void) printf("%3s %-15s %-16s %-10s %-5s %-9s "
|
||||
"%-6s %-6s\n",
|
||||
"ID", "POOL", "GUID", "DELAY (ms)", "LANES", "FREQ",
|
||||
"MATCH", "INJECT");
|
||||
(void) printf("--- --------------- ---------------- "
|
||||
"---------- ----- --------- "
|
||||
"------ ------\n");
|
||||
}
|
||||
|
||||
*count += 1;
|
||||
|
||||
(void) printf("%3d %-15s %-15llu %-15llu %llx\n", id, pool,
|
||||
double freq = record->zi_freq == 0 ? 100.0f :
|
||||
(((double)record->zi_freq) / ZI_PERCENTAGE_MAX) * 100.0f;
|
||||
|
||||
(void) printf("%3d %-15s %llx %10llu %5llu %8.4f%% "
|
||||
"%6lu %6lu\n", id, pool, (u_longlong_t)record->zi_guid,
|
||||
(u_longlong_t)NSEC2MSEC(record->zi_timer),
|
||||
(u_longlong_t)record->zi_nlanes,
|
||||
(u_longlong_t)record->zi_guid);
|
||||
freq, record->zi_match_count, record->zi_inject_count);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -852,7 +892,7 @@ main(int argc, char **argv)
|
||||
int quiet = 0;
|
||||
int error = 0;
|
||||
int domount = 0;
|
||||
int io_type = ZIO_TYPES;
|
||||
int io_type = ZINJECT_IOTYPE_ALL;
|
||||
int action = VDEV_STATE_UNKNOWN;
|
||||
err_type_t type = TYPE_INVAL;
|
||||
err_type_t label = TYPE_INVAL;
|
||||
@ -1046,19 +1086,8 @@ main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
if (strcasecmp(optarg, "read") == 0) {
|
||||
io_type = ZIO_TYPE_READ;
|
||||
} else if (strcasecmp(optarg, "write") == 0) {
|
||||
io_type = ZIO_TYPE_WRITE;
|
||||
} else if (strcasecmp(optarg, "free") == 0) {
|
||||
io_type = ZIO_TYPE_FREE;
|
||||
} else if (strcasecmp(optarg, "claim") == 0) {
|
||||
io_type = ZIO_TYPE_CLAIM;
|
||||
} else if (strcasecmp(optarg, "flush") == 0) {
|
||||
io_type = ZIO_TYPE_FLUSH;
|
||||
} else if (strcasecmp(optarg, "all") == 0) {
|
||||
io_type = ZIO_TYPES;
|
||||
} else {
|
||||
io_type = str_to_iotype(optarg);
|
||||
if (io_type == ZINJECT_IOTYPES) {
|
||||
(void) fprintf(stderr, "invalid I/O type "
|
||||
"'%s': must be 'read', 'write', 'free', "
|
||||
"'claim', 'flush' or 'all'\n", optarg);
|
||||
@ -1180,7 +1209,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (error == EILSEQ &&
|
||||
(record.zi_freq == 0 || io_type != ZIO_TYPE_READ)) {
|
||||
(record.zi_freq == 0 || io_type != ZINJECT_IOTYPE_READ)) {
|
||||
(void) fprintf(stderr, "device corrupt errors require "
|
||||
"io type read and a frequency value\n");
|
||||
libzfs_fini(g_zfs);
|
||||
@ -1195,9 +1224,9 @@ main(int argc, char **argv)
|
||||
|
||||
if (record.zi_nlanes) {
|
||||
switch (io_type) {
|
||||
case ZIO_TYPE_READ:
|
||||
case ZIO_TYPE_WRITE:
|
||||
case ZIO_TYPES:
|
||||
case ZINJECT_IOTYPE_READ:
|
||||
case ZINJECT_IOTYPE_WRITE:
|
||||
case ZINJECT_IOTYPE_ALL:
|
||||
break;
|
||||
default:
|
||||
(void) fprintf(stderr, "I/O type for a delay "
|
||||
|
@ -512,7 +512,8 @@ get_usage(zpool_help_t idx)
|
||||
return (gettext("\tinitialize [-c | -s | -u] [-w] <pool> "
|
||||
"[<device> ...]\n"));
|
||||
case HELP_SCRUB:
|
||||
return (gettext("\tscrub [-s | -p] [-w] [-e] <pool> ...\n"));
|
||||
return (gettext("\tscrub [-e | -s | -p | -C] [-w] "
|
||||
"<pool> ...\n"));
|
||||
case HELP_RESILVER:
|
||||
return (gettext("\tresilver <pool> ...\n"));
|
||||
case HELP_TRIM:
|
||||
@ -6882,8 +6883,13 @@ collect_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
|
||||
if (cb->cb_json) {
|
||||
if (pl->pl_prop == ZPOOL_PROP_NAME)
|
||||
continue;
|
||||
const char *prop_name;
|
||||
if (pl->pl_prop != ZPROP_USERPROP)
|
||||
prop_name = zpool_prop_to_name(pl->pl_prop);
|
||||
else
|
||||
prop_name = pl->pl_user_prop;
|
||||
(void) zprop_nvlist_one_property(
|
||||
zpool_prop_to_name(pl->pl_prop), propstr,
|
||||
prop_name, propstr,
|
||||
sourcetype, NULL, NULL, props, cb->cb_json_as_int);
|
||||
} else {
|
||||
/*
|
||||
@ -7340,6 +7346,7 @@ zpool_do_list(int argc, char **argv)
|
||||
current_prop_type = ZFS_TYPE_POOL;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"json", no_argument, NULL, 'j'},
|
||||
{"json-int", no_argument, NULL, ZPOOL_OPTION_JSON_NUMS_AS_INT},
|
||||
{"json-pool-key-guid", no_argument, NULL,
|
||||
ZPOOL_OPTION_POOL_KEY_GUID},
|
||||
@ -7965,8 +7972,11 @@ zpool_do_online(int argc, char **argv)
|
||||
|
||||
poolname = argv[0];
|
||||
|
||||
if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
|
||||
if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
|
||||
(void) fprintf(stderr, gettext("failed to open pool "
|
||||
"\"%s\""), poolname);
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
vdev_state_t oldstate;
|
||||
@ -7987,12 +7997,15 @@ zpool_do_online(int argc, char **argv)
|
||||
&l2cache, NULL);
|
||||
if (tgt == NULL) {
|
||||
ret = 1;
|
||||
(void) fprintf(stderr, gettext("couldn't find device "
|
||||
"\"%s\" in pool \"%s\"\n"), argv[i], poolname);
|
||||
continue;
|
||||
}
|
||||
uint_t vsc;
|
||||
oldstate = ((vdev_stat_t *)fnvlist_lookup_uint64_array(tgt,
|
||||
ZPOOL_CONFIG_VDEV_STATS, &vsc))->vs_state;
|
||||
if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
|
||||
if ((rc = zpool_vdev_online(zhp, argv[i], flags,
|
||||
&newstate)) == 0) {
|
||||
if (newstate != VDEV_STATE_HEALTHY) {
|
||||
(void) printf(gettext("warning: device '%s' "
|
||||
"onlined, but remains in faulted state\n"),
|
||||
@ -8018,6 +8031,9 @@ zpool_do_online(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(void) fprintf(stderr, gettext("Failed to online "
|
||||
"\"%s\" in pool \"%s\": %d\n"),
|
||||
argv[i], poolname, rc);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
@ -8102,8 +8118,11 @@ zpool_do_offline(int argc, char **argv)
|
||||
|
||||
poolname = argv[0];
|
||||
|
||||
if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
|
||||
if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
|
||||
(void) fprintf(stderr, gettext("failed to open pool "
|
||||
"\"%s\""), poolname);
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
uint64_t guid = zpool_vdev_path_to_guid(zhp, argv[i]);
|
||||
@ -8411,12 +8430,13 @@ wait_callback(zpool_handle_t *zhp, void *data)
|
||||
}
|
||||
|
||||
/*
|
||||
* zpool scrub [-s | -p] [-w] [-e] <pool> ...
|
||||
* zpool scrub [-e | -s | -p | -C] [-w] <pool> ...
|
||||
*
|
||||
* -e Only scrub blocks in the error log.
|
||||
* -s Stop. Stops any in-progress scrub.
|
||||
* -p Pause. Pause in-progress scrub.
|
||||
* -w Wait. Blocks until scrub has completed.
|
||||
* -C Scrub from last saved txg.
|
||||
*/
|
||||
int
|
||||
zpool_do_scrub(int argc, char **argv)
|
||||
@ -8432,9 +8452,10 @@ zpool_do_scrub(int argc, char **argv)
|
||||
boolean_t is_error_scrub = B_FALSE;
|
||||
boolean_t is_pause = B_FALSE;
|
||||
boolean_t is_stop = B_FALSE;
|
||||
boolean_t is_txg_continue = B_FALSE;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "spwe")) != -1) {
|
||||
while ((c = getopt(argc, argv, "spweC")) != -1) {
|
||||
switch (c) {
|
||||
case 'e':
|
||||
is_error_scrub = B_TRUE;
|
||||
@ -8448,6 +8469,9 @@ zpool_do_scrub(int argc, char **argv)
|
||||
case 'w':
|
||||
wait = B_TRUE;
|
||||
break;
|
||||
case 'C':
|
||||
is_txg_continue = B_TRUE;
|
||||
break;
|
||||
case '?':
|
||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||
optopt);
|
||||
@ -8457,7 +8481,19 @@ zpool_do_scrub(int argc, char **argv)
|
||||
|
||||
if (is_pause && is_stop) {
|
||||
(void) fprintf(stderr, gettext("invalid option "
|
||||
"combination :-s and -p are mutually exclusive\n"));
|
||||
"combination: -s and -p are mutually exclusive\n"));
|
||||
usage(B_FALSE);
|
||||
} else if (is_pause && is_txg_continue) {
|
||||
(void) fprintf(stderr, gettext("invalid option "
|
||||
"combination: -p and -C are mutually exclusive\n"));
|
||||
usage(B_FALSE);
|
||||
} else if (is_stop && is_txg_continue) {
|
||||
(void) fprintf(stderr, gettext("invalid option "
|
||||
"combination: -s and -C are mutually exclusive\n"));
|
||||
usage(B_FALSE);
|
||||
} else if (is_error_scrub && is_txg_continue) {
|
||||
(void) fprintf(stderr, gettext("invalid option "
|
||||
"combination: -e and -C are mutually exclusive\n"));
|
||||
usage(B_FALSE);
|
||||
} else {
|
||||
if (is_error_scrub)
|
||||
@ -8467,6 +8503,8 @@ zpool_do_scrub(int argc, char **argv)
|
||||
cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
|
||||
} else if (is_stop) {
|
||||
cb.cb_type = POOL_SCAN_NONE;
|
||||
} else if (is_txg_continue) {
|
||||
cb.cb_scrub_cmd = POOL_SCRUB_FROM_LAST_TXG;
|
||||
} else {
|
||||
cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
|
||||
}
|
||||
@ -9224,6 +9262,12 @@ vdev_stats_nvlist(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv,
|
||||
}
|
||||
}
|
||||
|
||||
if (cb->cb_print_dio_verify) {
|
||||
nice_num_str_nvlist(vds, "dio_verify_errors",
|
||||
vs->vs_dio_verify_errors, cb->cb_literal,
|
||||
cb->cb_json_as_int, ZFS_NICENUM_1024);
|
||||
}
|
||||
|
||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
|
||||
¬present) == 0) {
|
||||
nice_num_str_nvlist(vds, ZPOOL_CONFIG_NOT_PRESENT,
|
||||
@ -10010,9 +10054,8 @@ print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
|
||||
(void) printf(gettext("Removal of %s canceled on %s"),
|
||||
vdev_name, ctime(&end));
|
||||
} else {
|
||||
uint64_t copied, total, elapsed, mins_left, hours_left;
|
||||
uint64_t copied, total, elapsed, rate, mins_left, hours_left;
|
||||
double fraction_done;
|
||||
uint_t rate;
|
||||
|
||||
assert(prs->prs_state == DSS_SCANNING);
|
||||
|
||||
@ -10108,9 +10151,8 @@ print_raidz_expand_status(zpool_handle_t *zhp, pool_raidz_expand_stat_t *pres)
|
||||
copied_buf, time_buf, ctime((time_t *)&end));
|
||||
} else {
|
||||
char examined_buf[7], total_buf[7], rate_buf[7];
|
||||
uint64_t copied, total, elapsed, secs_left;
|
||||
uint64_t copied, total, elapsed, rate, secs_left;
|
||||
double fraction_done;
|
||||
uint_t rate;
|
||||
|
||||
assert(pres->pres_state == DSS_SCANNING);
|
||||
|
||||
@ -10975,6 +11017,7 @@ zpool_do_status(int argc, char **argv)
|
||||
|
||||
struct option long_options[] = {
|
||||
{"power", no_argument, NULL, ZPOOL_OPTION_POWER},
|
||||
{"json", no_argument, NULL, 'j'},
|
||||
{"json-int", no_argument, NULL, ZPOOL_OPTION_JSON_NUMS_AS_INT},
|
||||
{"json-flat-vdevs", no_argument, NULL,
|
||||
ZPOOL_OPTION_JSON_FLAT_VDEVS},
|
||||
@ -12583,6 +12626,7 @@ zpool_do_get(int argc, char **argv)
|
||||
current_prop_type = cb.cb_type;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"json", no_argument, NULL, 'j'},
|
||||
{"json-int", no_argument, NULL, ZPOOL_OPTION_JSON_NUMS_AS_INT},
|
||||
{"json-pool-key-guid", no_argument, NULL,
|
||||
ZPOOL_OPTION_POOL_KEY_GUID},
|
||||
@ -13497,7 +13541,12 @@ zpool_do_version(int argc, char **argv)
|
||||
int c;
|
||||
nvlist_t *jsobj = NULL, *zfs_ver = NULL;
|
||||
boolean_t json = B_FALSE;
|
||||
while ((c = getopt(argc, argv, "j")) != -1) {
|
||||
|
||||
struct option long_options[] = {
|
||||
{"json", no_argument, NULL, 'j'},
|
||||
};
|
||||
|
||||
while ((c = getopt_long(argc, argv, "j", long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'j':
|
||||
json = B_TRUE;
|
||||
@ -13613,7 +13662,7 @@ main(int argc, char **argv)
|
||||
* Special case '-V|--version'
|
||||
*/
|
||||
if ((strcmp(cmdname, "-V") == 0) || (strcmp(cmdname, "--version") == 0))
|
||||
return (zpool_do_version(argc, argv));
|
||||
return (zfs_version_print() != 0);
|
||||
|
||||
/*
|
||||
* Special case 'help'
|
||||
|
19
cmd/ztest.c
19
cmd/ztest.c
@ -6717,6 +6717,17 @@ out:
|
||||
*
|
||||
* Only after a full scrub has been completed is it safe to start injecting
|
||||
* data corruption. See the comment in zfs_fault_inject().
|
||||
*
|
||||
* EBUSY may be returned for the following six cases. It's the callers
|
||||
* responsibility to handle them accordingly.
|
||||
*
|
||||
* Current state Requested
|
||||
* 1. Normal Scrub Running Normal Scrub or Error Scrub
|
||||
* 2. Normal Scrub Paused Error Scrub
|
||||
* 3. Normal Scrub Paused Pause Normal Scrub
|
||||
* 4. Error Scrub Running Normal Scrub or Error Scrub
|
||||
* 5. Error Scrub Paused Pause Error Scrub
|
||||
* 6. Resilvering Anything else
|
||||
*/
|
||||
static int
|
||||
ztest_scrub_impl(spa_t *spa)
|
||||
@ -8082,8 +8093,14 @@ ztest_raidz_expand_check(spa_t *spa)
|
||||
(void) printf("verifying an interrupted raidz "
|
||||
"expansion using a pool scrub ...\n");
|
||||
}
|
||||
|
||||
/* Will fail here if there is non-recoverable corruption detected */
|
||||
VERIFY0(ztest_scrub_impl(spa));
|
||||
int error = ztest_scrub_impl(spa);
|
||||
if (error == EBUSY)
|
||||
error = 0;
|
||||
|
||||
VERIFY0(error);
|
||||
|
||||
if (ztest_opts.zo_verbose >= 1) {
|
||||
(void) printf("raidz expansion scrub check complete\n");
|
||||
}
|
||||
|
@ -58,9 +58,9 @@ deb-utils: deb-local rpm-utils-initramfs
|
||||
pkg1=$${name}-$${version}.$${arch}.rpm; \
|
||||
pkg2=libnvpair3-$${version}.$${arch}.rpm; \
|
||||
pkg3=libuutil3-$${version}.$${arch}.rpm; \
|
||||
pkg4=libzfs5-$${version}.$${arch}.rpm; \
|
||||
pkg5=libzpool5-$${version}.$${arch}.rpm; \
|
||||
pkg6=libzfs5-devel-$${version}.$${arch}.rpm; \
|
||||
pkg4=libzfs6-$${version}.$${arch}.rpm; \
|
||||
pkg5=libzpool6-$${version}.$${arch}.rpm; \
|
||||
pkg6=libzfs6-devel-$${version}.$${arch}.rpm; \
|
||||
pkg7=$${name}-test-$${version}.$${arch}.rpm; \
|
||||
pkg8=$${name}-dracut-$${version}.noarch.rpm; \
|
||||
pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
|
||||
@ -72,7 +72,7 @@ deb-utils: deb-local rpm-utils-initramfs
|
||||
path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \
|
||||
echo "#!$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
|
||||
echo "`which dh_shlibdeps` -- \
|
||||
-xlibuutil3linux -xlibnvpair3linux -xlibzfs5linux -xlibzpool5linux" \
|
||||
-xlibuutil3linux -xlibnvpair3linux -xlibzfs6linux -xlibzpool6linux" \
|
||||
>> $${path_prepend}/dh_shlibdeps; \
|
||||
## These -x arguments are passed to dpkg-shlibdeps, which exclude the
|
||||
## Debianized packages from the auto-generated dependencies of the new debs,
|
||||
@ -93,13 +93,17 @@ debian:
|
||||
cp -r contrib/debian debian; chmod +x debian/rules;
|
||||
|
||||
native-deb-utils: native-deb-local debian
|
||||
while [ -f debian/deb-build.lock ]; do sleep 1; done; \
|
||||
echo "native-deb-utils" > debian/deb-build.lock; \
|
||||
cp contrib/debian/control debian/control; \
|
||||
$(DPKGBUILD) -b -rfakeroot -us -uc;
|
||||
$(DPKGBUILD) -b -rfakeroot -us -uc; \
|
||||
$(RM) -f debian/deb-build.lock
|
||||
|
||||
native-deb-kmod: native-deb-local debian
|
||||
while [ -f debian/deb-build.lock ]; do sleep 1; done; \
|
||||
echo "native-deb-kmod" > debian/deb-build.lock; \
|
||||
sh scripts/make_gitrev.sh; \
|
||||
fakeroot debian/rules override_dh_binary-modules;
|
||||
fakeroot debian/rules override_dh_binary-modules; \
|
||||
$(RM) -f debian/deb-build.lock
|
||||
|
||||
native-deb: native-deb-utils native-deb-kmod
|
||||
|
||||
.NOTPARALLEL: native-deb native-deb-utils native-deb-kmod
|
||||
|
@ -5,7 +5,7 @@ dnl # solution to handling automounts. Prior to this cifs/nfs clients
|
||||
dnl # which required automount support would abuse the follow_link()
|
||||
dnl # operation on directories for this purpose.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_D_AUTOMOUNT], [
|
||||
ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [
|
||||
#include <linux/dcache.h>
|
||||
static struct vfsmount *d_automount(struct path *p) { return NULL; }
|
||||
@ -15,7 +15,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
|
||||
AC_DEFUN([ZFS_AC_KERNEL_D_AUTOMOUNT], [
|
||||
AC_MSG_CHECKING([whether dops->d_automount() exists])
|
||||
ZFS_LINUX_TEST_RESULT([dentry_operations_d_automount], [
|
||||
AC_MSG_RESULT(yes)
|
||||
@ -23,3 +23,40 @@ AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
|
||||
ZFS_LINUX_TEST_ERROR([dops->d_automount()])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 6.14 API change
|
||||
dnl # dops->d_revalidate now has four args.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_D_REVALIDATE_4ARGS], [
|
||||
ZFS_LINUX_TEST_SRC([dentry_operations_d_revalidate_4args], [
|
||||
#include <linux/dcache.h>
|
||||
static int d_revalidate(struct inode *dir,
|
||||
const struct qstr *name, struct dentry *dentry,
|
||||
unsigned int fl) { return 0; }
|
||||
struct dentry_operations dops __attribute__ ((unused)) = {
|
||||
.d_revalidate = d_revalidate,
|
||||
};
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_4ARGS], [
|
||||
AC_MSG_CHECKING([whether dops->d_revalidate() takes 4 args])
|
||||
ZFS_LINUX_TEST_RESULT([dentry_operations_d_revalidate_4args], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_D_REVALIDATE_4ARGS, 1,
|
||||
[dops->d_revalidate() takes 4 args])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
|
||||
ZFS_AC_KERNEL_SRC_D_AUTOMOUNT
|
||||
ZFS_AC_KERNEL_SRC_D_REVALIDATE_4ARGS
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
|
||||
ZFS_AC_KERNEL_D_AUTOMOUNT
|
||||
ZFS_AC_KERNEL_D_REVALIDATE_4ARGS
|
||||
])
|
||||
|
@ -17,14 +17,21 @@ AC_DEFUN([ZFS_AC_KERNEL_KTHREAD_COMPLETE_AND_EXIT], [
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_KTHREAD_DEQUEUE_SIGNAL], [
|
||||
dnl #
|
||||
dnl # 5.17 API: enum pid_type * as new 4th dequeue_signal() argument,
|
||||
dnl # 5768d8906bc23d512b1a736c1e198aa833a6daa4 ("signal: Requeue signals in the appropriate queue")
|
||||
dnl # prehistory:
|
||||
dnl # int dequeue_signal(struct task_struct *task, sigset_t *mask,
|
||||
dnl # siginfo_t *info)
|
||||
dnl #
|
||||
dnl # int dequeue_signal(struct task_struct *task, sigset_t *mask, kernel_siginfo_t *info);
|
||||
dnl # int dequeue_signal(struct task_struct *task, sigset_t *mask, kernel_siginfo_t *info, enum pid_type *type);
|
||||
dnl # 4.20: kernel_siginfo_t introduced, replaces siginfo_t
|
||||
dnl # int dequeue_signal(struct task_struct *task, sigset_t *mask,
|
||||
dnl kernel_siginfo_t *info)
|
||||
dnl #
|
||||
dnl # 6.12 API: first arg struct_task* removed
|
||||
dnl # int dequeue_signal(sigset_t *mask, kernel_siginfo_t *info, enum pid_type *type);
|
||||
dnl # 5.17: enum pid_type introduced as 4th arg
|
||||
dnl # int dequeue_signal(struct task_struct *task, sigset_t *mask,
|
||||
dnl # kernel_siginfo_t *info, enum pid_type *type)
|
||||
dnl #
|
||||
dnl # 6.12: first arg struct_task* removed
|
||||
dnl # int dequeue_signal(sigset_t *mask, kernel_siginfo_t *info,
|
||||
dnl # enum pid_type *type)
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether dequeue_signal() takes 4 arguments])
|
||||
ZFS_LINUX_TEST_RESULT([kthread_dequeue_signal_4arg], [
|
||||
@ -33,11 +40,11 @@ AC_DEFUN([ZFS_AC_KERNEL_KTHREAD_DEQUEUE_SIGNAL], [
|
||||
[dequeue_signal() takes 4 arguments])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether dequeue_signal() a task argument])
|
||||
ZFS_LINUX_TEST_RESULT([kthread_dequeue_signal_3arg_task], [
|
||||
AC_MSG_CHECKING([whether 3-arg dequeue_signal() takes a type argument])
|
||||
ZFS_LINUX_TEST_RESULT([kthread_dequeue_signal_3arg_type], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_DEQUEUE_SIGNAL_3ARG_TASK, 1,
|
||||
[dequeue_signal() takes a task argument])
|
||||
AC_DEFINE(HAVE_DEQUEUE_SIGNAL_3ARG_TYPE, 1,
|
||||
[3-arg dequeue_signal() takes a type argument])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
@ -56,17 +63,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_KTHREAD_COMPLETE_AND_EXIT], [
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_KTHREAD_DEQUEUE_SIGNAL], [
|
||||
ZFS_LINUX_TEST_SRC([kthread_dequeue_signal_3arg_task], [
|
||||
#include <linux/sched/signal.h>
|
||||
], [
|
||||
struct task_struct *task = NULL;
|
||||
sigset_t *mask = NULL;
|
||||
kernel_siginfo_t *info = NULL;
|
||||
int error __attribute__ ((unused));
|
||||
|
||||
error = dequeue_signal(task, mask, info);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([kthread_dequeue_signal_4arg], [
|
||||
#include <linux/sched/signal.h>
|
||||
], [
|
||||
@ -78,6 +74,17 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_KTHREAD_DEQUEUE_SIGNAL], [
|
||||
|
||||
error = dequeue_signal(task, mask, info, type);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([kthread_dequeue_signal_3arg_type], [
|
||||
#include <linux/sched/signal.h>
|
||||
], [
|
||||
sigset_t *mask = NULL;
|
||||
kernel_siginfo_t *info = NULL;
|
||||
enum pid_type *type = NULL;
|
||||
int error __attribute__ ((unused));
|
||||
|
||||
error = dequeue_signal(mask, info, type);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_KTHREAD], [
|
||||
|
33
config/kernel-pin-user-pages.m4
Normal file
33
config/kernel-pin-user-pages.m4
Normal file
@ -0,0 +1,33 @@
|
||||
dnl #
|
||||
dnl # Check for pin_user_pages_unlocked().
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_PIN_USER_PAGES], [
|
||||
ZFS_LINUX_TEST_SRC([pin_user_pages_unlocked], [
|
||||
#include <linux/mm.h>
|
||||
],[
|
||||
unsigned long start = 0;
|
||||
unsigned long nr_pages = 1;
|
||||
struct page **pages = NULL;
|
||||
unsigned int gup_flags = 0;
|
||||
long ret __attribute__ ((unused));
|
||||
|
||||
ret = pin_user_pages_unlocked(start, nr_pages, pages,
|
||||
gup_flags);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_PIN_USER_PAGES], [
|
||||
|
||||
dnl #
|
||||
dnl # Kernal 5.8 introduced the pin_user_pages* interfaces which should
|
||||
dnl # be used for Direct I/O requests.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether pin_user_pages_unlocked() is available])
|
||||
ZFS_LINUX_TEST_RESULT([pin_user_pages_unlocked], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PIN_USER_PAGES_UNLOCKED, 1,
|
||||
[pin_user_pages_unlocked() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
@ -36,7 +36,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_SZ], [
|
||||
ZFS_LINUX_TEST_SRC([has_register_sysctl_sz], [
|
||||
#include <linux/sysctl.h>
|
||||
],[
|
||||
struct ctl_table test_table[] __attribute__((unused)) = {0};
|
||||
struct ctl_table test_table[] __attribute__((unused)) = {{}};
|
||||
register_sysctl_sz("", test_table, 0);
|
||||
])
|
||||
])
|
||||
|
@ -1,57 +0,0 @@
|
||||
dnl #
|
||||
dnl # Check for Direct I/O interfaces.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO], [
|
||||
ZFS_LINUX_TEST_SRC([direct_io_iter], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static ssize_t test_direct_IO(struct kiocb *kiocb,
|
||||
struct iov_iter *iter) { return 0; }
|
||||
|
||||
static const struct address_space_operations
|
||||
aops __attribute__ ((unused)) = {
|
||||
.direct_IO = test_direct_IO,
|
||||
};
|
||||
],[])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([direct_io_iter_offset], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static ssize_t test_direct_IO(struct kiocb *kiocb,
|
||||
struct iov_iter *iter, loff_t offset) { return 0; }
|
||||
|
||||
static const struct address_space_operations
|
||||
aops __attribute__ ((unused)) = {
|
||||
.direct_IO = test_direct_IO,
|
||||
};
|
||||
],[])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO], [
|
||||
dnl #
|
||||
dnl # Linux 4.6.x API change
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether aops->direct_IO() uses iov_iter])
|
||||
ZFS_LINUX_TEST_RESULT([direct_io_iter], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER, 1,
|
||||
[aops->direct_IO() uses iov_iter without rw])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
|
||||
dnl #
|
||||
dnl # Linux 4.1.x API change
|
||||
dnl #
|
||||
AC_MSG_CHECKING(
|
||||
[whether aops->direct_IO() uses offset])
|
||||
ZFS_LINUX_TEST_RESULT([direct_io_iter_offset], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_OFFSET, 1,
|
||||
[aops->direct_IO() uses iov_iter with offset])
|
||||
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
ZFS_LINUX_TEST_ERROR([Direct I/O])
|
||||
])
|
||||
])
|
||||
])
|
@ -1,33 +0,0 @@
|
||||
dnl #
|
||||
dnl # Linux 5.18 uses invalidate_folio in lieu of invalidate_page
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_INVALIDATE_FOLIO], [
|
||||
ZFS_LINUX_TEST_SRC([vfs_has_invalidate_folio], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static void
|
||||
test_invalidate_folio(struct folio *folio, size_t offset,
|
||||
size_t len) {
|
||||
(void) folio; (void) offset; (void) len;
|
||||
return;
|
||||
}
|
||||
|
||||
static const struct address_space_operations
|
||||
aops __attribute__ ((unused)) = {
|
||||
.invalidate_folio = test_invalidate_folio,
|
||||
};
|
||||
],[])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_INVALIDATE_FOLIO], [
|
||||
dnl #
|
||||
dnl # Linux 5.18 uses invalidate_folio in lieu of invalidate_page
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether invalidate_folio exists])
|
||||
ZFS_LINUX_TEST_RESULT([vfs_has_invalidate_folio], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_VFS_INVALIDATE_FOLIO, 1, [invalidate_folio exists])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
@ -13,9 +13,17 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [
|
||||
error = fault_in_iov_iter_readable(&iter, size);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([iov_iter_type], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uio.h>
|
||||
],[
|
||||
struct iov_iter iter = { 0 };
|
||||
__attribute__((unused)) enum iter_type i = iov_iter_type(&iter);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([iov_iter_get_pages2], [
|
||||
#include <linux/uio.h>
|
||||
], [
|
||||
],[
|
||||
struct iov_iter iter = { 0 };
|
||||
struct page **pages = NULL;
|
||||
size_t maxsize = 4096;
|
||||
@ -27,26 +35,13 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [
|
||||
&start);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([iov_iter_get_pages], [
|
||||
#include <linux/uio.h>
|
||||
], [
|
||||
struct iov_iter iter = { 0 };
|
||||
struct page **pages = NULL;
|
||||
size_t maxsize = 4096;
|
||||
unsigned maxpages = 1;
|
||||
size_t start;
|
||||
size_t ret __attribute__ ((unused));
|
||||
|
||||
ret = iov_iter_get_pages(&iter, pages, maxsize, maxpages,
|
||||
&start);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([iov_iter_type], [
|
||||
#include <linux/fs.h>
|
||||
ZFS_LINUX_TEST_SRC([iter_is_ubuf], [
|
||||
#include <linux/uio.h>
|
||||
],[
|
||||
struct iov_iter iter = { 0 };
|
||||
__attribute__((unused)) enum iter_type i = iov_iter_type(&iter);
|
||||
bool ret __attribute__((unused));
|
||||
|
||||
ret = iter_is_ubuf(&iter);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([iter_iov], [
|
||||
@ -59,7 +54,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
|
||||
enable_vfs_iov_iter="yes"
|
||||
|
||||
AC_MSG_CHECKING([whether fault_in_iov_iter_readable() is available])
|
||||
ZFS_LINUX_TEST_RESULT([fault_in_iov_iter_readable], [
|
||||
@ -70,27 +64,6 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Kernel 6.0 changed iov_iter_get_pages() to iov_iter_page_pages2().
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether iov_iter_get_pages2() is available])
|
||||
ZFS_LINUX_TEST_RESULT([iov_iter_get_pages2], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_IOV_ITER_GET_PAGES2, 1,
|
||||
[iov_iter_get_pages2() is available])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether iov_iter_get_pages() is available])
|
||||
ZFS_LINUX_TEST_RESULT([iov_iter_get_pages], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_IOV_ITER_GET_PAGES, 1,
|
||||
[iov_iter_get_pages() is available])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
enable_vfs_iov_iter="no"
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # This checks for iov_iter_type() in linux/uio.h. It is not
|
||||
dnl # required, however, and the module will compiled without it
|
||||
@ -105,15 +78,29 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
|
||||
dnl #
|
||||
dnl # As of the 4.9 kernel support is provided for iovecs, kvecs,
|
||||
dnl # bvecs and pipes in the iov_iter structure. As long as the
|
||||
dnl # other support interfaces are all available the iov_iter can
|
||||
dnl # be correctly used in the uio structure.
|
||||
dnl # Kernel 6.0 changed iov_iter_get_pages() to iov_iter_get_pages2().
|
||||
dnl #
|
||||
AS_IF([test "x$enable_vfs_iov_iter" = "xyes"], [
|
||||
AC_DEFINE(HAVE_VFS_IOV_ITER, 1,
|
||||
[All required iov_iter interfaces are available])
|
||||
AC_MSG_CHECKING([whether iov_iter_get_pages2() is available])
|
||||
ZFS_LINUX_TEST_RESULT([iov_iter_get_pages2], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_IOV_ITER_GET_PAGES2, 1,
|
||||
[iov_iter_get_pages2() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Kernel 6.0 introduced the ITER_UBUF iov_iter type. iter_is_ubuf()
|
||||
dnl # was also added to determine if the iov_iter is an ITER_UBUF.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether iter_is_ubuf() is available])
|
||||
ZFS_LINUX_TEST_RESULT([iter_is_ubuf], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_ITER_IS_UBUF, 1, [iter_is_ubuf() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
dnl #
|
||||
|
27
config/kernel-vfs-migrate_folio.m4
Normal file
27
config/kernel-vfs-migrate_folio.m4
Normal file
@ -0,0 +1,27 @@
|
||||
dnl #
|
||||
dnl # Linux 6.0 uses migrate_folio in lieu of migrate_page
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_MIGRATE_FOLIO], [
|
||||
ZFS_LINUX_TEST_SRC([vfs_has_migrate_folio], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/migrate.h>
|
||||
|
||||
static const struct address_space_operations
|
||||
aops __attribute__ ((unused)) = {
|
||||
.migrate_folio = migrate_folio,
|
||||
};
|
||||
],[])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_MIGRATE_FOLIO], [
|
||||
dnl #
|
||||
dnl # Linux 6.0 uses migrate_folio in lieu of migrate_page
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether migrate_folio exists])
|
||||
ZFS_LINUX_TEST_RESULT([vfs_has_migrate_folio], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_VFS_MIGRATE_FOLIO, 1, [migrate_folio exists])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
@ -1,32 +0,0 @@
|
||||
dnl #
|
||||
dnl # Linux 5.19 uses release_folio in lieu of releasepage
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_RELEASE_FOLIO], [
|
||||
ZFS_LINUX_TEST_SRC([vfs_has_release_folio], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static bool
|
||||
test_release_folio(struct folio *folio, gfp_t gfp) {
|
||||
(void) folio; (void) gfp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct address_space_operations
|
||||
aops __attribute__ ((unused)) = {
|
||||
.release_folio = test_release_folio,
|
||||
};
|
||||
],[])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_RELEASE_FOLIO], [
|
||||
dnl #
|
||||
dnl # Linux 5.19 uses release_folio in lieu of releasepage
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether release_folio exists])
|
||||
ZFS_LINUX_TEST_RESULT([vfs_has_release_folio], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_VFS_RELEASE_FOLIO, 1, [release_folio exists])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
@ -54,7 +54,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_GET_DENTRY_INODE_FLAGS], [
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET_DENTRY_INODE_FLAGS], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether xattr_handler->get() wants dentry and inode and flags])
|
||||
ZFS_LINUX_TEST_RESULT([xattr_handler_get_dentry_inode_flags], [
|
||||
|
@ -77,10 +77,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||
ZFS_AC_KERNEL_SRC_SGET
|
||||
ZFS_AC_KERNEL_SRC_VFS_FILEMAP_DIRTY_FOLIO
|
||||
ZFS_AC_KERNEL_SRC_VFS_READ_FOLIO
|
||||
ZFS_AC_KERNEL_SRC_VFS_RELEASE_FOLIO
|
||||
ZFS_AC_KERNEL_SRC_VFS_INVALIDATE_FOLIO
|
||||
ZFS_AC_KERNEL_SRC_VFS_MIGRATE_FOLIO
|
||||
ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS
|
||||
ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO
|
||||
ZFS_AC_KERNEL_SRC_VFS_READPAGES
|
||||
ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS
|
||||
ZFS_AC_KERNEL_SRC_VFS_IOV_ITER
|
||||
@ -129,6 +127,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||
ZFS_AC_KERNEL_SRC_MM_PAGE_SIZE
|
||||
ZFS_AC_KERNEL_SRC_MM_PAGE_MAPPING
|
||||
ZFS_AC_KERNEL_SRC_FILE
|
||||
ZFS_AC_KERNEL_SRC_PIN_USER_PAGES
|
||||
case "$host_cpu" in
|
||||
powerpc*)
|
||||
ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE
|
||||
@ -189,10 +188,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||
ZFS_AC_KERNEL_SGET
|
||||
ZFS_AC_KERNEL_VFS_FILEMAP_DIRTY_FOLIO
|
||||
ZFS_AC_KERNEL_VFS_READ_FOLIO
|
||||
ZFS_AC_KERNEL_VFS_RELEASE_FOLIO
|
||||
ZFS_AC_KERNEL_VFS_INVALIDATE_FOLIO
|
||||
ZFS_AC_KERNEL_VFS_MIGRATE_FOLIO
|
||||
ZFS_AC_KERNEL_VFS_FSYNC_2ARGS
|
||||
ZFS_AC_KERNEL_VFS_DIRECT_IO
|
||||
ZFS_AC_KERNEL_VFS_READPAGES
|
||||
ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS
|
||||
ZFS_AC_KERNEL_VFS_IOV_ITER
|
||||
@ -242,6 +239,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||
ZFS_AC_KERNEL_MM_PAGE_MAPPING
|
||||
ZFS_AC_KERNEL_1ARG_ASSIGN_STR
|
||||
ZFS_AC_KERNEL_FILE
|
||||
ZFS_AC_KERNEL_PIN_USER_PAGES
|
||||
case "$host_cpu" in
|
||||
powerpc*)
|
||||
ZFS_AC_KERNEL_CPU_HAS_FEATURE
|
||||
@ -683,11 +681,16 @@ AC_DEFUN([ZFS_LINUX_COMPILE], [
|
||||
building kernel modules])
|
||||
AC_ARG_VAR([KERNEL_LLVM], [Binary option to
|
||||
build kernel modules with LLVM/CLANG toolchain])
|
||||
AC_ARG_VAR([KERNEL_CROSS_COMPILE], [Cross compile prefix
|
||||
for kernel module builds])
|
||||
AC_ARG_VAR([KERNEL_ARCH], [Architecture to build kernel modules for])
|
||||
AC_TRY_COMMAND([
|
||||
KBUILD_MODPOST_NOFINAL="$5" KBUILD_MODPOST_WARN="$6"
|
||||
make modules -k -j$TEST_JOBS ${KERNEL_CC:+CC=$KERNEL_CC}
|
||||
${KERNEL_LD:+LD=$KERNEL_LD} ${KERNEL_LLVM:+LLVM=$KERNEL_LLVM}
|
||||
CONFIG_MODULES=y CFLAGS_MODULE=-DCONFIG_MODULES
|
||||
${KERNEL_CROSS_COMPILE:+CROSS_COMPILE=$KERNEL_CROSS_COMPILE}
|
||||
${KERNEL_ARCH:+ARCH=$KERNEL_ARCH}
|
||||
-C $LINUX_OBJ $ARCH_UM M=$PWD/$1 >$1/build.log 2>&1])
|
||||
AS_IF([AC_TRY_COMMAND([$2])], [$3], [$4])
|
||||
])
|
||||
|
@ -393,6 +393,8 @@ AC_DEFUN([ZFS_AC_RPM], [
|
||||
RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_cc KERNEL_CC=$(KERNEL_CC)"'
|
||||
RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_ld KERNEL_LD=$(KERNEL_LD)"'
|
||||
RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_llvm KERNEL_LLVM=$(KERNEL_LLVM)"'
|
||||
RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_cross_compile KERNEL_CROSS_COMPILE=$(KERNEL_CROSS_COMPILE)"'
|
||||
RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_arch KERNEL_ARCH=$(KERNEL_ARCH)"'
|
||||
])
|
||||
|
||||
RPM_DEFINE_DKMS=''
|
||||
@ -627,7 +629,7 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
||||
|
||||
AC_MSG_CHECKING([default bash completion directory])
|
||||
case "$VENDOR" in
|
||||
alpine|artix|debian|gentoo|ubuntu)
|
||||
alpine|arch|artix|debian|gentoo|ubuntu)
|
||||
bashcompletiondir=/usr/share/bash-completion/completions
|
||||
;;
|
||||
freebsd)
|
||||
|
@ -12,14 +12,14 @@ dist_noinst_DATA += %D%/openzfs-libpam-zfs.postinst
|
||||
dist_noinst_DATA += %D%/openzfs-libpam-zfs.prerm
|
||||
dist_noinst_DATA += %D%/openzfs-libuutil3.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libuutil3.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs4.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs4.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs6.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs6.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzfsbootenv1.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzfsbootenv1.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs-dev.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs-dev.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzpool5.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzpool5.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzpool6.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzpool6.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-python3-pyzfs.install
|
||||
dist_noinst_DATA += %D%/openzfs-zfs-dkms.config
|
||||
dist_noinst_DATA += %D%/openzfs-zfs-dkms.dkms
|
||||
|
@ -6,6 +6,6 @@ contrib/pyzfs/libzfs_core/bindings/__pycache__/
|
||||
contrib/pyzfs/pyzfs.egg-info/
|
||||
debian/openzfs-libnvpair3.install
|
||||
debian/openzfs-libuutil3.install
|
||||
debian/openzfs-libzfs4.install
|
||||
debian/openzfs-libzfs6.install
|
||||
debian/openzfs-libzfs-dev.install
|
||||
debian/openzfs-libzpool5.install
|
||||
debian/openzfs-libzpool6.install
|
||||
|
@ -78,9 +78,9 @@ Architecture: linux-any
|
||||
Depends: libssl-dev | libssl1.0-dev,
|
||||
openzfs-libnvpair3 (= ${binary:Version}),
|
||||
openzfs-libuutil3 (= ${binary:Version}),
|
||||
openzfs-libzfs4 (= ${binary:Version}),
|
||||
openzfs-libzfs6 (= ${binary:Version}),
|
||||
openzfs-libzfsbootenv1 (= ${binary:Version}),
|
||||
openzfs-libzpool5 (= ${binary:Version}),
|
||||
openzfs-libzpool6 (= ${binary:Version}),
|
||||
${misc:Depends}
|
||||
Replaces: libzfslinux-dev
|
||||
Conflicts: libzfslinux-dev
|
||||
@ -90,18 +90,18 @@ Description: OpenZFS filesystem development files for Linux
|
||||
libraries of OpenZFS filesystem.
|
||||
.
|
||||
This package includes the development files of libnvpair3, libuutil3,
|
||||
libzpool5 and libzfs4.
|
||||
libzpool6 and libzfs6.
|
||||
|
||||
Package: openzfs-libzfs4
|
||||
Package: openzfs-libzfs6
|
||||
Section: contrib/libs
|
||||
Architecture: linux-any
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
# The libcurl4 is loaded through dlopen("libcurl.so.4").
|
||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=988521
|
||||
Recommends: libcurl4
|
||||
Breaks: libzfs2, libzfs4
|
||||
Replaces: libzfs2, libzfs4, libzfs4linux
|
||||
Conflicts: libzfs4linux
|
||||
Breaks: libzfs2, libzfs4, libzfs4linux, libzfs6linux
|
||||
Replaces: libzfs2, libzfs4, libzfs4linux, libzfs6linux
|
||||
Conflicts: libzfs6linux
|
||||
Description: OpenZFS filesystem library for Linux - general support
|
||||
OpenZFS is a storage platform that encompasses the functionality of
|
||||
traditional filesystems and volume managers. It supports data checksums,
|
||||
@ -123,13 +123,13 @@ Description: OpenZFS filesystem library for Linux - label info support
|
||||
.
|
||||
The zfsbootenv library provides support for modifying ZFS label information.
|
||||
|
||||
Package: openzfs-libzpool5
|
||||
Package: openzfs-libzpool6
|
||||
Section: contrib/libs
|
||||
Architecture: linux-any
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Breaks: libzpool2, libzpool5
|
||||
Replaces: libzpool2, libzpool5, libzpool5linux
|
||||
Conflicts: libzpool5linux
|
||||
Breaks: libzpool2, libzpool5, libzpool5linux, libzpool6linux
|
||||
Replaces: libzpool2, libzpool5, libzpool5linux, libzpool6linux
|
||||
Conflicts: libzpool6linux
|
||||
Description: OpenZFS pool library for Linux
|
||||
OpenZFS is a storage platform that encompasses the functionality of
|
||||
traditional filesystems and volume managers. It supports data checksums,
|
||||
@ -246,8 +246,8 @@ Architecture: linux-any
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Depends: openzfs-libnvpair3 (= ${binary:Version}),
|
||||
openzfs-libuutil3 (= ${binary:Version}),
|
||||
openzfs-libzfs4 (= ${binary:Version}),
|
||||
openzfs-libzpool5 (= ${binary:Version}),
|
||||
openzfs-libzfs6 (= ${binary:Version}),
|
||||
openzfs-libzpool6 (= ${binary:Version}),
|
||||
python3,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
|
@ -98,6 +98,7 @@ usr/share/man/man8/zpool-attach.8
|
||||
usr/share/man/man8/zpool-checkpoint.8
|
||||
usr/share/man/man8/zpool-clear.8
|
||||
usr/share/man/man8/zpool-create.8
|
||||
usr/share/man/man8/zpool-ddtprune.8
|
||||
usr/share/man/man8/zpool-destroy.8
|
||||
usr/share/man/man8/zpool-detach.8
|
||||
usr/share/man/man8/zpool-ddtprune.8
|
||||
@ -113,6 +114,7 @@ usr/share/man/man8/zpool-list.8
|
||||
usr/share/man/man8/zpool-offline.8
|
||||
usr/share/man/man8/zpool-online.8
|
||||
usr/share/man/man8/zpool-prefetch.8
|
||||
usr/share/man/man8/zpool-prefetch.8
|
||||
usr/share/man/man8/zpool-reguid.8
|
||||
usr/share/man/man8/zpool-remove.8
|
||||
usr/share/man/man8/zpool-reopen.8
|
||||
|
@ -344,7 +344,7 @@ mount_fs()
|
||||
|
||||
# Need the _original_ datasets mountpoint!
|
||||
mountpoint=$(get_fs_value "$fs" mountpoint)
|
||||
ZFS_CMD="mount -o zfsutil -t zfs"
|
||||
ZFS_CMD="mount.zfs -o zfsutil"
|
||||
if [ "$mountpoint" = "legacy" ] || [ "$mountpoint" = "none" ]; then
|
||||
# Can't use the mountpoint property. Might be one of our
|
||||
# clones. Check the 'org.zol:mountpoint' property set in
|
||||
@ -359,9 +359,8 @@ mount_fs()
|
||||
# isn't the root fs.
|
||||
return 0
|
||||
fi
|
||||
# Don't use mount.zfs -o zfsutils for legacy mountpoint
|
||||
if [ "$mountpoint" = "legacy" ]; then
|
||||
ZFS_CMD="mount -t zfs"
|
||||
ZFS_CMD="mount.zfs"
|
||||
fi
|
||||
# Last hail-mary: Hope 'rootmnt' is set!
|
||||
mountpoint=""
|
||||
|
@ -63,6 +63,7 @@ pam_syslog(pam_handle_t *pamh, int loglevel, const char *fmt, ...)
|
||||
#include <sys/file.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pwd.h>
|
||||
#include <lib/libzfs/libzfs_impl.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
@ -370,67 +371,6 @@ change_key(pam_handle_t *pamh, const char *ds_name,
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
decrypt_mount(pam_handle_t *pamh, const char *ds_name,
|
||||
const char *passphrase, boolean_t noop)
|
||||
{
|
||||
zfs_handle_t *ds = zfs_open(g_zfs, ds_name, ZFS_TYPE_FILESYSTEM);
|
||||
if (ds == NULL) {
|
||||
pam_syslog(pamh, LOG_ERR, "dataset %s not found", ds_name);
|
||||
return (-1);
|
||||
}
|
||||
pw_password_t *key = prepare_passphrase(pamh, ds, passphrase, NULL);
|
||||
if (key == NULL) {
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
int ret = lzc_load_key(ds_name, noop, (uint8_t *)key->value,
|
||||
WRAPPING_KEY_LEN);
|
||||
pw_free(key);
|
||||
if (ret && ret != EEXIST) {
|
||||
pam_syslog(pamh, LOG_ERR, "load_key failed: %d", ret);
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
if (noop) {
|
||||
goto out;
|
||||
}
|
||||
ret = zfs_mount(ds, NULL, 0);
|
||||
if (ret) {
|
||||
pam_syslog(pamh, LOG_ERR, "mount failed: %d", ret);
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
out:
|
||||
zfs_close(ds);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
unmount_unload(pam_handle_t *pamh, const char *ds_name, boolean_t force)
|
||||
{
|
||||
zfs_handle_t *ds = zfs_open(g_zfs, ds_name, ZFS_TYPE_FILESYSTEM);
|
||||
if (ds == NULL) {
|
||||
pam_syslog(pamh, LOG_ERR, "dataset %s not found", ds_name);
|
||||
return (-1);
|
||||
}
|
||||
int ret = zfs_unmount(ds, NULL, force ? MS_FORCE : 0);
|
||||
if (ret) {
|
||||
pam_syslog(pamh, LOG_ERR, "zfs_unmount failed with: %d", ret);
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ret = lzc_unload_key(ds_name);
|
||||
if (ret) {
|
||||
pam_syslog(pamh, LOG_ERR, "unload_key failed with: %d", ret);
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
zfs_close(ds);
|
||||
return (0);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *homes_prefix;
|
||||
char *runstatedir;
|
||||
@ -443,6 +383,7 @@ typedef struct {
|
||||
boolean_t unmount_and_unload;
|
||||
boolean_t force_unmount;
|
||||
boolean_t recursive_homes;
|
||||
boolean_t mount_recursively;
|
||||
} zfs_key_config_t;
|
||||
|
||||
static int
|
||||
@ -481,6 +422,7 @@ zfs_key_config_load(pam_handle_t *pamh, zfs_key_config_t *config,
|
||||
config->unmount_and_unload = B_TRUE;
|
||||
config->force_unmount = B_FALSE;
|
||||
config->recursive_homes = B_FALSE;
|
||||
config->mount_recursively = B_FALSE;
|
||||
config->dsname = NULL;
|
||||
config->homedir = NULL;
|
||||
for (int c = 0; c < argc; c++) {
|
||||
@ -500,6 +442,8 @@ zfs_key_config_load(pam_handle_t *pamh, zfs_key_config_t *config,
|
||||
config->force_unmount = B_TRUE;
|
||||
} else if (strcmp(argv[c], "recursive_homes") == 0) {
|
||||
config->recursive_homes = B_TRUE;
|
||||
} else if (strcmp(argv[c], "mount_recursively") == 0) {
|
||||
config->mount_recursively = B_TRUE;
|
||||
} else if (strcmp(argv[c], "prop_mountpoint") == 0) {
|
||||
if (config->homedir == NULL)
|
||||
config->homedir = strdup(entry->pw_dir);
|
||||
@ -508,6 +452,217 @@ zfs_key_config_load(pam_handle_t *pamh, zfs_key_config_t *config,
|
||||
return (PAM_SUCCESS);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
pam_handle_t *pamh;
|
||||
zfs_key_config_t *target;
|
||||
} mount_umount_dataset_data_t;
|
||||
|
||||
static int
|
||||
mount_dataset(zfs_handle_t *zhp, void *data)
|
||||
{
|
||||
mount_umount_dataset_data_t *mount_umount_dataset_data = data;
|
||||
|
||||
zfs_key_config_t *target = mount_umount_dataset_data->target;
|
||||
pam_handle_t *pamh = mount_umount_dataset_data->pamh;
|
||||
|
||||
/* Refresh properties to get the latest key status */
|
||||
zfs_refresh_properties(zhp);
|
||||
|
||||
int ret = 0;
|
||||
|
||||
/* Check if dataset type is filesystem */
|
||||
if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM) {
|
||||
pam_syslog(pamh, LOG_DEBUG,
|
||||
"dataset is not filesystem: %s, skipping.",
|
||||
zfs_get_name(zhp));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Check if encryption key is available */
|
||||
if (zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS) ==
|
||||
ZFS_KEYSTATUS_UNAVAILABLE) {
|
||||
pam_syslog(pamh, LOG_WARNING,
|
||||
"key unavailable for: %s, skipping",
|
||||
zfs_get_name(zhp));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Check if prop canmount is on */
|
||||
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) != ZFS_CANMOUNT_ON) {
|
||||
pam_syslog(pamh, LOG_INFO,
|
||||
"canmount is not on for: %s, skipping",
|
||||
zfs_get_name(zhp));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Get mountpoint prop for check */
|
||||
char mountpoint[ZFS_MAXPROPLEN];
|
||||
if ((ret = zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
|
||||
sizeof (mountpoint), NULL, NULL, 0, 1)) != 0) {
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"failed to get mountpoint prop: %d", ret);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Check if mountpoint isn't none or legacy */
|
||||
if (strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) == 0 ||
|
||||
strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) == 0) {
|
||||
pam_syslog(pamh, LOG_INFO,
|
||||
"mountpoint is none or legacy for: %s, skipping",
|
||||
zfs_get_name(zhp));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Don't mount the dataset if already mounted */
|
||||
if (zfs_is_mounted(zhp, NULL)) {
|
||||
pam_syslog(pamh, LOG_INFO, "already mounted: %s",
|
||||
zfs_get_name(zhp));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Mount the dataset */
|
||||
ret = zfs_mount(zhp, NULL, 0);
|
||||
if (ret) {
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"zfs_mount failed for %s with: %d", zfs_get_name(zhp),
|
||||
ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Recursively mount children if the recursive flag is set */
|
||||
if (target->mount_recursively) {
|
||||
ret = zfs_iter_filesystems_v2(zhp, 0, mount_dataset, data);
|
||||
if (ret != 0) {
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"child iteration failed: %d", ret);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
umount_dataset(zfs_handle_t *zhp, void *data)
|
||||
{
|
||||
mount_umount_dataset_data_t *mount_umount_dataset_data = data;
|
||||
|
||||
zfs_key_config_t *target = mount_umount_dataset_data->target;
|
||||
pam_handle_t *pamh = mount_umount_dataset_data->pamh;
|
||||
|
||||
int ret = 0;
|
||||
/* Recursively umount children if the recursive flag is set */
|
||||
if (target->mount_recursively) {
|
||||
ret = zfs_iter_filesystems_v2(zhp, 0, umount_dataset, data);
|
||||
if (ret != 0) {
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"child iteration failed: %d", ret);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if dataset type is filesystem */
|
||||
if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM) {
|
||||
pam_syslog(pamh, LOG_DEBUG,
|
||||
"dataset is not filesystem: %s, skipping",
|
||||
zfs_get_name(zhp));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Don't umount the dataset if already unmounted */
|
||||
if (zfs_is_mounted(zhp, NULL) == 0) {
|
||||
pam_syslog(pamh, LOG_INFO, "already unmounted: %s",
|
||||
zfs_get_name(zhp));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Unmount the dataset */
|
||||
ret = zfs_unmount(zhp, NULL, target->force_unmount ? MS_FORCE : 0);
|
||||
if (ret) {
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"zfs_unmount failed for %s with: %d", zfs_get_name(zhp),
|
||||
ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
decrypt_mount(pam_handle_t *pamh, zfs_key_config_t *config, const char *ds_name,
|
||||
const char *passphrase, boolean_t noop)
|
||||
{
|
||||
zfs_handle_t *ds = zfs_open(g_zfs, ds_name, ZFS_TYPE_FILESYSTEM);
|
||||
if (ds == NULL) {
|
||||
pam_syslog(pamh, LOG_ERR, "dataset %s not found", ds_name);
|
||||
return (-1);
|
||||
}
|
||||
pw_password_t *key = prepare_passphrase(pamh, ds, passphrase, NULL);
|
||||
if (key == NULL) {
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
int ret = lzc_load_key(ds_name, noop, (uint8_t *)key->value,
|
||||
WRAPPING_KEY_LEN);
|
||||
pw_free(key);
|
||||
if (ret && ret != EEXIST) {
|
||||
pam_syslog(pamh, LOG_ERR, "load_key failed: %d", ret);
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (noop) {
|
||||
zfs_close(ds);
|
||||
return (0);
|
||||
}
|
||||
|
||||
mount_umount_dataset_data_t data;
|
||||
data.pamh = pamh;
|
||||
data.target = config;
|
||||
|
||||
ret = mount_dataset(ds, &data);
|
||||
if (ret != 0) {
|
||||
pam_syslog(pamh, LOG_ERR, "mount failed: %d", ret);
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
zfs_close(ds);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
unmount_unload(pam_handle_t *pamh, const char *ds_name,
|
||||
zfs_key_config_t *target)
|
||||
{
|
||||
zfs_handle_t *ds = zfs_open(g_zfs, ds_name, ZFS_TYPE_FILESYSTEM);
|
||||
if (ds == NULL) {
|
||||
pam_syslog(pamh, LOG_ERR, "dataset %s not found", ds_name);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
mount_umount_dataset_data_t data;
|
||||
data.pamh = pamh;
|
||||
data.target = target;
|
||||
|
||||
int ret = umount_dataset(ds, &data);
|
||||
if (ret) {
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"unmount_dataset failed with: %d", ret);
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ret = lzc_unload_key(ds_name);
|
||||
if (ret) {
|
||||
pam_syslog(pamh, LOG_ERR, "unload_key failed with: %d", ret);
|
||||
zfs_close(ds);
|
||||
return (-1);
|
||||
}
|
||||
zfs_close(ds);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
zfs_key_config_free(zfs_key_config_t *config)
|
||||
{
|
||||
@ -548,7 +703,7 @@ find_dsname_by_prop_value(zfs_handle_t *zhp, void *data)
|
||||
}
|
||||
|
||||
static char *
|
||||
zfs_key_config_get_dataset(zfs_key_config_t *config)
|
||||
zfs_key_config_get_dataset(pam_handle_t *pamh, zfs_key_config_t *config)
|
||||
{
|
||||
if (config->homedir != NULL &&
|
||||
config->homes_prefix != NULL) {
|
||||
@ -559,7 +714,7 @@ zfs_key_config_get_dataset(zfs_key_config_t *config)
|
||||
zfs_handle_t *zhp = zfs_open(g_zfs,
|
||||
config->homes_prefix, ZFS_TYPE_FILESYSTEM);
|
||||
if (zhp == NULL) {
|
||||
pam_syslog(NULL, LOG_ERR,
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"dataset %s not found",
|
||||
config->homes_prefix);
|
||||
return (NULL);
|
||||
@ -697,13 +852,13 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
|
||||
zfs_key_config_free(&config);
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
char *dataset = zfs_key_config_get_dataset(&config);
|
||||
char *dataset = zfs_key_config_get_dataset(pamh, &config);
|
||||
if (!dataset) {
|
||||
pam_zfs_free();
|
||||
zfs_key_config_free(&config);
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
if (decrypt_mount(pamh, dataset, token->value, B_TRUE) == -1) {
|
||||
if (decrypt_mount(pamh, &config, dataset, token->value, B_TRUE) == -1) {
|
||||
free(dataset);
|
||||
pam_zfs_free();
|
||||
zfs_key_config_free(&config);
|
||||
@ -749,7 +904,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
|
||||
zfs_key_config_free(&config);
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
char *dataset = zfs_key_config_get_dataset(&config);
|
||||
char *dataset = zfs_key_config_get_dataset(pamh, &config);
|
||||
if (!dataset) {
|
||||
pam_zfs_free();
|
||||
zfs_key_config_free(&config);
|
||||
@ -763,7 +918,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
|
||||
zfs_key_config_free(&config);
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
if (decrypt_mount(pamh, dataset,
|
||||
if (decrypt_mount(pamh, &config, dataset,
|
||||
old_token->value, B_TRUE) == -1) {
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"old token mismatch");
|
||||
@ -784,7 +939,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
|
||||
pw_clear(pamh, OLD_PASSWORD_VAR_NAME);
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
char *dataset = zfs_key_config_get_dataset(&config);
|
||||
char *dataset = zfs_key_config_get_dataset(pamh, &config);
|
||||
if (!dataset) {
|
||||
pam_zfs_free();
|
||||
zfs_key_config_free(&config);
|
||||
@ -793,7 +948,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
int was_loaded = is_key_loaded(pamh, dataset);
|
||||
if (!was_loaded && decrypt_mount(pamh, dataset,
|
||||
if (!was_loaded && decrypt_mount(pamh, &config, dataset,
|
||||
old_token->value, B_FALSE) == -1) {
|
||||
free(dataset);
|
||||
pam_zfs_free();
|
||||
@ -804,7 +959,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
|
||||
}
|
||||
int changed = change_key(pamh, dataset, token->value);
|
||||
if (!was_loaded) {
|
||||
unmount_unload(pamh, dataset, config.force_unmount);
|
||||
unmount_unload(pamh, dataset, &config);
|
||||
}
|
||||
free(dataset);
|
||||
pam_zfs_free();
|
||||
@ -856,13 +1011,14 @@ pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
zfs_key_config_free(&config);
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
char *dataset = zfs_key_config_get_dataset(&config);
|
||||
char *dataset = zfs_key_config_get_dataset(pamh, &config);
|
||||
if (!dataset) {
|
||||
pam_zfs_free();
|
||||
zfs_key_config_free(&config);
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
if (decrypt_mount(pamh, dataset, token->value, B_FALSE) == -1) {
|
||||
if (decrypt_mount(pamh, &config, dataset,
|
||||
token->value, B_FALSE) == -1) {
|
||||
free(dataset);
|
||||
pam_zfs_free();
|
||||
zfs_key_config_free(&config);
|
||||
@ -910,13 +1066,13 @@ pam_sm_close_session(pam_handle_t *pamh, int flags,
|
||||
zfs_key_config_free(&config);
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
char *dataset = zfs_key_config_get_dataset(&config);
|
||||
char *dataset = zfs_key_config_get_dataset(pamh, &config);
|
||||
if (!dataset) {
|
||||
pam_zfs_free();
|
||||
zfs_key_config_free(&config);
|
||||
return (PAM_SESSION_ERR);
|
||||
}
|
||||
if (unmount_unload(pamh, dataset, config.force_unmount) == -1) {
|
||||
if (unmount_unload(pamh, dataset, &config) == -1) {
|
||||
free(dataset);
|
||||
pam_zfs_free();
|
||||
zfs_key_config_free(&config);
|
||||
|
@ -8,6 +8,13 @@ After=systemd-remount-fs.service
|
||||
Before=local-fs.target
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
# This merely tells the service manager
|
||||
# that unmounting everything undoes the
|
||||
# effect of this service. No extra logic
|
||||
# is ran as a result of these settings.
|
||||
Conflicts=umount.target
|
||||
Before=umount.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
|
@ -150,7 +150,6 @@ COMMON_H = \
|
||||
sys/zio_compress.h \
|
||||
sys/zio_crypt.h \
|
||||
sys/zio_impl.h \
|
||||
sys/zio_priority.h \
|
||||
sys/zrlock.h \
|
||||
sys/zthr.h \
|
||||
\
|
||||
|
@ -27,7 +27,7 @@
|
||||
#define _LIBZUTIL_H extern __attribute__((visibility("default")))
|
||||
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/nvpair.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
|
||||
@ -276,7 +276,14 @@ _LIBZUTIL_H void update_vdev_config_dev_sysfs_path(nvlist_t *nv,
|
||||
* Thread-safe strerror() for use in ZFS libraries
|
||||
*/
|
||||
static inline char *zfs_strerror(int errnum) {
|
||||
return (strerror_l(errnum, uselocale(0)));
|
||||
static __thread char errbuf[512];
|
||||
static pthread_mutex_t zfs_strerror_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
(void) pthread_mutex_lock(&zfs_strerror_lock);
|
||||
(void) strlcpy(errbuf, strerror(errnum), sizeof (errbuf));
|
||||
(void) pthread_mutex_unlock(&zfs_strerror_lock);
|
||||
|
||||
return (errbuf);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,10 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Isilon Systems, Inc.
|
||||
* Copyright (c) 2010 iXsystems, Inc.
|
||||
* Copyright (c) 2010 Panasas, Inc.
|
||||
* Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
|
||||
* Copyright (c) 2015 François Tigeot
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2024 Warner Losh.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -26,76 +21,14 @@
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _LINUX_COMPILER_H_
|
||||
#define _LINUX_COMPILER_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
/*
|
||||
* FreeBSD's LinuxKPI compiler.h as far back as FreeBSD 12 has what we need,
|
||||
* except zfs_fallthrough.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <compat/linuxkpi/common/include/linux/compiler.h>
|
||||
|
||||
#define __user
|
||||
#define __kernel
|
||||
#define __safe
|
||||
#define __force
|
||||
#define __nocast
|
||||
#define __iomem
|
||||
#define __chk_user_ptr(x) ((void)0)
|
||||
#define __chk_io_ptr(x) ((void)0)
|
||||
#define __builtin_warning(x, y...) (1)
|
||||
#define __acquires(x)
|
||||
#define __releases(x)
|
||||
#define __acquire(x) do { } while (0)
|
||||
#define __release(x) do { } while (0)
|
||||
#define __cond_lock(x, c) (c)
|
||||
#define __bitwise
|
||||
#define __devinitdata
|
||||
#define __deprecated
|
||||
#define __init
|
||||
#define __initconst
|
||||
#define __devinit
|
||||
#define __devexit
|
||||
#define __exit
|
||||
#define __rcu
|
||||
#define __percpu
|
||||
#define __weak __weak_symbol
|
||||
#define __malloc
|
||||
#define ___stringify(...) #__VA_ARGS__
|
||||
#define __stringify(...) ___stringify(__VA_ARGS__)
|
||||
#define __attribute_const__ __attribute__((__const__))
|
||||
#undef __always_inline
|
||||
#define __always_inline inline
|
||||
#define noinline __noinline
|
||||
#define ____cacheline_aligned __aligned(CACHE_LINE_SIZE)
|
||||
#define zfs_fallthrough __attribute__((__fallthrough__))
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
#define typeof(x) __typeof(x)
|
||||
|
||||
#define uninitialized_var(x) x = x
|
||||
#define __maybe_unused __unused
|
||||
#define __always_unused __unused
|
||||
#define __must_check __result_use_check
|
||||
|
||||
#define __printf(a, b) __printflike(a, b)
|
||||
|
||||
#define barrier() __asm__ __volatile__("": : :"memory")
|
||||
#define ___PASTE(a, b) a##b
|
||||
#define __PASTE(a, b) ___PASTE(a, b)
|
||||
|
||||
#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x))
|
||||
|
||||
#define WRITE_ONCE(x, v) do { \
|
||||
barrier(); \
|
||||
ACCESS_ONCE(x) = (v); \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
#define lockless_dereference(p) READ_ONCE(p)
|
||||
|
||||
#define _AT(T, X) ((T)(X))
|
||||
|
||||
#endif /* _LINUX_COMPILER_H_ */
|
||||
|
@ -70,15 +70,6 @@ hlist_del(struct hlist_node *n)
|
||||
n->next->pprev = n->pprev;
|
||||
}
|
||||
/* BEGIN CSTYLED */
|
||||
#define READ_ONCE(x) ({ \
|
||||
__typeof(x) __var = ({ \
|
||||
barrier(); \
|
||||
ACCESS_ONCE(x); \
|
||||
}); \
|
||||
barrier(); \
|
||||
__var; \
|
||||
})
|
||||
|
||||
#define HLIST_HEAD_INIT { }
|
||||
#define HLIST_HEAD(name) struct hlist_head name = HLIST_HEAD_INIT
|
||||
#define INIT_HLIST_HEAD(head) (head)->first = NULL
|
||||
|
@ -95,10 +95,6 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
#ifndef expect
|
||||
#define expect(expr, value) (__builtin_expect((expr), (value)))
|
||||
#endif
|
||||
#ifndef __linux__
|
||||
#define likely(expr) expect((expr) != 0, 1)
|
||||
#define unlikely(expr) expect((expr) != 0, 0)
|
||||
#endif
|
||||
|
||||
#define PANIC(fmt, a...) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
|
||||
@ -109,7 +105,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
__FILE__, __FUNCTION__, __LINE__))
|
||||
|
||||
#define VERIFYF(cond, str, ...) do { \
|
||||
if (unlikely(!cond)) \
|
||||
if (unlikely(!(cond))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY(" #cond ") failed " str "\n", __VA_ARGS__);\
|
||||
} while (0)
|
||||
@ -205,7 +201,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
"failed (%lld " #OP " %lld) " STR "\n", \
|
||||
(long long)(_verify3_left), \
|
||||
(long long)(_verify3_right), \
|
||||
__VA_ARGS); \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3UF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
@ -217,7 +213,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
"failed (%llu " #OP " %llu) " STR "\n", \
|
||||
(unsigned long long)(_verify3_left), \
|
||||
(unsigned long long)(_verify3_right), \
|
||||
__VA_ARGS); \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3PF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
|
@ -94,6 +94,9 @@
|
||||
#define param_set_max_auto_ashift_args(var) \
|
||||
CTLTYPE_UINT, NULL, 0, param_set_max_auto_ashift, "IU"
|
||||
|
||||
#define param_set_raidz_impl_args(var) \
|
||||
CTLTYPE_STRING, NULL, 0, param_set_raidz_impl, "A"
|
||||
|
||||
#define spa_taskq_read_param_set_args(var) \
|
||||
CTLTYPE_STRING, NULL, 0, spa_taskq_read_param, "A"
|
||||
|
||||
|
@ -31,9 +31,9 @@
|
||||
|
||||
#include_next <sys/sdt.h>
|
||||
#ifdef KDTRACE_HOOKS
|
||||
/* BEGIN CSTYLED */
|
||||
SDT_PROBE_DECLARE(sdt, , , set__error);
|
||||
|
||||
/* BEGIN CSTYLED */
|
||||
#define SET_ERROR(err) ({ \
|
||||
SDT_PROBE1(sdt, , , set__error, (uintptr_t)err); \
|
||||
err; \
|
||||
|
@ -50,7 +50,7 @@
|
||||
#define kfpu_fini() do {} while (0)
|
||||
#endif
|
||||
|
||||
#define simd_stat_init() 0
|
||||
#define simd_stat_fini() 0
|
||||
#define simd_stat_init() do {} while (0)
|
||||
#define simd_stat_fini() do {} while (0)
|
||||
|
||||
#endif
|
||||
|
@ -68,47 +68,30 @@ enum symfollow { NO_FOLLOW = NOFOLLOW };
|
||||
#include <vm/vm_object.h>
|
||||
|
||||
typedef struct vop_vector vnodeops_t;
|
||||
#define VOP_FID VOP_VPTOFH
|
||||
#define vop_fid vop_vptofh
|
||||
#define vop_fid_args vop_vptofh_args
|
||||
#define a_fid a_fhp
|
||||
|
||||
#define rootvfs (rootvnode == NULL ? NULL : rootvnode->v_mount)
|
||||
|
||||
#ifndef IN_BASE
|
||||
static __inline int
|
||||
vn_is_readonly(vnode_t *vp)
|
||||
{
|
||||
return (vp->v_mount->mnt_flag & MNT_RDONLY);
|
||||
}
|
||||
#endif
|
||||
#define vn_vfswlock(vp) (0)
|
||||
#define vn_vfsunlock(vp) do { } while (0)
|
||||
#define vn_ismntpt(vp) \
|
||||
((vp)->v_type == VDIR && (vp)->v_mountedhere != NULL)
|
||||
#define vn_mountedvfs(vp) ((vp)->v_mountedhere)
|
||||
|
||||
#ifndef IN_BASE
|
||||
#define vn_has_cached_data(vp) \
|
||||
((vp)->v_object != NULL && \
|
||||
(vp)->v_object->resident_page_count > 0)
|
||||
|
||||
#ifndef IN_BASE
|
||||
static __inline void
|
||||
vn_flush_cached_data(vnode_t *vp, boolean_t sync)
|
||||
{
|
||||
if (vm_object_mightbedirty(vp->v_object)) {
|
||||
int flags = sync ? OBJPC_SYNC : 0;
|
||||
vn_lock(vp, LK_SHARED | LK_RETRY);
|
||||
zfs_vmobject_wlock(vp->v_object);
|
||||
vm_object_page_clean(vp->v_object, 0, 0, flags);
|
||||
zfs_vmobject_wunlock(vp->v_object);
|
||||
VOP_UNLOCK(vp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define vn_exists(vp) do { } while (0)
|
||||
#define vn_invalid(vp) do { } while (0)
|
||||
#define vn_free(vp) do { } while (0)
|
||||
#define vn_matchops(vp, vops) ((vp)->v_op == &(vops))
|
||||
|
||||
#define VN_HOLD(v) vref(v)
|
||||
@ -123,9 +106,6 @@ vn_flush_cached_data(vnode_t *vp, boolean_t sync)
|
||||
#define vnevent_rename_dest(vp, dvp, name, ct) do { } while (0)
|
||||
#define vnevent_rename_dest_dir(vp, ct) do { } while (0)
|
||||
|
||||
#define specvp(vp, rdev, type, cr) (VN_HOLD(vp), (vp))
|
||||
#define MANDLOCK(vp, mode) (0)
|
||||
|
||||
/*
|
||||
* We will use va_spare is place of Solaris' va_mask.
|
||||
* This field is initialized in zfs_setattr().
|
||||
|
@ -26,8 +26,10 @@
|
||||
#ifndef _ABD_OS_H
|
||||
#define _ABD_OS_H
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/vm.h>
|
||||
#include <vm/vm_page.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -47,8 +49,10 @@ struct abd_linear {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
__attribute__((malloc))
|
||||
struct abd *abd_alloc_from_pages(vm_page_t *, unsigned long, uint64_t);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
__FILE__, __FUNCTION__, __LINE__))
|
||||
|
||||
#define VERIFYF(cond, str, ...) do { \
|
||||
if (unlikely(!cond)) \
|
||||
if (unlikely(!(cond))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY(" #cond ") failed " str "\n", __VA_ARGS__);\
|
||||
} while (0)
|
||||
@ -205,7 +205,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
"failed (%lld " #OP " %lld) " STR "\n", \
|
||||
(long long)(_verify3_left), \
|
||||
(long long)(_verify3_right), \
|
||||
__VA_ARGS); \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3UF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
@ -217,7 +217,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
"failed (%llu " #OP " %llu) " STR "\n", \
|
||||
(unsigned long long)(_verify3_left), \
|
||||
(unsigned long long)(_verify3_right), \
|
||||
__VA_ARGS); \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3PF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
|
@ -38,8 +38,7 @@
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/wmsum.h>
|
||||
|
||||
typedef struct kstat_s kstat_t;
|
||||
#include <sys/kstat.h>
|
||||
|
||||
#define TASKQ_NAMELEN 31
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
#define TS_ZOMB EXIT_ZOMBIE
|
||||
#define TS_STOPPED TASK_STOPPED
|
||||
|
||||
typedef void (*thread_func_t)(void *);
|
||||
typedef void (*thread_func_t)(void *) __attribute__((noreturn));
|
||||
|
||||
#define thread_create_named(name, stk, stksize, func, arg, len, \
|
||||
pp, state, pri) \
|
||||
|
@ -40,7 +40,7 @@
|
||||
*/
|
||||
#define UIO_DIRECT 0x0001 /* Direct I/O request */
|
||||
|
||||
#if defined(HAVE_VFS_IOV_ITER) && defined(HAVE_FAULT_IN_IOV_ITER_READABLE)
|
||||
#if defined(HAVE_FAULT_IN_IOV_ITER_READABLE)
|
||||
#define iov_iter_fault_in_readable(a, b) fault_in_iov_iter_readable(a, b)
|
||||
#endif
|
||||
|
||||
@ -52,12 +52,9 @@ typedef enum zfs_uio_rw {
|
||||
} zfs_uio_rw_t;
|
||||
|
||||
typedef enum zfs_uio_seg {
|
||||
UIO_USERSPACE = 0,
|
||||
UIO_SYSSPACE = 1,
|
||||
UIO_BVEC = 2,
|
||||
#if defined(HAVE_VFS_IOV_ITER)
|
||||
UIO_ITER = 3,
|
||||
#endif
|
||||
UIO_SYSSPACE = 0,
|
||||
UIO_BVEC = 1,
|
||||
UIO_ITER = 2,
|
||||
} zfs_uio_seg_t;
|
||||
|
||||
/*
|
||||
@ -66,15 +63,14 @@ typedef enum zfs_uio_seg {
|
||||
typedef struct {
|
||||
struct page **pages; /* Mapped pages */
|
||||
long npages; /* Number of mapped pages */
|
||||
boolean_t pinned; /* Whether FOLL_PIN was used */
|
||||
} zfs_uio_dio_t;
|
||||
|
||||
typedef struct zfs_uio {
|
||||
union {
|
||||
const struct iovec *uio_iov;
|
||||
const struct bio_vec *uio_bvec;
|
||||
#if defined(HAVE_VFS_IOV_ITER)
|
||||
struct iov_iter *uio_iter;
|
||||
#endif
|
||||
};
|
||||
int uio_iovcnt; /* Number of iovecs */
|
||||
offset_t uio_soffset; /* Starting logical offset */
|
||||
@ -129,7 +125,7 @@ zfs_uio_iovec_init(zfs_uio_t *uio, const struct iovec *iov,
|
||||
unsigned long nr_segs, offset_t offset, zfs_uio_seg_t seg, ssize_t resid,
|
||||
size_t skip)
|
||||
{
|
||||
ASSERT(seg == UIO_USERSPACE || seg == UIO_SYSSPACE);
|
||||
ASSERT(seg == UIO_SYSSPACE);
|
||||
|
||||
uio->uio_iov = iov;
|
||||
uio->uio_iovcnt = nr_segs;
|
||||
@ -175,7 +171,6 @@ zfs_uio_bvec_init(zfs_uio_t *uio, struct bio *bio, struct request *rq)
|
||||
memset(&uio->uio_dio, 0, sizeof (zfs_uio_dio_t));
|
||||
}
|
||||
|
||||
#if defined(HAVE_VFS_IOV_ITER)
|
||||
static inline void
|
||||
zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
|
||||
ssize_t resid, size_t skip)
|
||||
@ -192,7 +187,6 @@ zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
|
||||
uio->uio_soffset = uio->uio_loffset;
|
||||
memset(&uio->uio_dio, 0, sizeof (zfs_uio_dio_t));
|
||||
}
|
||||
#endif /* HAVE_VFS_IOV_ITER */
|
||||
|
||||
#if defined(HAVE_ITER_IOV)
|
||||
#define zfs_uio_iter_iov(iter) iter_iov((iter))
|
||||
@ -206,4 +200,13 @@ zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
|
||||
#define zfs_uio_iov_iter_type(iter) (iter)->type
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ITER_IS_UBUF)
|
||||
#define zfs_user_backed_iov_iter(iter) \
|
||||
(iter_is_ubuf((iter)) || \
|
||||
(zfs_uio_iov_iter_type((iter)) == ITER_IOVEC))
|
||||
#else
|
||||
#define zfs_user_backed_iov_iter(iter) \
|
||||
(zfs_uio_iov_iter_type((iter)) == ITER_IOVEC)
|
||||
#endif
|
||||
|
||||
#endif /* SPL_UIO_H */
|
||||
|
@ -30,6 +30,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct abd;
|
||||
|
||||
struct abd_scatter {
|
||||
uint_t abd_offset;
|
||||
uint_t abd_nents;
|
||||
@ -41,10 +43,8 @@ struct abd_linear {
|
||||
struct scatterlist *abd_sgl; /* for LINEAR_PAGE */
|
||||
};
|
||||
|
||||
typedef struct abd abd_t;
|
||||
|
||||
typedef int abd_iter_page_func_t(struct page *, size_t, size_t, void *);
|
||||
int abd_iterate_page_func(abd_t *, size_t, size_t, abd_iter_page_func_t *,
|
||||
int abd_iterate_page_func(struct abd *, size_t, size_t, abd_iter_page_func_t *,
|
||||
void *);
|
||||
|
||||
/*
|
||||
@ -52,11 +52,11 @@ int abd_iterate_page_func(abd_t *, size_t, size_t, abd_iter_page_func_t *,
|
||||
* Note: these are only needed to support vdev_classic. See comment in
|
||||
* vdev_disk.c.
|
||||
*/
|
||||
unsigned int abd_bio_map_off(struct bio *, abd_t *, unsigned int, size_t);
|
||||
unsigned long abd_nr_pages_off(abd_t *, unsigned int, size_t);
|
||||
unsigned int abd_bio_map_off(struct bio *, struct abd *, unsigned int, size_t);
|
||||
unsigned long abd_nr_pages_off(struct abd *, unsigned int, size_t);
|
||||
|
||||
__attribute__((malloc))
|
||||
abd_t *abd_alloc_from_pages(struct page **, unsigned long, uint64_t);
|
||||
struct abd *abd_alloc_from_pages(struct page **, unsigned long, uint64_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ typedef struct vfs {
|
||||
boolean_t vfs_do_relatime;
|
||||
boolean_t vfs_nbmand;
|
||||
boolean_t vfs_do_nbmand;
|
||||
kmutex_t vfs_mntpt_lock;
|
||||
} vfs_t;
|
||||
|
||||
typedef struct zfs_mnt {
|
||||
|
@ -347,6 +347,7 @@ void l2arc_fini(void);
|
||||
void l2arc_start(void);
|
||||
void l2arc_stop(void);
|
||||
void l2arc_spa_rebuild_start(spa_t *spa);
|
||||
void l2arc_spa_rebuild_stop(spa_t *spa);
|
||||
|
||||
#ifndef _KERNEL
|
||||
extern boolean_t arc_watch;
|
||||
|
@ -942,6 +942,7 @@ typedef struct arc_sums {
|
||||
wmsum_t arcstat_evict_l2_eligible_mru;
|
||||
wmsum_t arcstat_evict_l2_ineligible;
|
||||
wmsum_t arcstat_evict_l2_skip;
|
||||
wmsum_t arcstat_hash_elements;
|
||||
wmsum_t arcstat_hash_collisions;
|
||||
wmsum_t arcstat_hash_chains;
|
||||
aggsum_t arcstat_size;
|
||||
|
@ -86,28 +86,38 @@ typedef struct brt_vdev_phys {
|
||||
uint64_t bvp_savedspace;
|
||||
} brt_vdev_phys_t;
|
||||
|
||||
typedef struct brt_vdev {
|
||||
struct brt_vdev {
|
||||
/*
|
||||
* Pending changes from open contexts.
|
||||
*/
|
||||
kmutex_t bv_pending_lock;
|
||||
avl_tree_t bv_pending_tree[TXG_SIZE];
|
||||
/*
|
||||
* Protects bv_mos_*.
|
||||
*/
|
||||
krwlock_t bv_mos_entries_lock ____cacheline_aligned;
|
||||
/*
|
||||
* Protects all the fields starting from bv_initiated.
|
||||
*/
|
||||
krwlock_t bv_lock ____cacheline_aligned;
|
||||
/*
|
||||
* VDEV id.
|
||||
*/
|
||||
uint64_t bv_vdevid;
|
||||
/*
|
||||
* Is the structure initiated?
|
||||
* (bv_entcount and bv_bitmap are allocated?)
|
||||
*/
|
||||
boolean_t bv_initiated;
|
||||
uint64_t bv_vdevid ____cacheline_aligned;
|
||||
/*
|
||||
* Object number in the MOS for the entcount array and brt_vdev_phys.
|
||||
*/
|
||||
uint64_t bv_mos_brtvdev;
|
||||
/*
|
||||
* Object number in the MOS for the entries table.
|
||||
* Object number in the MOS and dnode for the entries table.
|
||||
*/
|
||||
uint64_t bv_mos_entries;
|
||||
dnode_t *bv_mos_entries_dnode;
|
||||
/*
|
||||
* Entries to sync.
|
||||
* Is the structure initiated?
|
||||
* (bv_entcount and bv_bitmap are allocated?)
|
||||
*/
|
||||
avl_tree_t bv_tree;
|
||||
boolean_t bv_initiated;
|
||||
/*
|
||||
* Does the bv_entcount[] array needs byte swapping?
|
||||
*/
|
||||
@ -120,6 +130,26 @@ typedef struct brt_vdev {
|
||||
* This is the array with BRT entry count per BRT_RANGESIZE.
|
||||
*/
|
||||
uint16_t *bv_entcount;
|
||||
/*
|
||||
* bv_entcount[] potentially can be a bit too big to sychronize it all
|
||||
* when we just changed few entcounts. The fields below allow us to
|
||||
* track updates to bv_entcount[] array since the last sync.
|
||||
* A single bit in the bv_bitmap represents as many entcounts as can
|
||||
* fit into a single BRT_BLOCKSIZE.
|
||||
* For example we have 65536 entcounts in the bv_entcount array
|
||||
* (so the whole array is 128kB). We updated bv_entcount[2] and
|
||||
* bv_entcount[5]. In that case only first bit in the bv_bitmap will
|
||||
* be set and we will write only first BRT_BLOCKSIZE out of 128kB.
|
||||
*/
|
||||
ulong_t *bv_bitmap;
|
||||
/*
|
||||
* bv_entcount[] needs updating on disk.
|
||||
*/
|
||||
boolean_t bv_entcount_dirty;
|
||||
/*
|
||||
* brt_vdev_phys needs updating on disk.
|
||||
*/
|
||||
boolean_t bv_meta_dirty;
|
||||
/*
|
||||
* Sum of all bv_entcount[]s.
|
||||
*/
|
||||
@ -133,65 +163,27 @@ typedef struct brt_vdev {
|
||||
*/
|
||||
uint64_t bv_savedspace;
|
||||
/*
|
||||
* brt_vdev_phys needs updating on disk.
|
||||
* Entries to sync.
|
||||
*/
|
||||
boolean_t bv_meta_dirty;
|
||||
/*
|
||||
* bv_entcount[] needs updating on disk.
|
||||
*/
|
||||
boolean_t bv_entcount_dirty;
|
||||
/*
|
||||
* bv_entcount[] potentially can be a bit too big to sychronize it all
|
||||
* when we just changed few entcounts. The fields below allow us to
|
||||
* track updates to bv_entcount[] array since the last sync.
|
||||
* A single bit in the bv_bitmap represents as many entcounts as can
|
||||
* fit into a single BRT_BLOCKSIZE.
|
||||
* For example we have 65536 entcounts in the bv_entcount array
|
||||
* (so the whole array is 128kB). We updated bv_entcount[2] and
|
||||
* bv_entcount[5]. In that case only first bit in the bv_bitmap will
|
||||
* be set and we will write only first BRT_BLOCKSIZE out of 128kB.
|
||||
*/
|
||||
ulong_t *bv_bitmap;
|
||||
uint64_t bv_nblocks;
|
||||
} brt_vdev_t;
|
||||
avl_tree_t bv_tree;
|
||||
};
|
||||
|
||||
/*
|
||||
* In-core brt
|
||||
*/
|
||||
typedef struct brt {
|
||||
krwlock_t brt_lock;
|
||||
spa_t *brt_spa;
|
||||
#define brt_mos brt_spa->spa_meta_objset
|
||||
uint64_t brt_rangesize;
|
||||
uint64_t brt_usedspace;
|
||||
uint64_t brt_savedspace;
|
||||
avl_tree_t brt_pending_tree[TXG_SIZE];
|
||||
kmutex_t brt_pending_lock[TXG_SIZE];
|
||||
/* Sum of all entries across all bv_trees. */
|
||||
uint64_t brt_nentries;
|
||||
brt_vdev_t *brt_vdevs;
|
||||
uint64_t brt_nvdevs;
|
||||
} brt_t;
|
||||
|
||||
/* Size of bre_offset / sizeof (uint64_t). */
|
||||
/* Size of offset / sizeof (uint64_t). */
|
||||
#define BRT_KEY_WORDS (1)
|
||||
|
||||
#define BRE_OFFSET(bre) (DVA_GET_OFFSET(&(bre)->bre_bp.blk_dva[0]))
|
||||
|
||||
/*
|
||||
* In-core brt entry.
|
||||
* On-disk we use bre_offset as the key and bre_refcount as the value.
|
||||
* On-disk we use ZAP with offset as the key and count as the value.
|
||||
*/
|
||||
typedef struct brt_entry {
|
||||
uint64_t bre_offset;
|
||||
uint64_t bre_refcount;
|
||||
avl_node_t bre_node;
|
||||
blkptr_t bre_bp;
|
||||
uint64_t bre_count;
|
||||
uint64_t bre_pcount;
|
||||
} brt_entry_t;
|
||||
|
||||
typedef struct brt_pending_entry {
|
||||
blkptr_t bpe_bp;
|
||||
int bpe_count;
|
||||
avl_node_t bpe_node;
|
||||
} brt_pending_entry_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -171,7 +171,6 @@ typedef struct dbuf_dirty_record {
|
||||
* gets COW'd in a subsequent transaction group.
|
||||
*/
|
||||
arc_buf_t *dr_data;
|
||||
blkptr_t dr_overridden_by;
|
||||
override_states_t dr_override_state;
|
||||
uint8_t dr_copies;
|
||||
boolean_t dr_nopwrite;
|
||||
@ -179,14 +178,21 @@ typedef struct dbuf_dirty_record {
|
||||
boolean_t dr_diowrite;
|
||||
boolean_t dr_has_raw_params;
|
||||
|
||||
/*
|
||||
* If dr_has_raw_params is set, the following crypt
|
||||
* params will be set on the BP that's written.
|
||||
*/
|
||||
boolean_t dr_byteorder;
|
||||
uint8_t dr_salt[ZIO_DATA_SALT_LEN];
|
||||
uint8_t dr_iv[ZIO_DATA_IV_LEN];
|
||||
uint8_t dr_mac[ZIO_DATA_MAC_LEN];
|
||||
/* Override and raw params are mutually exclusive. */
|
||||
union {
|
||||
blkptr_t dr_overridden_by;
|
||||
struct {
|
||||
/*
|
||||
* If dr_has_raw_params is set, the
|
||||
* following crypt params will be set
|
||||
* on the BP that's written.
|
||||
*/
|
||||
boolean_t dr_byteorder;
|
||||
uint8_t dr_salt[ZIO_DATA_SALT_LEN];
|
||||
uint8_t dr_iv[ZIO_DATA_IV_LEN];
|
||||
uint8_t dr_mac[ZIO_DATA_MAC_LEN];
|
||||
};
|
||||
};
|
||||
} dl;
|
||||
struct dirty_lightweight_leaf {
|
||||
/*
|
||||
@ -264,6 +270,27 @@ typedef struct dmu_buf_impl {
|
||||
*/
|
||||
uint8_t db_level;
|
||||
|
||||
/* This block was freed while a read or write was active. */
|
||||
uint8_t db_freed_in_flight;
|
||||
|
||||
/*
|
||||
* Evict user data as soon as the dirty and reference counts are equal.
|
||||
*/
|
||||
uint8_t db_user_immediate_evict;
|
||||
|
||||
/*
|
||||
* dnode_evict_dbufs() or dnode_evict_bonus() tried to evict this dbuf,
|
||||
* but couldn't due to outstanding references. Evict once the refcount
|
||||
* drops to 0.
|
||||
*/
|
||||
uint8_t db_pending_evict;
|
||||
|
||||
/* Number of TXGs in which this buffer is dirty. */
|
||||
uint8_t db_dirtycnt;
|
||||
|
||||
/* The buffer was partially read. More reads may follow. */
|
||||
uint8_t db_partial_read;
|
||||
|
||||
/*
|
||||
* Protects db_buf's contents if they contain an indirect block or data
|
||||
* block of the meta-dnode. We use this lock to protect the structure of
|
||||
@ -288,6 +315,9 @@ typedef struct dmu_buf_impl {
|
||||
*/
|
||||
dbuf_states_t db_state;
|
||||
|
||||
/* In which dbuf cache this dbuf is, if any. */
|
||||
dbuf_cached_state_t db_caching_status;
|
||||
|
||||
/*
|
||||
* Refcount accessed by dmu_buf_{hold,rele}.
|
||||
* If nonzero, the buffer can't be destroyed.
|
||||
@ -304,39 +334,10 @@ typedef struct dmu_buf_impl {
|
||||
/* Link in dbuf_cache or dbuf_metadata_cache */
|
||||
multilist_node_t db_cache_link;
|
||||
|
||||
/* Tells us which dbuf cache this dbuf is in, if any */
|
||||
dbuf_cached_state_t db_caching_status;
|
||||
|
||||
uint64_t db_hash;
|
||||
|
||||
/* Data which is unique to data (leaf) blocks: */
|
||||
|
||||
/* User callback information. */
|
||||
dmu_buf_user_t *db_user;
|
||||
|
||||
/*
|
||||
* Evict user data as soon as the dirty and reference
|
||||
* counts are equal.
|
||||
*/
|
||||
uint8_t db_user_immediate_evict;
|
||||
|
||||
/*
|
||||
* This block was freed while a read or write was
|
||||
* active.
|
||||
*/
|
||||
uint8_t db_freed_in_flight;
|
||||
|
||||
/*
|
||||
* dnode_evict_dbufs() or dnode_evict_bonus() tried to
|
||||
* evict this dbuf, but couldn't due to outstanding
|
||||
* references. Evict once the refcount drops to 0.
|
||||
*/
|
||||
uint8_t db_pending_evict;
|
||||
|
||||
uint8_t db_dirtycnt;
|
||||
|
||||
/* The buffer was partially read. More reads may follow. */
|
||||
uint8_t db_partial_read;
|
||||
} dmu_buf_impl_t;
|
||||
|
||||
#define DBUF_HASH_MUTEX(h, idx) \
|
||||
@ -351,6 +352,8 @@ typedef struct dbuf_hash_table {
|
||||
|
||||
typedef void (*dbuf_prefetch_fn)(void *, uint64_t, uint64_t, boolean_t);
|
||||
|
||||
extern kmem_cache_t *dbuf_dirty_kmem_cache;
|
||||
|
||||
uint64_t dbuf_whichblock(const struct dnode *di, const int64_t level,
|
||||
const uint64_t offset);
|
||||
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include <sys/cred.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <sys/zio_compress.h>
|
||||
#include <sys/zio_priority.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/zfs_file.h>
|
||||
|
||||
@ -381,6 +380,7 @@ typedef struct dmu_buf {
|
||||
#define DMU_POOL_CREATION_VERSION "creation_version"
|
||||
#define DMU_POOL_SCAN "scan"
|
||||
#define DMU_POOL_ERRORSCRUB "error_scrub"
|
||||
#define DMU_POOL_LAST_SCRUBBED_TXG "last_scrubbed_txg"
|
||||
#define DMU_POOL_FREE_BPOBJ "free_bpobj"
|
||||
#define DMU_POOL_BPTREE_OBJ "bptree_obj"
|
||||
#define DMU_POOL_EMPTY_BPOBJ "empty_bpobj"
|
||||
|
@ -335,7 +335,7 @@ struct dnode {
|
||||
/* protected by dn_mtx: */
|
||||
kmutex_t dn_mtx;
|
||||
list_t dn_dirty_records[TXG_SIZE];
|
||||
struct range_tree *dn_free_ranges[TXG_SIZE];
|
||||
struct zfs_range_tree *dn_free_ranges[TXG_SIZE];
|
||||
uint64_t dn_allocated_txg;
|
||||
uint64_t dn_free_txg;
|
||||
uint64_t dn_assigned_txg;
|
||||
|
@ -89,7 +89,7 @@ extern int zfs_livelist_min_percent_shared;
|
||||
|
||||
typedef int deadlist_iter_t(void *args, dsl_deadlist_entry_t *dle);
|
||||
|
||||
void dsl_deadlist_open(dsl_deadlist_t *dl, objset_t *os, uint64_t object);
|
||||
int dsl_deadlist_open(dsl_deadlist_t *dl, objset_t *os, uint64_t object);
|
||||
void dsl_deadlist_close(dsl_deadlist_t *dl);
|
||||
void dsl_deadlist_iterate(dsl_deadlist_t *dl, deadlist_iter_t func, void *arg);
|
||||
uint64_t dsl_deadlist_alloc(objset_t *os, dmu_tx_t *tx);
|
||||
|
@ -198,7 +198,7 @@ void dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, uint64_t value,
|
||||
dmu_tx_t *tx);
|
||||
void dsl_dir_zapify(dsl_dir_t *dd, dmu_tx_t *tx);
|
||||
boolean_t dsl_dir_is_zapified(dsl_dir_t *dd);
|
||||
void dsl_dir_livelist_open(dsl_dir_t *dd, uint64_t obj);
|
||||
int dsl_dir_livelist_open(dsl_dir_t *dd, uint64_t obj);
|
||||
void dsl_dir_livelist_close(dsl_dir_t *dd);
|
||||
void dsl_dir_remove_livelist(dsl_dir_t *dd, dmu_tx_t *tx, boolean_t total);
|
||||
int dsl_dir_wait(dsl_dir_t *dd, dsl_dataset_t *ds, zfs_wait_activity_t activity,
|
||||
|
@ -179,6 +179,12 @@ typedef struct dsl_scan {
|
||||
dsl_errorscrub_phys_t errorscrub_phys;
|
||||
} dsl_scan_t;
|
||||
|
||||
typedef struct {
|
||||
pool_scan_func_t func;
|
||||
uint64_t txgstart;
|
||||
uint64_t txgend;
|
||||
} setup_sync_arg_t;
|
||||
|
||||
typedef struct dsl_scan_io_queue dsl_scan_io_queue_t;
|
||||
|
||||
void scan_init(void);
|
||||
@ -189,7 +195,8 @@ void dsl_scan_setup_sync(void *, dmu_tx_t *);
|
||||
void dsl_scan_fini(struct dsl_pool *dp);
|
||||
void dsl_scan_sync(struct dsl_pool *, dmu_tx_t *);
|
||||
int dsl_scan_cancel(struct dsl_pool *);
|
||||
int dsl_scan(struct dsl_pool *, pool_scan_func_t);
|
||||
int dsl_scan(struct dsl_pool *, pool_scan_func_t, uint64_t starttxg,
|
||||
uint64_t txgend);
|
||||
void dsl_scan_assess_vdev(struct dsl_pool *dp, vdev_t *vd);
|
||||
boolean_t dsl_scan_scrubbing(const struct dsl_pool *dp);
|
||||
boolean_t dsl_errorscrubbing(const struct dsl_pool *dp);
|
||||
|
@ -42,7 +42,8 @@ extern "C" {
|
||||
#define FM_EREPORT_ZFS_DATA "data"
|
||||
#define FM_EREPORT_ZFS_DELAY "delay"
|
||||
#define FM_EREPORT_ZFS_DEADMAN "deadman"
|
||||
#define FM_EREPORT_ZFS_DIO_VERIFY "dio_verify"
|
||||
#define FM_EREPORT_ZFS_DIO_VERIFY_WR "dio_verify_wr"
|
||||
#define FM_EREPORT_ZFS_DIO_VERIFY_RD "dio_verify_rd"
|
||||
#define FM_EREPORT_ZFS_POOL "zpool"
|
||||
#define FM_EREPORT_ZFS_DEVICE_UNKNOWN "vdev.unknown"
|
||||
#define FM_EREPORT_ZFS_DEVICE_OPEN_FAILED "vdev.open_failed"
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2024 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2011, 2014, 2016, 2024 by Delphix. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2017 Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Integros [integros.com]
|
||||
@ -37,7 +37,6 @@
|
||||
#define _SYS_FS_ZFS_H extern __attribute__((visibility("default")))
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/zio_priority.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -265,6 +264,7 @@ typedef enum {
|
||||
ZPOOL_PROP_DEDUP_TABLE_SIZE,
|
||||
ZPOOL_PROP_DEDUP_TABLE_QUOTA,
|
||||
ZPOOL_PROP_DEDUPCACHED,
|
||||
ZPOOL_PROP_LAST_SCRUBBED_TXG,
|
||||
ZPOOL_NUM_PROPS
|
||||
} zpool_prop_t;
|
||||
|
||||
@ -1088,6 +1088,7 @@ typedef enum pool_scan_func {
|
||||
typedef enum pool_scrub_cmd {
|
||||
POOL_SCRUB_NORMAL = 0,
|
||||
POOL_SCRUB_PAUSE,
|
||||
POOL_SCRUB_FROM_LAST_TXG,
|
||||
POOL_SCRUB_FLAGS_END
|
||||
} pool_scrub_cmd_t;
|
||||
|
||||
@ -1124,6 +1125,26 @@ typedef enum zio_type {
|
||||
*/
|
||||
#define ZIO_TYPE_IOCTL ZIO_TYPE_FLUSH
|
||||
|
||||
/*
|
||||
* ZIO priority types. Needed to interpret vdev statistics below.
|
||||
*
|
||||
* NOTE: PLEASE UPDATE THE ENUM STRINGS IN zfs_valstr.c IF YOU ADD ANOTHER
|
||||
* VALUE.
|
||||
*/
|
||||
typedef enum zio_priority {
|
||||
ZIO_PRIORITY_SYNC_READ,
|
||||
ZIO_PRIORITY_SYNC_WRITE, /* ZIL */
|
||||
ZIO_PRIORITY_ASYNC_READ, /* prefetch */
|
||||
ZIO_PRIORITY_ASYNC_WRITE, /* spa_sync() */
|
||||
ZIO_PRIORITY_SCRUB, /* asynchronous scrub/resilver reads */
|
||||
ZIO_PRIORITY_REMOVAL, /* reads/writes for vdev removal */
|
||||
ZIO_PRIORITY_INITIALIZING, /* initializing I/O */
|
||||
ZIO_PRIORITY_TRIM, /* trim I/O (discard) */
|
||||
ZIO_PRIORITY_REBUILD, /* reads/writes for vdev rebuild */
|
||||
ZIO_PRIORITY_NUM_QUEUEABLE,
|
||||
ZIO_PRIORITY_NOW, /* non-queued i/os (e.g. free) */
|
||||
} zio_priority_t;
|
||||
|
||||
/*
|
||||
* Pool statistics. Note: all fields should be 64-bit because this
|
||||
* is passed between kernel and userland as an nvlist uint64 array.
|
||||
|
@ -139,7 +139,7 @@ void metaslab_set_selected_txg(metaslab_t *, uint64_t);
|
||||
|
||||
extern int metaslab_debug_load;
|
||||
|
||||
range_seg_type_t metaslab_calculate_range_tree_type(vdev_t *vdev,
|
||||
zfs_range_seg_type_t metaslab_calculate_range_tree_type(vdev_t *vdev,
|
||||
metaslab_t *msp, uint64_t *start, uint64_t *shift);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -200,7 +200,7 @@ struct metaslab_class {
|
||||
uint64_t mc_deferred; /* total deferred frees */
|
||||
uint64_t mc_space; /* total space (alloc + free) */
|
||||
uint64_t mc_dspace; /* total deflated space */
|
||||
uint64_t mc_histogram[RANGE_TREE_HISTOGRAM_SIZE];
|
||||
uint64_t mc_histogram[ZFS_RANGE_TREE_HISTOGRAM_SIZE];
|
||||
|
||||
/*
|
||||
* List of all loaded metaslabs in the class, sorted in order of most
|
||||
@ -290,7 +290,7 @@ struct metaslab_group {
|
||||
uint64_t mg_allocations;
|
||||
uint64_t mg_failed_allocations;
|
||||
uint64_t mg_fragmentation;
|
||||
uint64_t mg_histogram[RANGE_TREE_HISTOGRAM_SIZE];
|
||||
uint64_t mg_histogram[ZFS_RANGE_TREE_HISTOGRAM_SIZE];
|
||||
|
||||
int mg_ms_disabled;
|
||||
boolean_t mg_disabled_updating;
|
||||
@ -398,8 +398,8 @@ struct metaslab {
|
||||
uint64_t ms_size;
|
||||
uint64_t ms_fragmentation;
|
||||
|
||||
range_tree_t *ms_allocating[TXG_SIZE];
|
||||
range_tree_t *ms_allocatable;
|
||||
zfs_range_tree_t *ms_allocating[TXG_SIZE];
|
||||
zfs_range_tree_t *ms_allocatable;
|
||||
uint64_t ms_allocated_this_txg;
|
||||
uint64_t ms_allocating_total;
|
||||
|
||||
@ -408,10 +408,12 @@ struct metaslab {
|
||||
* ms_free*tree only have entries while syncing, and are empty
|
||||
* between syncs.
|
||||
*/
|
||||
range_tree_t *ms_freeing; /* to free this syncing txg */
|
||||
range_tree_t *ms_freed; /* already freed this syncing txg */
|
||||
range_tree_t *ms_defer[TXG_DEFER_SIZE];
|
||||
range_tree_t *ms_checkpointing; /* to add to the checkpoint */
|
||||
zfs_range_tree_t *ms_freeing; /* to free this syncing txg */
|
||||
/* already freed this syncing txg */
|
||||
zfs_range_tree_t *ms_freed;
|
||||
zfs_range_tree_t *ms_defer[TXG_DEFER_SIZE];
|
||||
/* to add to the checkpoint */
|
||||
zfs_range_tree_t *ms_checkpointing;
|
||||
|
||||
/*
|
||||
* The ms_trim tree is the set of allocatable segments which are
|
||||
@ -421,7 +423,7 @@ struct metaslab {
|
||||
* is unloaded. Its purpose is to aggregate freed ranges to
|
||||
* facilitate efficient trimming.
|
||||
*/
|
||||
range_tree_t *ms_trim;
|
||||
zfs_range_tree_t *ms_trim;
|
||||
|
||||
boolean_t ms_condensing; /* condensing? */
|
||||
boolean_t ms_condense_wanted;
|
||||
@ -542,8 +544,8 @@ struct metaslab {
|
||||
* Allocs and frees that are committed to the vdev log spacemap but
|
||||
* not yet to this metaslab's spacemap.
|
||||
*/
|
||||
range_tree_t *ms_unflushed_allocs;
|
||||
range_tree_t *ms_unflushed_frees;
|
||||
zfs_range_tree_t *ms_unflushed_allocs;
|
||||
zfs_range_tree_t *ms_unflushed_frees;
|
||||
|
||||
/*
|
||||
* We have flushed entries up to but not including this TXG. In
|
||||
|
@ -37,25 +37,25 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RANGE_TREE_HISTOGRAM_SIZE 64
|
||||
#define ZFS_RANGE_TREE_HISTOGRAM_SIZE 64
|
||||
|
||||
typedef struct range_tree_ops range_tree_ops_t;
|
||||
typedef struct zfs_range_tree_ops zfs_range_tree_ops_t;
|
||||
|
||||
typedef enum range_seg_type {
|
||||
RANGE_SEG32,
|
||||
RANGE_SEG64,
|
||||
RANGE_SEG_GAP,
|
||||
RANGE_SEG_NUM_TYPES,
|
||||
} range_seg_type_t;
|
||||
typedef enum zfs_range_seg_type {
|
||||
ZFS_RANGE_SEG32,
|
||||
ZFS_RANGE_SEG64,
|
||||
ZFS_RANGE_SEG_GAP,
|
||||
ZFS_RANGE_SEG_NUM_TYPES,
|
||||
} zfs_range_seg_type_t;
|
||||
|
||||
/*
|
||||
* Note: the range_tree may not be accessed concurrently; consumers
|
||||
* must provide external locking if required.
|
||||
*/
|
||||
typedef struct range_tree {
|
||||
typedef struct zfs_range_tree {
|
||||
zfs_btree_t rt_root; /* offset-ordered segment b-tree */
|
||||
uint64_t rt_space; /* sum of all segments in the map */
|
||||
range_seg_type_t rt_type; /* type of range_seg_t in use */
|
||||
zfs_range_seg_type_t rt_type; /* type of zfs_range_seg_t in use */
|
||||
/*
|
||||
* All data that is stored in the range tree must have a start higher
|
||||
* than or equal to rt_start, and all sizes and offsets must be
|
||||
@ -63,7 +63,7 @@ typedef struct range_tree {
|
||||
*/
|
||||
uint8_t rt_shift;
|
||||
uint64_t rt_start;
|
||||
const range_tree_ops_t *rt_ops;
|
||||
const zfs_range_tree_ops_t *rt_ops;
|
||||
void *rt_arg;
|
||||
uint64_t rt_gap; /* allowable inter-segment gap */
|
||||
|
||||
@ -72,61 +72,61 @@ typedef struct range_tree {
|
||||
* rt_histogram[i], contains the number of ranges whose size is:
|
||||
* 2^i <= size of range in bytes < 2^(i+1)
|
||||
*/
|
||||
uint64_t rt_histogram[RANGE_TREE_HISTOGRAM_SIZE];
|
||||
} range_tree_t;
|
||||
uint64_t rt_histogram[ZFS_RANGE_TREE_HISTOGRAM_SIZE];
|
||||
} zfs_range_tree_t;
|
||||
|
||||
typedef struct range_seg32 {
|
||||
typedef struct zfs_range_seg32 {
|
||||
uint32_t rs_start; /* starting offset of this segment */
|
||||
uint32_t rs_end; /* ending offset (non-inclusive) */
|
||||
} range_seg32_t;
|
||||
} zfs_range_seg32_t;
|
||||
|
||||
/*
|
||||
* Extremely large metaslabs, vdev-wide trees, and dnode-wide trees may
|
||||
* require 64-bit integers for ranges.
|
||||
*/
|
||||
typedef struct range_seg64 {
|
||||
typedef struct zfs_range_seg64 {
|
||||
uint64_t rs_start; /* starting offset of this segment */
|
||||
uint64_t rs_end; /* ending offset (non-inclusive) */
|
||||
} range_seg64_t;
|
||||
} zfs_range_seg64_t;
|
||||
|
||||
typedef struct range_seg_gap {
|
||||
typedef struct zfs_range_seg_gap {
|
||||
uint64_t rs_start; /* starting offset of this segment */
|
||||
uint64_t rs_end; /* ending offset (non-inclusive) */
|
||||
uint64_t rs_fill; /* actual fill if gap mode is on */
|
||||
} range_seg_gap_t;
|
||||
} zfs_range_seg_gap_t;
|
||||
|
||||
/*
|
||||
* This type needs to be the largest of the range segs, since it will be stack
|
||||
* allocated and then cast the actual type to do tree operations.
|
||||
*/
|
||||
typedef range_seg_gap_t range_seg_max_t;
|
||||
typedef zfs_range_seg_gap_t zfs_range_seg_max_t;
|
||||
|
||||
/*
|
||||
* This is just for clarity of code purposes, so we can make it clear that a
|
||||
* pointer is to a range seg of some type; when we need to do the actual math,
|
||||
* we'll figure out the real type.
|
||||
*/
|
||||
typedef void range_seg_t;
|
||||
typedef void zfs_range_seg_t;
|
||||
|
||||
struct range_tree_ops {
|
||||
void (*rtop_create)(range_tree_t *rt, void *arg);
|
||||
void (*rtop_destroy)(range_tree_t *rt, void *arg);
|
||||
void (*rtop_add)(range_tree_t *rt, void *rs, void *arg);
|
||||
void (*rtop_remove)(range_tree_t *rt, void *rs, void *arg);
|
||||
void (*rtop_vacate)(range_tree_t *rt, void *arg);
|
||||
struct zfs_range_tree_ops {
|
||||
void (*rtop_create)(zfs_range_tree_t *rt, void *arg);
|
||||
void (*rtop_destroy)(zfs_range_tree_t *rt, void *arg);
|
||||
void (*rtop_add)(zfs_range_tree_t *rt, void *rs, void *arg);
|
||||
void (*rtop_remove)(zfs_range_tree_t *rt, void *rs, void *arg);
|
||||
void (*rtop_vacate)(zfs_range_tree_t *rt, void *arg);
|
||||
};
|
||||
|
||||
static inline uint64_t
|
||||
rs_get_start_raw(const range_seg_t *rs, const range_tree_t *rt)
|
||||
zfs_rs_get_start_raw(const zfs_range_seg_t *rs, const zfs_range_tree_t *rt)
|
||||
{
|
||||
ASSERT3U(rt->rt_type, <=, RANGE_SEG_NUM_TYPES);
|
||||
ASSERT3U(rt->rt_type, <=, ZFS_RANGE_SEG_NUM_TYPES);
|
||||
switch (rt->rt_type) {
|
||||
case RANGE_SEG32:
|
||||
return (((const range_seg32_t *)rs)->rs_start);
|
||||
case RANGE_SEG64:
|
||||
return (((const range_seg64_t *)rs)->rs_start);
|
||||
case RANGE_SEG_GAP:
|
||||
return (((const range_seg_gap_t *)rs)->rs_start);
|
||||
case ZFS_RANGE_SEG32:
|
||||
return (((const zfs_range_seg32_t *)rs)->rs_start);
|
||||
case ZFS_RANGE_SEG64:
|
||||
return (((const zfs_range_seg64_t *)rs)->rs_start);
|
||||
case ZFS_RANGE_SEG_GAP:
|
||||
return (((const zfs_range_seg_gap_t *)rs)->rs_start);
|
||||
default:
|
||||
VERIFY(0);
|
||||
return (0);
|
||||
@ -134,16 +134,16 @@ rs_get_start_raw(const range_seg_t *rs, const range_tree_t *rt)
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
rs_get_end_raw(const range_seg_t *rs, const range_tree_t *rt)
|
||||
zfs_rs_get_end_raw(const zfs_range_seg_t *rs, const zfs_range_tree_t *rt)
|
||||
{
|
||||
ASSERT3U(rt->rt_type, <=, RANGE_SEG_NUM_TYPES);
|
||||
ASSERT3U(rt->rt_type, <=, ZFS_RANGE_SEG_NUM_TYPES);
|
||||
switch (rt->rt_type) {
|
||||
case RANGE_SEG32:
|
||||
return (((const range_seg32_t *)rs)->rs_end);
|
||||
case RANGE_SEG64:
|
||||
return (((const range_seg64_t *)rs)->rs_end);
|
||||
case RANGE_SEG_GAP:
|
||||
return (((const range_seg_gap_t *)rs)->rs_end);
|
||||
case ZFS_RANGE_SEG32:
|
||||
return (((const zfs_range_seg32_t *)rs)->rs_end);
|
||||
case ZFS_RANGE_SEG64:
|
||||
return (((const zfs_range_seg64_t *)rs)->rs_end);
|
||||
case ZFS_RANGE_SEG_GAP:
|
||||
return (((const zfs_range_seg_gap_t *)rs)->rs_end);
|
||||
default:
|
||||
VERIFY(0);
|
||||
return (0);
|
||||
@ -151,20 +151,20 @@ rs_get_end_raw(const range_seg_t *rs, const range_tree_t *rt)
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
rs_get_fill_raw(const range_seg_t *rs, const range_tree_t *rt)
|
||||
zfs_rs_get_fill_raw(const zfs_range_seg_t *rs, const zfs_range_tree_t *rt)
|
||||
{
|
||||
ASSERT3U(rt->rt_type, <=, RANGE_SEG_NUM_TYPES);
|
||||
ASSERT3U(rt->rt_type, <=, ZFS_RANGE_SEG_NUM_TYPES);
|
||||
switch (rt->rt_type) {
|
||||
case RANGE_SEG32: {
|
||||
const range_seg32_t *r32 = (const range_seg32_t *)rs;
|
||||
case ZFS_RANGE_SEG32: {
|
||||
const zfs_range_seg32_t *r32 = (const zfs_range_seg32_t *)rs;
|
||||
return (r32->rs_end - r32->rs_start);
|
||||
}
|
||||
case RANGE_SEG64: {
|
||||
const range_seg64_t *r64 = (const range_seg64_t *)rs;
|
||||
case ZFS_RANGE_SEG64: {
|
||||
const zfs_range_seg64_t *r64 = (const zfs_range_seg64_t *)rs;
|
||||
return (r64->rs_end - r64->rs_start);
|
||||
}
|
||||
case RANGE_SEG_GAP:
|
||||
return (((const range_seg_gap_t *)rs)->rs_fill);
|
||||
case ZFS_RANGE_SEG_GAP:
|
||||
return (((const zfs_range_seg_gap_t *)rs)->rs_fill);
|
||||
default:
|
||||
VERIFY(0);
|
||||
return (0);
|
||||
@ -173,37 +173,37 @@ rs_get_fill_raw(const range_seg_t *rs, const range_tree_t *rt)
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
rs_get_start(const range_seg_t *rs, const range_tree_t *rt)
|
||||
zfs_rs_get_start(const zfs_range_seg_t *rs, const zfs_range_tree_t *rt)
|
||||
{
|
||||
return ((rs_get_start_raw(rs, rt) << rt->rt_shift) + rt->rt_start);
|
||||
return ((zfs_rs_get_start_raw(rs, rt) << rt->rt_shift) + rt->rt_start);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
rs_get_end(const range_seg_t *rs, const range_tree_t *rt)
|
||||
zfs_rs_get_end(const zfs_range_seg_t *rs, const zfs_range_tree_t *rt)
|
||||
{
|
||||
return ((rs_get_end_raw(rs, rt) << rt->rt_shift) + rt->rt_start);
|
||||
return ((zfs_rs_get_end_raw(rs, rt) << rt->rt_shift) + rt->rt_start);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
rs_get_fill(const range_seg_t *rs, const range_tree_t *rt)
|
||||
zfs_rs_get_fill(const zfs_range_seg_t *rs, const zfs_range_tree_t *rt)
|
||||
{
|
||||
return (rs_get_fill_raw(rs, rt) << rt->rt_shift);
|
||||
return (zfs_rs_get_fill_raw(rs, rt) << rt->rt_shift);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rs_set_start_raw(range_seg_t *rs, range_tree_t *rt, uint64_t start)
|
||||
zfs_rs_set_start_raw(zfs_range_seg_t *rs, zfs_range_tree_t *rt, uint64_t start)
|
||||
{
|
||||
ASSERT3U(rt->rt_type, <=, RANGE_SEG_NUM_TYPES);
|
||||
ASSERT3U(rt->rt_type, <=, ZFS_RANGE_SEG_NUM_TYPES);
|
||||
switch (rt->rt_type) {
|
||||
case RANGE_SEG32:
|
||||
case ZFS_RANGE_SEG32:
|
||||
ASSERT3U(start, <=, UINT32_MAX);
|
||||
((range_seg32_t *)rs)->rs_start = (uint32_t)start;
|
||||
((zfs_range_seg32_t *)rs)->rs_start = (uint32_t)start;
|
||||
break;
|
||||
case RANGE_SEG64:
|
||||
((range_seg64_t *)rs)->rs_start = start;
|
||||
case ZFS_RANGE_SEG64:
|
||||
((zfs_range_seg64_t *)rs)->rs_start = start;
|
||||
break;
|
||||
case RANGE_SEG_GAP:
|
||||
((range_seg_gap_t *)rs)->rs_start = start;
|
||||
case ZFS_RANGE_SEG_GAP:
|
||||
((zfs_range_seg_gap_t *)rs)->rs_start = start;
|
||||
break;
|
||||
default:
|
||||
VERIFY(0);
|
||||
@ -211,19 +211,19 @@ rs_set_start_raw(range_seg_t *rs, range_tree_t *rt, uint64_t start)
|
||||
}
|
||||
|
||||
static inline void
|
||||
rs_set_end_raw(range_seg_t *rs, range_tree_t *rt, uint64_t end)
|
||||
zfs_rs_set_end_raw(zfs_range_seg_t *rs, zfs_range_tree_t *rt, uint64_t end)
|
||||
{
|
||||
ASSERT3U(rt->rt_type, <=, RANGE_SEG_NUM_TYPES);
|
||||
ASSERT3U(rt->rt_type, <=, ZFS_RANGE_SEG_NUM_TYPES);
|
||||
switch (rt->rt_type) {
|
||||
case RANGE_SEG32:
|
||||
case ZFS_RANGE_SEG32:
|
||||
ASSERT3U(end, <=, UINT32_MAX);
|
||||
((range_seg32_t *)rs)->rs_end = (uint32_t)end;
|
||||
((zfs_range_seg32_t *)rs)->rs_end = (uint32_t)end;
|
||||
break;
|
||||
case RANGE_SEG64:
|
||||
((range_seg64_t *)rs)->rs_end = end;
|
||||
case ZFS_RANGE_SEG64:
|
||||
((zfs_range_seg64_t *)rs)->rs_end = end;
|
||||
break;
|
||||
case RANGE_SEG_GAP:
|
||||
((range_seg_gap_t *)rs)->rs_end = end;
|
||||
case ZFS_RANGE_SEG_GAP:
|
||||
((zfs_range_seg_gap_t *)rs)->rs_end = end;
|
||||
break;
|
||||
default:
|
||||
VERIFY(0);
|
||||
@ -231,18 +231,19 @@ rs_set_end_raw(range_seg_t *rs, range_tree_t *rt, uint64_t end)
|
||||
}
|
||||
|
||||
static inline void
|
||||
rs_set_fill_raw(range_seg_t *rs, range_tree_t *rt, uint64_t fill)
|
||||
zfs_zfs_rs_set_fill_raw(zfs_range_seg_t *rs, zfs_range_tree_t *rt,
|
||||
uint64_t fill)
|
||||
{
|
||||
ASSERT3U(rt->rt_type, <=, RANGE_SEG_NUM_TYPES);
|
||||
ASSERT3U(rt->rt_type, <=, ZFS_RANGE_SEG_NUM_TYPES);
|
||||
switch (rt->rt_type) {
|
||||
case RANGE_SEG32:
|
||||
case ZFS_RANGE_SEG32:
|
||||
/* fall through */
|
||||
case RANGE_SEG64:
|
||||
ASSERT3U(fill, ==, rs_get_end_raw(rs, rt) - rs_get_start_raw(rs,
|
||||
rt));
|
||||
case ZFS_RANGE_SEG64:
|
||||
ASSERT3U(fill, ==, zfs_rs_get_end_raw(rs, rt) -
|
||||
zfs_rs_get_start_raw(rs, rt));
|
||||
break;
|
||||
case RANGE_SEG_GAP:
|
||||
((range_seg_gap_t *)rs)->rs_fill = fill;
|
||||
case ZFS_RANGE_SEG_GAP:
|
||||
((zfs_range_seg_gap_t *)rs)->rs_fill = fill;
|
||||
break;
|
||||
default:
|
||||
VERIFY(0);
|
||||
@ -250,67 +251,73 @@ rs_set_fill_raw(range_seg_t *rs, range_tree_t *rt, uint64_t fill)
|
||||
}
|
||||
|
||||
static inline void
|
||||
rs_set_start(range_seg_t *rs, range_tree_t *rt, uint64_t start)
|
||||
zfs_rs_set_start(zfs_range_seg_t *rs, zfs_range_tree_t *rt, uint64_t start)
|
||||
{
|
||||
ASSERT3U(start, >=, rt->rt_start);
|
||||
ASSERT(IS_P2ALIGNED(start, 1ULL << rt->rt_shift));
|
||||
rs_set_start_raw(rs, rt, (start - rt->rt_start) >> rt->rt_shift);
|
||||
zfs_rs_set_start_raw(rs, rt, (start - rt->rt_start) >> rt->rt_shift);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rs_set_end(range_seg_t *rs, range_tree_t *rt, uint64_t end)
|
||||
zfs_rs_set_end(zfs_range_seg_t *rs, zfs_range_tree_t *rt, uint64_t end)
|
||||
{
|
||||
ASSERT3U(end, >=, rt->rt_start);
|
||||
ASSERT(IS_P2ALIGNED(end, 1ULL << rt->rt_shift));
|
||||
rs_set_end_raw(rs, rt, (end - rt->rt_start) >> rt->rt_shift);
|
||||
zfs_rs_set_end_raw(rs, rt, (end - rt->rt_start) >> rt->rt_shift);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rs_set_fill(range_seg_t *rs, range_tree_t *rt, uint64_t fill)
|
||||
zfs_rs_set_fill(zfs_range_seg_t *rs, zfs_range_tree_t *rt, uint64_t fill)
|
||||
{
|
||||
ASSERT(IS_P2ALIGNED(fill, 1ULL << rt->rt_shift));
|
||||
rs_set_fill_raw(rs, rt, fill >> rt->rt_shift);
|
||||
zfs_zfs_rs_set_fill_raw(rs, rt, fill >> rt->rt_shift);
|
||||
}
|
||||
|
||||
typedef void range_tree_func_t(void *arg, uint64_t start, uint64_t size);
|
||||
typedef void zfs_range_tree_func_t(void *arg, uint64_t start, uint64_t size);
|
||||
|
||||
range_tree_t *range_tree_create_gap(const range_tree_ops_t *ops,
|
||||
range_seg_type_t type, void *arg, uint64_t start, uint64_t shift,
|
||||
zfs_range_tree_t *zfs_range_tree_create_gap(const zfs_range_tree_ops_t *ops,
|
||||
zfs_range_seg_type_t type, void *arg, uint64_t start, uint64_t shift,
|
||||
uint64_t gap);
|
||||
range_tree_t *range_tree_create(const range_tree_ops_t *ops,
|
||||
range_seg_type_t type, void *arg, uint64_t start, uint64_t shift);
|
||||
void range_tree_destroy(range_tree_t *rt);
|
||||
boolean_t range_tree_contains(range_tree_t *rt, uint64_t start, uint64_t size);
|
||||
range_seg_t *range_tree_find(range_tree_t *rt, uint64_t start, uint64_t size);
|
||||
boolean_t range_tree_find_in(range_tree_t *rt, uint64_t start, uint64_t size,
|
||||
uint64_t *ostart, uint64_t *osize);
|
||||
void range_tree_verify_not_present(range_tree_t *rt,
|
||||
zfs_range_tree_t *zfs_range_tree_create(const zfs_range_tree_ops_t *ops,
|
||||
zfs_range_seg_type_t type, void *arg, uint64_t start, uint64_t shift);
|
||||
void zfs_range_tree_destroy(zfs_range_tree_t *rt);
|
||||
boolean_t zfs_range_tree_contains(zfs_range_tree_t *rt, uint64_t start,
|
||||
uint64_t size);
|
||||
zfs_range_seg_t *zfs_range_tree_find(zfs_range_tree_t *rt, uint64_t start,
|
||||
uint64_t size);
|
||||
boolean_t zfs_range_tree_find_in(zfs_range_tree_t *rt, uint64_t start,
|
||||
uint64_t size, uint64_t *ostart, uint64_t *osize);
|
||||
void zfs_range_tree_verify_not_present(zfs_range_tree_t *rt,
|
||||
uint64_t start, uint64_t size);
|
||||
void range_tree_resize_segment(range_tree_t *rt, range_seg_t *rs,
|
||||
void zfs_range_tree_resize_segment(zfs_range_tree_t *rt, zfs_range_seg_t *rs,
|
||||
uint64_t newstart, uint64_t newsize);
|
||||
uint64_t range_tree_space(range_tree_t *rt);
|
||||
uint64_t range_tree_numsegs(range_tree_t *rt);
|
||||
boolean_t range_tree_is_empty(range_tree_t *rt);
|
||||
void range_tree_swap(range_tree_t **rtsrc, range_tree_t **rtdst);
|
||||
void range_tree_stat_verify(range_tree_t *rt);
|
||||
uint64_t range_tree_min(range_tree_t *rt);
|
||||
uint64_t range_tree_max(range_tree_t *rt);
|
||||
uint64_t range_tree_span(range_tree_t *rt);
|
||||
uint64_t zfs_range_tree_space(zfs_range_tree_t *rt);
|
||||
uint64_t zfs_range_tree_numsegs(zfs_range_tree_t *rt);
|
||||
boolean_t zfs_range_tree_is_empty(zfs_range_tree_t *rt);
|
||||
void zfs_range_tree_swap(zfs_range_tree_t **rtsrc, zfs_range_tree_t **rtdst);
|
||||
void zfs_range_tree_stat_verify(zfs_range_tree_t *rt);
|
||||
uint64_t zfs_range_tree_min(zfs_range_tree_t *rt);
|
||||
uint64_t zfs_range_tree_max(zfs_range_tree_t *rt);
|
||||
uint64_t zfs_range_tree_span(zfs_range_tree_t *rt);
|
||||
|
||||
void range_tree_add(void *arg, uint64_t start, uint64_t size);
|
||||
void range_tree_remove(void *arg, uint64_t start, uint64_t size);
|
||||
void range_tree_remove_fill(range_tree_t *rt, uint64_t start, uint64_t size);
|
||||
void range_tree_adjust_fill(range_tree_t *rt, range_seg_t *rs, int64_t delta);
|
||||
void range_tree_clear(range_tree_t *rt, uint64_t start, uint64_t size);
|
||||
void zfs_range_tree_add(void *arg, uint64_t start, uint64_t size);
|
||||
void zfs_range_tree_remove(void *arg, uint64_t start, uint64_t size);
|
||||
void zfs_range_tree_remove_fill(zfs_range_tree_t *rt, uint64_t start,
|
||||
uint64_t size);
|
||||
void zfs_range_tree_adjust_fill(zfs_range_tree_t *rt, zfs_range_seg_t *rs,
|
||||
int64_t delta);
|
||||
void zfs_range_tree_clear(zfs_range_tree_t *rt, uint64_t start, uint64_t size);
|
||||
|
||||
void range_tree_vacate(range_tree_t *rt, range_tree_func_t *func, void *arg);
|
||||
void range_tree_walk(range_tree_t *rt, range_tree_func_t *func, void *arg);
|
||||
range_seg_t *range_tree_first(range_tree_t *rt);
|
||||
void zfs_range_tree_vacate(zfs_range_tree_t *rt, zfs_range_tree_func_t *func,
|
||||
void *arg);
|
||||
void zfs_range_tree_walk(zfs_range_tree_t *rt, zfs_range_tree_func_t *func,
|
||||
void *arg);
|
||||
zfs_range_seg_t *zfs_range_tree_first(zfs_range_tree_t *rt);
|
||||
|
||||
void range_tree_remove_xor_add_segment(uint64_t start, uint64_t end,
|
||||
range_tree_t *removefrom, range_tree_t *addto);
|
||||
void range_tree_remove_xor_add(range_tree_t *rt, range_tree_t *removefrom,
|
||||
range_tree_t *addto);
|
||||
void zfs_range_tree_remove_xor_add_segment(uint64_t start, uint64_t end,
|
||||
zfs_range_tree_t *removefrom, zfs_range_tree_t *addto);
|
||||
void zfs_range_tree_remove_xor_add(zfs_range_tree_t *rt,
|
||||
zfs_range_tree_t *removefrom, zfs_range_tree_t *addto);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -49,10 +49,10 @@ typedef uint16_t sa_attr_type_t;
|
||||
* Attribute to register support for.
|
||||
*/
|
||||
typedef struct sa_attr_reg {
|
||||
const char *sa_name; /* attribute name */
|
||||
uint16_t sa_length;
|
||||
const char *sa_name; /* attribute name */
|
||||
uint16_t sa_length;
|
||||
sa_bswap_type_t sa_byteswap; /* bswap function enum */
|
||||
sa_attr_type_t sa_attr; /* filled in during registration */
|
||||
sa_attr_type_t sa_attr; /* filled in during registration */
|
||||
} sa_attr_reg_t;
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ typedef struct sa_bulk_attr {
|
||||
uint16_t sa_length;
|
||||
sa_attr_type_t sa_attr;
|
||||
/* the following are private to the sa framework */
|
||||
void *sa_addr;
|
||||
void *sa_addr;
|
||||
uint16_t sa_buftype;
|
||||
uint16_t sa_size;
|
||||
} sa_bulk_attr_t;
|
||||
|
@ -53,6 +53,7 @@ extern "C" {
|
||||
/*
|
||||
* Forward references that lots of things need.
|
||||
*/
|
||||
typedef struct brt_vdev brt_vdev_t;
|
||||
typedef struct spa spa_t;
|
||||
typedef struct vdev vdev_t;
|
||||
typedef struct metaslab metaslab_t;
|
||||
@ -821,6 +822,8 @@ extern void spa_l2cache_drop(spa_t *spa);
|
||||
|
||||
/* scanning */
|
||||
extern int spa_scan(spa_t *spa, pool_scan_func_t func);
|
||||
extern int spa_scan_range(spa_t *spa, pool_scan_func_t func, uint64_t txgstart,
|
||||
uint64_t txgend);
|
||||
extern int spa_scan_stop(spa_t *spa);
|
||||
extern int spa_scrub_pause_resume(spa_t *spa, pool_scrub_cmd_t flag);
|
||||
|
||||
@ -1079,6 +1082,7 @@ extern uint64_t spa_get_deadman_failmode(spa_t *spa);
|
||||
extern void spa_set_deadman_failmode(spa_t *spa, const char *failmode);
|
||||
extern boolean_t spa_suspended(spa_t *spa);
|
||||
extern uint64_t spa_bootfs(spa_t *spa);
|
||||
extern uint64_t spa_get_last_scrubbed_txg(spa_t *spa);
|
||||
extern uint64_t spa_delegation(spa_t *spa);
|
||||
extern objset_t *spa_meta_objset(spa_t *spa);
|
||||
extern space_map_t *spa_syncing_log_sm(spa_t *spa);
|
||||
@ -1209,7 +1213,7 @@ extern void vdev_mirror_stat_fini(void);
|
||||
/* Initialization and termination */
|
||||
extern void spa_init(spa_mode_t mode);
|
||||
extern void spa_fini(void);
|
||||
extern void spa_boot_init(void);
|
||||
extern void spa_boot_init(void *);
|
||||
|
||||
/* properties */
|
||||
extern int spa_prop_set(spa_t *spa, nvlist_t *nvp);
|
||||
|
@ -318,6 +318,7 @@ struct spa {
|
||||
uint64_t spa_scan_pass_scrub_spent_paused; /* total paused */
|
||||
uint64_t spa_scan_pass_exam; /* examined bytes per pass */
|
||||
uint64_t spa_scan_pass_issued; /* issued bytes per pass */
|
||||
uint64_t spa_scrubbed_last_txg; /* last txg scrubbed */
|
||||
|
||||
/* error scrub pause time in milliseconds */
|
||||
uint64_t spa_scan_pass_errorscrub_pause;
|
||||
@ -412,8 +413,12 @@ struct spa {
|
||||
uint64_t spa_dedup_dspace; /* Cache get_dedup_dspace() */
|
||||
uint64_t spa_dedup_checksum; /* default dedup checksum */
|
||||
uint64_t spa_dspace; /* dspace in normal class */
|
||||
uint64_t spa_rdspace; /* raw (non-dedup) --//-- */
|
||||
boolean_t spa_active_ddt_prune; /* ddt prune process active */
|
||||
struct brt *spa_brt; /* in-core BRT */
|
||||
brt_vdev_t **spa_brt_vdevs; /* array of per-vdev BRTs */
|
||||
uint64_t spa_brt_nvdevs; /* number of vdevs in BRT */
|
||||
uint64_t spa_brt_rangesize; /* pool's BRT range size */
|
||||
krwlock_t spa_brt_lock; /* Protects brt_vdevs/nvdevs */
|
||||
kmutex_t spa_vdev_top_lock; /* dueling offline/remove */
|
||||
kmutex_t spa_proc_lock; /* protects spa_proc* */
|
||||
kcondvar_t spa_proc_cv; /* spa_proc_state transitions */
|
||||
|
@ -207,28 +207,28 @@ boolean_t sm_entry_is_double_word(uint64_t e);
|
||||
|
||||
typedef int (*sm_cb_t)(space_map_entry_t *sme, void *arg);
|
||||
|
||||
int space_map_load(space_map_t *sm, range_tree_t *rt, maptype_t maptype);
|
||||
int space_map_load_length(space_map_t *sm, range_tree_t *rt, maptype_t maptype,
|
||||
uint64_t length);
|
||||
int space_map_load(space_map_t *sm, zfs_range_tree_t *rt, maptype_t maptype);
|
||||
int space_map_load_length(space_map_t *sm, zfs_range_tree_t *rt,
|
||||
maptype_t maptype, uint64_t length);
|
||||
int space_map_iterate(space_map_t *sm, uint64_t length,
|
||||
sm_cb_t callback, void *arg);
|
||||
int space_map_incremental_destroy(space_map_t *sm, sm_cb_t callback, void *arg,
|
||||
dmu_tx_t *tx);
|
||||
|
||||
boolean_t space_map_histogram_verify(space_map_t *sm, range_tree_t *rt);
|
||||
boolean_t space_map_histogram_verify(space_map_t *sm, zfs_range_tree_t *rt);
|
||||
void space_map_histogram_clear(space_map_t *sm);
|
||||
void space_map_histogram_add(space_map_t *sm, range_tree_t *rt,
|
||||
void space_map_histogram_add(space_map_t *sm, zfs_range_tree_t *rt,
|
||||
dmu_tx_t *tx);
|
||||
|
||||
uint64_t space_map_object(space_map_t *sm);
|
||||
int64_t space_map_allocated(space_map_t *sm);
|
||||
uint64_t space_map_length(space_map_t *sm);
|
||||
uint64_t space_map_entries(space_map_t *sm, range_tree_t *rt);
|
||||
uint64_t space_map_entries(space_map_t *sm, zfs_range_tree_t *rt);
|
||||
uint64_t space_map_nblocks(space_map_t *sm);
|
||||
|
||||
void space_map_write(space_map_t *sm, range_tree_t *rt, maptype_t maptype,
|
||||
void space_map_write(space_map_t *sm, zfs_range_tree_t *rt, maptype_t maptype,
|
||||
uint64_t vdev_id, dmu_tx_t *tx);
|
||||
uint64_t space_map_estimate_optimal_size(space_map_t *sm, range_tree_t *rt,
|
||||
uint64_t space_map_estimate_optimal_size(space_map_t *sm, zfs_range_tree_t *rt,
|
||||
uint64_t vdev_id);
|
||||
void space_map_truncate(space_map_t *sm, int blocksize, dmu_tx_t *tx);
|
||||
uint64_t space_map_alloc(objset_t *os, int blocksize, dmu_tx_t *tx);
|
||||
|
@ -46,8 +46,8 @@ void space_reftree_create(avl_tree_t *t);
|
||||
void space_reftree_destroy(avl_tree_t *t);
|
||||
void space_reftree_add_seg(avl_tree_t *t, uint64_t start, uint64_t end,
|
||||
int64_t refcnt);
|
||||
void space_reftree_add_map(avl_tree_t *t, range_tree_t *rt, int64_t refcnt);
|
||||
void space_reftree_generate_map(avl_tree_t *t, range_tree_t *rt,
|
||||
void space_reftree_add_map(avl_tree_t *t, zfs_range_tree_t *rt, int64_t refcnt);
|
||||
void space_reftree_generate_map(avl_tree_t *t, zfs_range_tree_t *rt,
|
||||
int64_t minref);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -106,12 +106,12 @@ extern void vdev_expand(vdev_t *vd, uint64_t txg);
|
||||
extern void vdev_split(vdev_t *vd);
|
||||
extern void vdev_deadman(vdev_t *vd, const char *tag);
|
||||
|
||||
typedef void vdev_xlate_func_t(void *arg, range_seg64_t *physical_rs);
|
||||
typedef void vdev_xlate_func_t(void *arg, zfs_range_seg64_t *physical_rs);
|
||||
|
||||
extern boolean_t vdev_xlate_is_empty(range_seg64_t *rs);
|
||||
extern void vdev_xlate(vdev_t *vd, const range_seg64_t *logical_rs,
|
||||
range_seg64_t *physical_rs, range_seg64_t *remain_rs);
|
||||
extern void vdev_xlate_walk(vdev_t *vd, const range_seg64_t *logical_rs,
|
||||
extern boolean_t vdev_xlate_is_empty(zfs_range_seg64_t *rs);
|
||||
extern void vdev_xlate(vdev_t *vd, const zfs_range_seg64_t *logical_rs,
|
||||
zfs_range_seg64_t *physical_rs, zfs_range_seg64_t *remain_rs);
|
||||
extern void vdev_xlate_walk(vdev_t *vd, const zfs_range_seg64_t *logical_rs,
|
||||
vdev_xlate_func_t *func, void *arg);
|
||||
|
||||
extern void vdev_get_stats_ex(vdev_t *vd, vdev_stat_t *vs, vdev_stat_ex_t *vsx);
|
||||
|
@ -91,8 +91,8 @@ typedef void vdev_remap_func_t(vdev_t *vd, uint64_t offset, uint64_t size,
|
||||
* Given a target vdev, translates the logical range "in" to the physical
|
||||
* range "res"
|
||||
*/
|
||||
typedef void vdev_xlation_func_t(vdev_t *cvd, const range_seg64_t *logical,
|
||||
range_seg64_t *physical, range_seg64_t *remain);
|
||||
typedef void vdev_xlation_func_t(vdev_t *cvd, const zfs_range_seg64_t *logical,
|
||||
zfs_range_seg64_t *physical, zfs_range_seg64_t *remain);
|
||||
typedef uint64_t vdev_rebuild_asize_func_t(vdev_t *vd, uint64_t start,
|
||||
uint64_t size, uint64_t max_segment);
|
||||
typedef void vdev_metaslab_init_func_t(vdev_t *vd, uint64_t *startp,
|
||||
@ -299,7 +299,8 @@ struct vdev {
|
||||
kcondvar_t vdev_initialize_cv;
|
||||
uint64_t vdev_initialize_offset[TXG_SIZE];
|
||||
uint64_t vdev_initialize_last_offset;
|
||||
range_tree_t *vdev_initialize_tree; /* valid while initializing */
|
||||
/* valid while initializing */
|
||||
zfs_range_tree_t *vdev_initialize_tree;
|
||||
uint64_t vdev_initialize_bytes_est;
|
||||
uint64_t vdev_initialize_bytes_done;
|
||||
uint64_t vdev_initialize_action_time; /* start and end time */
|
||||
@ -375,7 +376,7 @@ struct vdev {
|
||||
* from multiple zio threads.
|
||||
*/
|
||||
kmutex_t vdev_obsolete_lock;
|
||||
range_tree_t *vdev_obsolete_segments;
|
||||
zfs_range_tree_t *vdev_obsolete_segments;
|
||||
space_map_t *vdev_obsolete_sm;
|
||||
|
||||
/*
|
||||
@ -388,7 +389,7 @@ struct vdev {
|
||||
/*
|
||||
* Leaf vdev state.
|
||||
*/
|
||||
range_tree_t *vdev_dtl[DTL_TYPES]; /* dirty time logs */
|
||||
zfs_range_tree_t *vdev_dtl[DTL_TYPES]; /* dirty time logs */
|
||||
space_map_t *vdev_dtl_sm; /* dirty time log space map */
|
||||
txg_node_t vdev_dtl_node; /* per-txg dirty DTL linkage */
|
||||
uint64_t vdev_dtl_object; /* DTL object */
|
||||
@ -615,8 +616,8 @@ extern vdev_ops_t vdev_indirect_ops;
|
||||
/*
|
||||
* Common size functions
|
||||
*/
|
||||
extern void vdev_default_xlate(vdev_t *vd, const range_seg64_t *logical_rs,
|
||||
range_seg64_t *physical_rs, range_seg64_t *remain_rs);
|
||||
extern void vdev_default_xlate(vdev_t *vd, const zfs_range_seg64_t *logical_rs,
|
||||
zfs_range_seg64_t *physical_rs, zfs_range_seg64_t *remain_rs);
|
||||
extern uint64_t vdev_default_asize(vdev_t *vd, uint64_t psize, uint64_t txg);
|
||||
extern uint64_t vdev_default_min_asize(vdev_t *vd);
|
||||
extern uint64_t vdev_get_min_asize(vdev_t *vd);
|
||||
@ -645,6 +646,10 @@ extern int vdev_obsolete_counts_are_precise(vdev_t *vd, boolean_t *are_precise);
|
||||
int vdev_checkpoint_sm_object(vdev_t *vd, uint64_t *sm_obj);
|
||||
void vdev_metaslab_group_create(vdev_t *vd);
|
||||
uint64_t vdev_best_ashift(uint64_t logical, uint64_t a, uint64_t b);
|
||||
#if defined(__linux__)
|
||||
int param_get_raidz_impl(char *buf, zfs_kernel_param_t *kp);
|
||||
#endif
|
||||
int param_set_raidz_impl(ZFS_MODULE_PARAM_ARGS);
|
||||
|
||||
/*
|
||||
* Vdev ashift optimization tunables
|
||||
|
@ -57,7 +57,7 @@ void vdev_raidz_reconstruct(struct raidz_map *, const int *, int);
|
||||
void vdev_raidz_child_done(zio_t *);
|
||||
void vdev_raidz_io_done(zio_t *);
|
||||
void vdev_raidz_checksum_error(zio_t *, struct raidz_col *, abd_t *);
|
||||
struct raidz_row *vdev_raidz_row_alloc(int);
|
||||
struct raidz_row *vdev_raidz_row_alloc(int, zio_t *);
|
||||
void vdev_raidz_reflow_copy_scratch(spa_t *);
|
||||
void raidz_dtl_reassessed(vdev_t *);
|
||||
|
||||
@ -66,6 +66,8 @@ extern const zio_vsd_ops_t vdev_raidz_vsd_ops;
|
||||
/*
|
||||
* vdev_raidz_math interface
|
||||
*/
|
||||
/* Required, but not used, by ZFS_MODULE_PARAM_CALL */
|
||||
extern uint32_t zfs_vdev_raidz_impl;
|
||||
void vdev_raidz_math_init(void);
|
||||
void vdev_raidz_math_fini(void);
|
||||
const struct raidz_impl_ops *vdev_raidz_math_get_ops(void);
|
||||
@ -73,6 +75,7 @@ int vdev_raidz_math_generate(struct raidz_map *, struct raidz_row *);
|
||||
int vdev_raidz_math_reconstruct(struct raidz_map *, struct raidz_row *,
|
||||
const int *, const int *, const int);
|
||||
int vdev_raidz_impl_set(const char *);
|
||||
int vdev_raidz_impl_get(char *buffer, size_t size);
|
||||
|
||||
typedef struct vdev_raidz_expand {
|
||||
uint64_t vre_vdev_id;
|
||||
|
@ -65,7 +65,8 @@ typedef struct vdev_rebuild_phys {
|
||||
typedef struct vdev_rebuild {
|
||||
vdev_t *vr_top_vdev; /* top-level vdev to rebuild */
|
||||
metaslab_t *vr_scan_msp; /* scanning disabled metaslab */
|
||||
range_tree_t *vr_scan_tree; /* scan ranges (in metaslab) */
|
||||
/* scan ranges (in metaslab) */
|
||||
zfs_range_tree_t *vr_scan_tree;
|
||||
kmutex_t vr_io_lock; /* inflight IO lock */
|
||||
kcondvar_t vr_io_cv; /* inflight IO cv */
|
||||
|
||||
|
@ -35,7 +35,7 @@ typedef struct spa_vdev_removal {
|
||||
/* Thread performing a vdev removal. */
|
||||
kthread_t *svr_thread;
|
||||
/* Segments left to copy from the current metaslab. */
|
||||
range_tree_t *svr_allocd_segs;
|
||||
zfs_range_tree_t *svr_allocd_segs;
|
||||
kmutex_t svr_lock;
|
||||
kcondvar_t svr_cv;
|
||||
boolean_t svr_thread_exit;
|
||||
@ -49,7 +49,7 @@ typedef struct spa_vdev_removal {
|
||||
* Ranges that were freed while a mapping was in flight. This is
|
||||
* a subset of the ranges covered by vdev_im_new_segments.
|
||||
*/
|
||||
range_tree_t *svr_frees[TXG_SIZE];
|
||||
zfs_range_tree_t *svr_frees[TXG_SIZE];
|
||||
|
||||
/*
|
||||
* Number of bytes which we have finished our work for
|
||||
|
@ -223,11 +223,15 @@ int zap_lookup_norm(objset_t *ds, uint64_t zapobj, const char *name,
|
||||
boolean_t *normalization_conflictp);
|
||||
int zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
|
||||
int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf);
|
||||
int zap_lookup_uint64_by_dnode(dnode_t *dn, const uint64_t *key,
|
||||
int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf);
|
||||
int zap_contains(objset_t *ds, uint64_t zapobj, const char *name);
|
||||
int zap_prefetch(objset_t *os, uint64_t zapobj, const char *name);
|
||||
int zap_prefetch_object(objset_t *os, uint64_t zapobj);
|
||||
int zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
|
||||
int key_numints);
|
||||
int zap_prefetch_uint64_by_dnode(dnode_t *dn, const uint64_t *key,
|
||||
int key_numints);
|
||||
|
||||
int zap_lookup_by_dnode(dnode_t *dn, const char *name,
|
||||
uint64_t integer_size, uint64_t num_integers, void *buf);
|
||||
@ -236,9 +240,6 @@ int zap_lookup_norm_by_dnode(dnode_t *dn, const char *name,
|
||||
matchtype_t mt, char *realname, int rn_len,
|
||||
boolean_t *ncp);
|
||||
|
||||
int zap_count_write_by_dnode(dnode_t *dn, const char *name,
|
||||
int add, zfs_refcount_t *towrite, zfs_refcount_t *tooverwrite);
|
||||
|
||||
/*
|
||||
* Create an attribute with the given name and value.
|
||||
*
|
||||
|
@ -23,7 +23,7 @@
|
||||
* Copyright (c) 2012, 2024 by Delphix. All rights reserved.
|
||||
* Copyright 2016 RackTop Systems.
|
||||
* Copyright (c) 2017, Intel Corporation.
|
||||
* Copyright (c) 2024, Klara, Inc.
|
||||
* Copyright (c) 2024-2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ZFS_IOCTL_H
|
||||
@ -421,6 +421,8 @@ typedef struct zinject_record {
|
||||
uint64_t zi_nlanes;
|
||||
uint32_t zi_cmd;
|
||||
uint32_t zi_dvas;
|
||||
uint64_t zi_match_count; /* count of times matched */
|
||||
uint64_t zi_inject_count; /* count of times injected */
|
||||
} zinject_record_t;
|
||||
|
||||
#define ZINJECT_NULL 0x1
|
||||
@ -454,6 +456,25 @@ typedef enum zinject_type {
|
||||
ZINJECT_DELAY_EXPORT,
|
||||
} zinject_type_t;
|
||||
|
||||
typedef enum zinject_iotype {
|
||||
/*
|
||||
* Compatibility: zi_iotype used to be set to ZIO_TYPE_, so make sure
|
||||
* the corresponding ZINJECT_IOTYPE_ matches. Note that existing here
|
||||
* does not mean that injections are possible for all these types.
|
||||
*/
|
||||
ZINJECT_IOTYPE_NULL = ZIO_TYPE_NULL,
|
||||
ZINJECT_IOTYPE_READ = ZIO_TYPE_READ,
|
||||
ZINJECT_IOTYPE_WRITE = ZIO_TYPE_WRITE,
|
||||
ZINJECT_IOTYPE_FREE = ZIO_TYPE_FREE,
|
||||
ZINJECT_IOTYPE_CLAIM = ZIO_TYPE_CLAIM,
|
||||
ZINJECT_IOTYPE_FLUSH = ZIO_TYPE_FLUSH,
|
||||
ZINJECT_IOTYPE_TRIM = ZIO_TYPE_TRIM,
|
||||
ZINJECT_IOTYPE_ALL = ZIO_TYPES,
|
||||
/* Room for future expansion for ZIO_TYPE_* */
|
||||
ZINJECT_IOTYPE_PROBE = 16,
|
||||
ZINJECT_IOTYPES,
|
||||
} zinject_iotype_t;
|
||||
|
||||
typedef struct zfs_share {
|
||||
uint64_t z_exportdata;
|
||||
uint64_t z_sharedata;
|
||||
|
@ -35,7 +35,6 @@
|
||||
#ifndef _ZIO_H
|
||||
#define _ZIO_H
|
||||
|
||||
#include <sys/zio_priority.h>
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/spa.h>
|
||||
#include <sys/txg.h>
|
||||
@ -208,25 +207,25 @@ typedef uint64_t zio_flag_t;
|
||||
#define ZIO_FLAG_PROBE (1ULL << 16)
|
||||
#define ZIO_FLAG_TRYHARD (1ULL << 17)
|
||||
#define ZIO_FLAG_OPTIONAL (1ULL << 18)
|
||||
|
||||
#define ZIO_FLAG_DIO_READ (1ULL << 19)
|
||||
#define ZIO_FLAG_VDEV_INHERIT (ZIO_FLAG_DONT_QUEUE - 1)
|
||||
|
||||
/*
|
||||
* Flags not inherited by any children.
|
||||
*/
|
||||
#define ZIO_FLAG_DONT_QUEUE (1ULL << 19) /* must be first for INHERIT */
|
||||
#define ZIO_FLAG_DONT_PROPAGATE (1ULL << 20)
|
||||
#define ZIO_FLAG_IO_BYPASS (1ULL << 21)
|
||||
#define ZIO_FLAG_IO_REWRITE (1ULL << 22)
|
||||
#define ZIO_FLAG_RAW_COMPRESS (1ULL << 23)
|
||||
#define ZIO_FLAG_RAW_ENCRYPT (1ULL << 24)
|
||||
#define ZIO_FLAG_GANG_CHILD (1ULL << 25)
|
||||
#define ZIO_FLAG_DDT_CHILD (1ULL << 26)
|
||||
#define ZIO_FLAG_GODFATHER (1ULL << 27)
|
||||
#define ZIO_FLAG_NOPWRITE (1ULL << 28)
|
||||
#define ZIO_FLAG_REEXECUTED (1ULL << 29)
|
||||
#define ZIO_FLAG_DELEGATED (1ULL << 30)
|
||||
#define ZIO_FLAG_DIO_CHKSUM_ERR (1ULL << 31)
|
||||
#define ZIO_FLAG_DONT_QUEUE (1ULL << 20) /* must be first for INHERIT */
|
||||
#define ZIO_FLAG_DONT_PROPAGATE (1ULL << 21)
|
||||
#define ZIO_FLAG_IO_BYPASS (1ULL << 22)
|
||||
#define ZIO_FLAG_IO_REWRITE (1ULL << 23)
|
||||
#define ZIO_FLAG_RAW_COMPRESS (1ULL << 24)
|
||||
#define ZIO_FLAG_RAW_ENCRYPT (1ULL << 25)
|
||||
#define ZIO_FLAG_GANG_CHILD (1ULL << 26)
|
||||
#define ZIO_FLAG_DDT_CHILD (1ULL << 27)
|
||||
#define ZIO_FLAG_GODFATHER (1ULL << 28)
|
||||
#define ZIO_FLAG_NOPWRITE (1ULL << 29)
|
||||
#define ZIO_FLAG_REEXECUTED (1ULL << 30)
|
||||
#define ZIO_FLAG_DELEGATED (1ULL << 31)
|
||||
#define ZIO_FLAG_DIO_CHKSUM_ERR (1ULL << 32)
|
||||
|
||||
#define ZIO_ALLOCATOR_NONE (-1)
|
||||
#define ZIO_HAS_ALLOCATOR(zio) ((zio)->io_allocator != ZIO_ALLOCATOR_NONE)
|
||||
@ -546,6 +545,7 @@ enum blk_verify_flag {
|
||||
enum blk_config_flag {
|
||||
BLK_CONFIG_HELD, // SCL_VDEV held for writer
|
||||
BLK_CONFIG_NEEDED, // SCL_VDEV should be obtained for reader
|
||||
BLK_CONFIG_NEEDED_TRY, // Try with SCL_VDEV for reader
|
||||
BLK_CONFIG_SKIP, // skip checks which require SCL_VDEV
|
||||
};
|
||||
|
||||
@ -647,6 +647,7 @@ extern void zio_vdev_io_redone(zio_t *zio);
|
||||
extern void zio_change_priority(zio_t *pio, zio_priority_t priority);
|
||||
|
||||
extern void zio_checksum_verified(zio_t *zio);
|
||||
extern void zio_dio_chksum_verify_error_report(zio_t *zio);
|
||||
extern int zio_worst_error(int e1, int e2);
|
||||
|
||||
extern enum zio_checksum zio_checksum_select(enum zio_checksum child,
|
||||
@ -662,7 +663,7 @@ extern void zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t);
|
||||
extern int zio_resume(spa_t *spa);
|
||||
extern void zio_resume_wait(spa_t *spa);
|
||||
|
||||
extern boolean_t zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
|
||||
extern int zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
|
||||
enum blk_config_flag blk_config, enum blk_verify_flag blk_verify);
|
||||
|
||||
/*
|
||||
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* This file and its contents are supplied under the terms of the
|
||||
* Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
* You may only use this file in accordance with the terms of version
|
||||
* 1.0 of the CDDL.
|
||||
*
|
||||
* A full copy of the text of the CDDL should have accompanied this
|
||||
* source. A copy of the CDDL is also available via the Internet at
|
||||
* http://www.illumos.org/license/CDDL.
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
|
||||
*/
|
||||
#ifndef _ZIO_PRIORITY_H
|
||||
#define _ZIO_PRIORITY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NOTE: PLEASE UPDATE THE ENUM STRINGS IN zfs_valstr.c IF YOU ADD ANOTHER
|
||||
* VALUE.
|
||||
*/
|
||||
typedef enum zio_priority {
|
||||
ZIO_PRIORITY_SYNC_READ,
|
||||
ZIO_PRIORITY_SYNC_WRITE, /* ZIL */
|
||||
ZIO_PRIORITY_ASYNC_READ, /* prefetch */
|
||||
ZIO_PRIORITY_ASYNC_WRITE, /* spa_sync() */
|
||||
ZIO_PRIORITY_SCRUB, /* asynchronous scrub/resilver reads */
|
||||
ZIO_PRIORITY_REMOVAL, /* reads/writes for vdev removal */
|
||||
ZIO_PRIORITY_INITIALIZING, /* initializing I/O */
|
||||
ZIO_PRIORITY_TRIM, /* trim I/O (discard) */
|
||||
ZIO_PRIORITY_REBUILD, /* reads/writes for vdev rebuild */
|
||||
ZIO_PRIORITY_NUM_QUEUEABLE,
|
||||
ZIO_PRIORITY_NOW, /* non-queued i/os (e.g. free) */
|
||||
} zio_priority_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ZIO_PRIORITY_H */
|
@ -88,6 +88,11 @@ int zvol_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf,
|
||||
int zvol_init_impl(void);
|
||||
void zvol_fini_impl(void);
|
||||
void zvol_wait_close(zvol_state_t *zv);
|
||||
int zvol_clone_range(zvol_state_handle_t *, uint64_t,
|
||||
zvol_state_handle_t *, uint64_t, uint64_t);
|
||||
void zvol_log_clone_range(zilog_t *zilog, dmu_tx_t *tx, int txtype,
|
||||
uint64_t off, uint64_t len, uint64_t blksz, const blkptr_t *bps,
|
||||
size_t nbps);
|
||||
|
||||
/*
|
||||
* platform dependent functions exported to platform independent code
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user