Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
fc44c73
build: add SPDX license tags to build system files
robn Dec 20, 2025
4234660
spdxcheck: enforce SPDX license tags on build system files
robn Dec 20, 2025
faddb7f
Linux 7.0: explicitly set setlease handler to kernel implementation
robn Feb 22, 2026
ca18f1a
build: get objtool from $kernelbuild
teapot9 Feb 23, 2026
786b7c2
Linux 7.0: blk_queue_nonrot() renamed to blk_queue_rot()
robn Feb 5, 2026
ffa0a5a
Linux 7.0: posix_acl_to_xattr() now allocates memory
robn Jan 27, 2026
20a30ac
Linux 7.0: add shims for the fs_context-based mount API
robn Jan 26, 2026
04daeff
CI: Remove deprecated Fedora 41
tonyhutter Feb 25, 2026
1ace2bf
zpl_super: prefer "new" mount API when available
robn Feb 25, 2026
02ed091
Fix check for .cfi_negate_ra_state on aarch64
arter97 Mar 6, 2026
a94b137
FreeBSD: Improve dmesg kernel message prefix
concussious Mar 9, 2026
cb2e2f9
libzfs: use mount_setattr for selective remount including legacy mounts
ixhamza Mar 9, 2026
5445c37
config: remove minimum kernel version check
robn Mar 8, 2026
12cd6ff
README: describe specific kernels/distros we target
robn Mar 8, 2026
3396114
Fix deadlock on dmu_tx_assign() from vdev_rebuild()
andriytk Feb 26, 2026
938c8c9
draid: fix data corruption after disk clear
andriytk Mar 11, 2026
97949da
config: fix STATX_MNT_ID detection
robn Mar 12, 2026
7894a5e
ZTS: redundancy_draid_spare{1,3} exceptions
behlendorf Mar 13, 2026
1bc9225
ZTS: Add back redundancy_draid_spare3 exception
behlendorf Mar 16, 2026
59185c5
Linux 7.0: also set setlease handler on directories (#18331)
robn Mar 17, 2026
bec56a4
config: refuse to build without fs_context
robn Mar 15, 2026
0edbfbf
linux/super: remove support for old mount API
robn Mar 15, 2026
7c3f75a
linux/super: flatten mount/remount into get_tree/reconfigure
robn Mar 15, 2026
04692b2
linux/super: flatten zpl_mount_impl into zpl_get_tree
robn Mar 16, 2026
20b8936
linux/super: flatten zpl_fill_super into zpl_get_tree
robn Mar 16, 2026
2c861eb
CI: Support repository variable override for ZTS OS selection
ixhamza Mar 19, 2026
0d42a6c
CI: Add ARM builder
tonyhutter Mar 19, 2026
6756fd4
Linux 7.0: autoconf: Remove copy-from-user-inatomic API checks (#1834…
john-cabaj Mar 23, 2026
7405240
ci: update FreeBSD CI images from 14.3 to 14.4
chrislongros Mar 23, 2026
3ca81f6
Linux 7.0: ensure LSMs get to process mount options
robn Mar 30, 2026
9b8ccbd
draid: fix import failure after disks replacements
andriytk Mar 31, 2026
7843c42
linux/vfsops: add vfs_t allocator, make public
robn Mar 26, 2026
36ae5a6
linux/vfsops: remove old options parser
robn Mar 21, 2026
f5a60b6
linux/super: remove zpl_parse_monolithic
robn Mar 26, 2026
43eed9e
linux/super: match vfs_t lifetime to fs_context
robn Mar 26, 2026
0b223ef
linux/super: implement new mount params parser
robn Mar 20, 2026
a8942fd
linux/super: work around kernels that enforce "forbidden" mount options
robn Mar 31, 2026
fc285ca
linux/vfsops: remove zfs_mnt_t, pass directly
robn Mar 26, 2026
26e9a69
CI: Free 35GB of unused files on the runner
tonyhutter Apr 4, 2026
63b8da8
Linux: Refactor zpl_fadvise()
amotin Apr 6, 2026
e9a8c6e
draid: allow seq resilver reads from degraded vdevs
behlendorf Apr 7, 2026
f4e5eb7
CI: set /etc/hostid in zloop runner
behlendorf Apr 8, 2026
eec8b9b
CI: Disable ZIP file artifacts, update versions
tonyhutter Apr 14, 2026
da44040
draid: fix cksum errors after rebuild with degraded disks
andriytk Apr 15, 2026
a6b3ff9
deb.am: propagate build errors in native-deb targets
chrislongros Apr 15, 2026
eb3331a
Linux 7.0 compat: META
behlendorf Apr 16, 2026
6cb1e85
CI: Do not set scheduler in qemu-1-setup.sh
tonyhutter Apr 17, 2026
f99954c
CI: tolerate missing artifacts
behlendorf Apr 18, 2026
afc6e08
CI: Add more debugging to qemu-1-setup.sh
tonyhutter Apr 20, 2026
aba3ed3
fix memleak in spa_errlog.c
alek-p Apr 6, 2026
b40cd91
Fix s_active leak in zfsvfs_hold() when z_unmounted is true
mischivus Mar 12, 2026
5d56935
Fix options memory leak in zfsctl_snapshot_mount
ixhamza Apr 8, 2026
b2602a4
Fix snapshot automount deadlock during concurrent zfs recv
ixhamza Apr 8, 2026
e752459
Fix read corruption after block clone after truncate
nbdd0121 Apr 15, 2026
9edfdd6
[zfs-2.4.2] Whitelist some Makefile.am files from SPDX
tonyhutter Apr 23, 2026
b06caae
range_tree: use zfs_panic_recover() for partial-overlap remove
clefru Feb 25, 2026
7590972
Prevent range tree corruption race by updating dnode_sync()
alek-p Mar 24, 2026
b8addf9
dmu_direct: avoid UAF in dmu_write_direct_done()
Gality369 Apr 20, 2026
aa62ae8
Fix 'kernel BUG at mm/usercopy.c'
tonyhutter Apr 23, 2026
19354ab
CI: curl fallback, print killed tests, FreeBSD URL
tonyhutter Apr 25, 2026
887bfc1
build: use pax tar format for make dist
chrislongros Apr 25, 2026
602ed78
Tag zfs-2.4.2
tonyhutter Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/checkstyle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ jobs:
- name: Prepare artifacts
if: failure() && steps.CheckABI.outcome == 'failure'
run: |
find -name *.abi | tar -cf abi_files.tar -T -
- uses: actions/upload-artifact@v4
find -name *.abi | tar -cjf abi_files.tar.bz2 -T -
- uses: actions/upload-artifact@v7
if: failure() && steps.CheckABI.outcome == 'failure'
with:
name: New ABI files (use only if you're sure about interface changes)
path: abi_files.tar
path: abi_files.tar.bz2
archive: false
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV

- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
Expand Down
33 changes: 21 additions & 12 deletions .github/workflows/scripts/generate-ci-type.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
"""
Determine the CI type based on the change list and commit message.

Prints "quick" if (explicity required by user):
Output format: "<type> <source>" where source is "manual" (from
ZFS-CI-Type commit tag) or "auto" (from file change heuristics).

Prints "quick manual" if:
- the *last* commit message contains 'ZFS-CI-Type: quick'
or if (heuristics):
or "quick auto" if (heuristics):
- the files changed are not in the list of specified directories, and
- all commit messages do not contain 'ZFS-CI-Type: (full|linux|freebsd)'

Otherwise prints "full".
Otherwise prints "full auto" (or "<type> manual" if explicitly requested).
"""

import sys
Expand Down Expand Up @@ -58,9 +61,10 @@

head, base = sys.argv[1:3]

def output_type(type, reason):
print(f'{prog}: will run {type} CI: {reason}', file=sys.stderr)
print(type)
def output_type(type, source, reason):
print(f'{prog}: will run {type} CI ({source}): {reason}',
file=sys.stderr)
print(f'{type} {source}')
sys.exit(0)

# check last (HEAD) commit message
Expand All @@ -70,7 +74,8 @@ def output_type(type, reason):

for line in last_commit_message_raw.stdout.decode().splitlines():
if line.strip().lower() == 'zfs-ci-type: quick':
output_type('quick', f'requested by HEAD commit {head}')
output_type('quick', 'manual',
f'requested by HEAD commit {head}')

# check all commit messages
all_commit_message_raw = subprocess.run([
Expand All @@ -84,11 +89,14 @@ def output_type(type, reason):
if line.startswith('ZFS-CI-Commit:'):
commit_ref = line.lstrip('ZFS-CI-Commit:').rstrip()
if line.strip().lower() == 'zfs-ci-type: freebsd':
output_type('freebsd', f'requested by commit {commit_ref}')
output_type('freebsd', 'manual',
f'requested by commit {commit_ref}')
if line.strip().lower() == 'zfs-ci-type: linux':
output_type('linux', f'requested by commit {commit_ref}')
output_type('linux', 'manual',
f'requested by commit {commit_ref}')
if line.strip().lower() == 'zfs-ci-type: full':
output_type('full', f'requested by commit {commit_ref}')
output_type('full', 'manual',
f'requested by commit {commit_ref}')

# check changed files
changed_files_raw = subprocess.run([
Expand All @@ -104,9 +112,10 @@ def output_type(type, reason):
for r in FULL_RUN_REGEX:
if r.match(f):
output_type(
'full',
'full', 'auto',
f'changed file "{f}" matches pattern "{r.pattern}"'
)

# catch-all
output_type('quick', 'no changed file matches full CI patterns')
output_type('quick', 'auto',
'no changed file matches full CI patterns')
38 changes: 38 additions & 0 deletions .github/workflows/scripts/merge_summary.awk
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ BEGIN {
pass=0
fail=0
skip=0
killed=0
state=""
cl=0
el=0
Expand Down Expand Up @@ -49,6 +50,37 @@ BEGIN {
/PASS/{ if (state=="pass_count") {pass += $2}}
/FAIL/{ if (state=="pass_count") {fail += $2}}
/SKIP/{ if (state=="pass_count") {skip += $2}}

# If the test was killed, you'll get a line like:
#
# [2026-04-22T03:34:17.694616] Test (Linux): /usr/share/zfs/zfs-tests/tests/functional/io/setup (run as root) [10:00] [KILLED]
#
# Parse out the test name minus the /usr/share/zfs/zfs-tests/tests/functional/'
# part, and include the optional "(Linux): " line, as you can have the killed
# tests in two categories, like:
#
# KILLED (Linux): io/setup
# KILLED io/setup
#
/KILLED/{
extra=""
for(i=1; i<=NF; i++) {
# Look for optional "(Linux):" field
if ($i ~ "\\("){
extra=$i" "}

# Look for a field with a '/' in it. It is the test name.
if($i ~ "/") {
testname=$i
# Remove /usr/share/zfs/zfs-test/test/functional string
sub(/\/usr\/share\/zfs\/zfs-tests\/tests\/functional\//,"",testname)
testname=extra""testname
killed_tests[killed] = testname
killed++
break
}
}
}
/Running Time/{
state="";
running[i]=$3;
Expand Down Expand Up @@ -106,4 +138,10 @@ END {
asort(unexpected_lines, sorted)
for (j in sorted)
print sorted[j]

# We don't want to sort killed tests, as the first test that was killed
# most likely caused the others to be killed.
print "\n\nTests that were killed:"
for (j in killed_tests)
print " KILLED "killed_tests[j]
}
43 changes: 33 additions & 10 deletions .github/workflows/scripts/qemu-1-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@

set -eu

# The default runner has a bunch of development tools and other things
# that we do not need. Remove them here to free up a total of 35GB.
#
# First remove packages - this frees up ~10GB
echo "Disk space before purge:"
df -h /
sudo docker image prune --all --force
sudo docker builder prune -a
unneeded="microsoft-edge-stable|azure-cli|google-cloud|google-chrome-stable|"\
"temurin|llvm|firefox|mysql-server|snapd|android|dotnet|haskell|ghcup|"\
"powershell|julia|swift|miniconda|chromium"
sudo apt-get -y remove $(dpkg-query -f '${binary:Package}\n' -W | grep -E "'$unneeded'")
sudo apt-get -y autoremove

# Next, remove unneeded files in /usr. This frees up an additional 25GB.
sudo rm -fr /usr/local/lib/android /usr/share/dotnet /usr/local/.ghcup \
/usr/share/swift /usr/local/share/powershell /usr/local/julia* \
/usr/share/miniconda /usr/local/share/chromium
echo "Disk space after:"
df -h /

# The default 'azure.archive.ubuntu.com' mirrors can be really slow.
# Prioritize the official Ubuntu mirrors.
#
Expand Down Expand Up @@ -42,7 +63,7 @@ sudo swapoff -a
# configurations. On one config you get two 75GB block devices, and on the
# other you get a single 150GB block device. Here's what both look like:
#
# --- Two 75GB block devices ---
# --- One 150GB block device ---
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sda 8:0 0 150G 0 disk
# ├─sda1 8:1 0 149G 0 part /
Expand All @@ -56,7 +77,7 @@ sudo swapoff -a
# lrwxrwxrwx 1 root root 11 Jan 29 18:07 azure_root-part15 -> ../../sda15
# lrwxrwxrwx 1 root root 11 Jan 29 18:07 azure_root-part16 -> ../../sda16
#
# --- One 150GB block device ---
# --- Two 75GB block devices ---
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sda 8:0 0 75G 0 disk
# ├─sda1 8:1 0 74G 0 part /
Expand Down Expand Up @@ -118,18 +139,20 @@ fi
sudo mkswap $SWAP
sudo swapon $SWAP

echo "Block devices:"
lsblk

# adjust zfs module parameter and create pool
exec 1>/dev/null
ARC_MIN=$((1024*1024*256))
ARC_MAX=$((1024*1024*512))
echo $ARC_MIN | sudo tee /sys/module/zfs/parameters/zfs_arc_min
echo $ARC_MAX | sudo tee /sys/module/zfs/parameters/zfs_arc_max
echo 1 | sudo tee /sys/module/zfs/parameters/zvol_use_blk_mq
echo $ARC_MIN | sudo tee /sys/module/zfs/parameters/zfs_arc_min >/dev/null
echo $ARC_MAX | sudo tee /sys/module/zfs/parameters/zfs_arc_max >/dev/null
echo 1 | sudo tee /sys/module/zfs/parameters/zvol_use_blk_mq >/dev/null
sudo zpool create -f -o ashift=12 zpool $DISKS -O relatime=off \
-O atime=off -O xattr=sa -O compression=lz4 -O sync=disabled \
-O redundant_metadata=none -O mountpoint=/mnt/tests
echo "Status:"
zpool status

# no need for some scheduler
for i in /sys/block/s*/queue/scheduler; do
echo "none" | sudo tee $i
done
echo "Last dmesg:"
sudo dmesg | tail -n 10
65 changes: 46 additions & 19 deletions .github/workflows/scripts/qemu-2-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,6 @@ case "$OS" in
OPTS[0]="--boot"
OPTS[1]="uefi=on"
;;
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"
;;
fedora42)
OSNAME="Fedora 42"
OSv="fedora-unknown"
Expand All @@ -101,8 +96,8 @@ case "$OS" in
KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
NIC="rtl8139"
;;
freebsd14-3r)
FreeBSD="14.3-RELEASE"
freebsd14-4r)
FreeBSD="14.4-RELEASE"
OSNAME="FreeBSD $FreeBSD"
OSv="freebsd14.0"
URLxz="$FREEBSD_REL/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI.raw.xz"
Expand All @@ -116,8 +111,8 @@ case "$OS" in
KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz"
NIC="rtl8139"
;;
freebsd14-3s)
FreeBSD="14.3-STABLE"
freebsd14-4s)
FreeBSD="14.4-STABLE"
OSNAME="FreeBSD $FreeBSD"
OSv="freebsd14.0"
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
Expand Down Expand Up @@ -193,17 +188,49 @@ DISK="/dev/zvol/zpool/openzfs"
sudo zfs create -ps -b 64k -V 80g zpool/openzfs
while true; do test -b $DISK && break; sleep 1; done

# we are downloading via axel, curl and wget are mostly slower and
# require more return value checking
# We first try to download with 'axel', which is faster than curl, but fallback
# to curl if that doesn't work. It is hoped that the curl fallback will get
# around the occasional "ERROR 502: Bad Gateway" errors.
IMG="/mnt/tests/cloud-image"
if [ ! -z "$URLxz" ]; then
echo "Loading $URLxz ..."
time axel -q -o "$IMG" "$URLxz"
echo "Loading $KSRC ..."
time axel -q -o ~/src.txz $KSRC
else
echo "Loading $URL ..."
time axel -q -o "$IMG" "$URL"
for cmd in 'axel -q -o' 'curl --fail -LSs -o' ; do
if [ ! -z "$URLxz" ]; then
echo "Loading $URLxz with $cmd..."
time eval "$cmd $IMG $URLxz" || true

if [ ! -s ~/src.txz ] ; then
echo "Loading $KSRC with $cmd..."
time eval "$cmd ~/src.txz $KSRC" || true
fi
else
echo "Loading $URL with $cmd..."
time eval "$cmd $IMG $URL" || true
fi

if [ -s "$IMG" ] ; then
# Successful download
break
fi
done

# SPECIAL CASE
# FreeBSD sometimes has broken links in their "current/" URL. Go back up a
# level and look for other images that might work. For example:
#
# https://download.freebsd.org/snapshots/CI-IMAGES/16.0-CURRENT/amd64/:
#
# 20251110/
# 20251209/
# 20260420/
# current/
#
# In this case let's say the raw.xz link in current/ is bad, so look though the
# other snapshot links for the newest existing raw.xz file.
if [ ! -z "$URLxz" ] && [ ! -s "$IMG" ] ; then
URLxz=$(wget --accept "*.raw.xz" --spider -np --recursive --no-verbose \
$(dirname $(dirname $URLxz)) 2>&1 | awk '/200 OK/{print $(NF-2)}' | \
sort -n | tail -n 1)
echo "Couldn't download FreeBSD raw.xz. Trying fallback snapshot $URLxz"
curl --fail -LSs -o $IMG $URLxz
fi

echo "Importing VM image to zvol..."
Expand Down
22 changes: 19 additions & 3 deletions .github/workflows/scripts/qemu-3-deps-vm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
######################################################################
# 3) install dependencies for compiling and loading
#
# $1: OS name (like 'fedora41')
# $2: (optional) Experimental Fedora kernel version, like "6.14" to
# qemu-3-deps-vm.sh [--poweroff] OS_NAME [FEDORA_VERSION]
#
# --poweroff: Power off the VM after installing dependencies
# OS_NAME: OS name (like 'fedora41')
# FEDORA_VERSION: (optional) Experimental Fedora kernel version, like "6.14" to
# install instead of Fedora defaults.
######################################################################

Expand Down Expand Up @@ -153,6 +156,12 @@ function install_fedora_experimental_kernel {
sudo dnf -y copr disable @kernel-vanilla/mainline
}

POWEROFF=""
if [ "$1" == "--poweroff" ] ; then
POWEROFF=1
shift
fi

# Install dependencies
case "$1" in
almalinux8)
Expand Down Expand Up @@ -212,6 +221,11 @@ case "$1" in
sudo apt-get install -yq linux-tools-common libtirpc-dev \
linux-modules-extra-$(uname -r)
sudo apt-get install -yq dh-sequence-dkms

# Need 'build-essential' explicitly for ARM builder
# https://github.com/actions/runner-images/issues/9946
sudo apt-get install -yq build-essential

echo "##[endgroup]"
echo "##[group]Delete Ubuntu OpenZFS modules"
for i in $(find /lib/modules -name zfs -type d); do sudo rm -rvf $i; done
Expand Down Expand Up @@ -306,5 +320,7 @@ esac

# reset cloud-init configuration and poweroff
sudo cloud-init clean --logs
sleep 2 && sudo poweroff &
if [ "$POWEROFF" == "1" ] ; then
sleep 2 && sudo poweroff &
fi
exit 0
11 changes: 10 additions & 1 deletion .github/workflows/scripts/qemu-4-build-vm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,16 @@ fi
# save some sysinfo
uname -a > /var/tmp/uname.txt

cd $HOME/zfs
# Check if we're running this script from within a VM or on the runner itself.
# Most of the time we will be running in a VM, but the ARM builder actually
# runs this script on the runner. If we happen to be running on the ARM
# runner, we will start in the ZFS source directory. If we're running on a VM
# then we'll just start in our home directory, and will need to 'cd' into our
# source directory.
if [ ! -e META ] ; then
cd $HOME/zfs
fi

export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"

extra=""
Expand Down
Loading
Loading