OpenZFS/src 8f6f4bctests/runfiles sanity.run

ZTS: update sanity.run file

Several of the tests included in the sanity.run file are no
longer quick.  In fact, the pyzfs tests can take over 5 minutes
to run which exceeds the allowed default timeout resulting the
the testing being killed.

Perform a little housekeeping and drop any test which takes more
than 10 seconds to run.  This brings things back a little closer
to the original intent of having a battery of useful test cases
which can be run in ~10 minutes.

ZFS-CI-Type: quick
Reviewed-by: George Melikov <mail at gmelikov.ru>
Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Closes #18576
DeltaFile
+6-27tests/runfiles/sanity.run
+6-271 files

OpenZFS/src 1d601ebtests/unit test_zap.c Makefile.am

unit/test_zap: a trivial ZAP unit test suite

This commit adds the bones of a unit test suite for the ZAP subsystem.
The actual tests themselves don't do much, just ZAP creation and
destruction and basic KV ops. At this point its intended to be enough to
demonstrate what tests under this framework would look like.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18564
DeltaFile
+273-0tests/unit/test_zap.c
+23-1tests/unit/Makefile.am
+2-0tests/unit/.gitignore
+298-13 files

OpenZFS/src a20ef9ctests/unit mock_dmu.c mock_dmu.h

unit: dnode/dbuf/dmu_tx mocks

Some simple initial mock for key DMU structures. It's hard to say this
early how generalisable these are, however they are enough for the ZAP
unit tests (next commit).

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18564
DeltaFile
+393-0tests/unit/mock_dmu.c
+47-0tests/unit/mock_dmu.h
+2-0tests/unit/Makefile.am
+442-03 files

OpenZFS/src 82b33c0tests/unit munit.c munit.h

unit: a unit testing framework

This commit establishes a unit test framework for OpenZFS, and
integrates it into the build.

It includes:
- the "munit" unit test framework (munit.c, munit.h)
- some light extensions to munit and glue for OpenZFS (unit.c, unit.h)
- make targets for running tests and generating coverage reports
- a document explaining the what, how and why

This is a first step; I expect we will extend all of this as we use it
more places and gain experience with it.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18564
DeltaFile
+2,458-0tests/unit/munit.c
+575-0tests/unit/munit.h
+189-0tests/unit/README.md
+85-0tests/unit/unit.c
+60-0tests/unit/unit.h
+60-0tests/unit/Makefile.am
+3,427-03 files not shown
+3,431-09 files

OpenZFS/src accb2b4.github/workflows/scripts generate-ci-type.py

CI: run full CI when a workflow YAML changes

FULL_RUN_REGEX in generate-ci-type.py covered .github/workflows/scripts/
but not the workflow YAML files, so a PR that only edited zfs-qemu.yml
got "quick" CI and never tested its own matrix change. Add the YAML
files to the list.

Reviewed-by: George Melikov <mail at gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Christos Longros <chris.longros at gmail.com>
Closes #18577
DeltaFile
+1-0.github/workflows/scripts/generate-ci-type.py
+1-01 files

OpenZFS/src 1916c2c.github/workflows zfs-qemu.yml codeql.yml

CI: skip full CI runs on push events

Full CI runs for proposed changes always occur in the PR where the
review is done and patch approved.  Once merged the full CI is run
again using the merged commit.  This is somewhat overkill.  In the
interest of reducing the CI load only run the zloop and checkstyle
workflows which are enough to verify the build on the master branch.
Push events to forks will continue to trigger a full CI run.

Reviewed-by: George Melikov <mail at gmelikov.ru>
Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Closes #18571
DeltaFile
+9-2.github/workflows/zfs-qemu.yml
+1-0.github/workflows/codeql.yml
+1-0.github/workflows/smatch.yml
+1-0.github/workflows/zfs-arm.yml
+12-24 files

OpenZFS/src 9717917.github/workflows zfs-qemu.yml, .github/workflows/scripts qemu-2-start.sh

CI: enable FreeBSD 15.0-RELEASE in matrix

Add freebsd15-0r to the FreeBSD presets

Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Signed-off-by: Christos Longros <chris.longros at gmail.com>
Closes #18561
DeltaFile
+2-2.github/workflows/zfs-qemu.yml
+1-1.github/workflows/scripts/qemu-2-start.sh
+3-32 files

OpenZFS/src 1576195.github/workflows zfs-qemu-packages.yml, .github/workflows/scripts qemu-4-build-vm.sh

CI: Build custom branch from zfs-qemu-packages

The zfs-qemu-packages workflow allows us to easily build RPMs for the
current branch.  However, there can be cases where we want to use the
current CI environment to build older releases.  This can happen when
the VM or runner environment changes, and the older CI doesn't have
the updates needed to run with it anymore.

This commit adds in a text box to specify a specific branch/tag to build
using the current CI environment.

Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Tony Hutter <hutter2 at llnl.gov>
Closes #18569
DeltaFile
+30-2.github/workflows/scripts/qemu-4-build-vm.sh
+12-0.github/workflows/zfs-qemu-packages.yml
+42-22 files

OpenZFS/src 58d7194module/os/linux/zfs zpl_super.c

linux/super: properly apply ro/rw mount option to superblock

f5a9e3a622 changed how SB_RDONLY was applied to the new mount in a way
that was too simplistic - it only sets readonly on the filesystem if the
mount was 'ro', but it never clears it if the mount was 'rw'. This
causes the 'rw' option to effectively be ignored, and so the readonly=
property wins out.

This fixes it by doing it the right way: checking the flags mask to see
if it was actually provided as an option at all, and then setting or
clearing it as appropriate.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18557
Closes #18563
DeltaFile
+8-3module/os/linux/zfs/zpl_super.c
+8-31 files

OpenZFS/src 20437d8tests/runfiles common.run sanity.run, tests/zfs-tests/tests Makefile.am

ZTS/zfs_mount: test that ro/rw mount methods remain consistent

Whether a mount ends up as read-only or read-write depends on a
combination of platform, readonly= filesystem property, mount method
(system mount(8) or zfs-mount(8)) and mount option provided (ro, rw or
none).

This tests all combinations, and ensures they match what has
traditionally been expected on this platform, so we'll know if we
accidentally changed it.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18557
Closes #18563
DeltaFile
+130-0tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_ro_rw.ksh
+2-2tests/runfiles/common.run
+1-1tests/runfiles/sanity.run
+1-0tests/zfs-tests/tests/Makefile.am
+134-34 files

OpenZFS/src b394b87tests/zfs-tests/tests/functional/cli_root/zfs_mount zfs_mount.kshlib zfs_mount_remount.ksh

ZTS/zfs_mount: lift & update helpers from zfs_mount_remount

zfs_mount_remount has some nice helpers for checking the claimed and
actual read-only/read-write state of a mount. I wanted to use them for
another test but they weren't exactly what I wanted.

This adds separate functions for the different kinds of mounts the
zfs_mount_remount test wants to use, mostly to avoid the assymetry of
sometimes calling a helper function and sometimes doing it direct. It
also separates the code to get the current ro/rw mount option from
actually asserting it.

Test has been updated to use the new functions, but the logic and
structure has not changed.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18557
Closes #18563
DeltaFile
+128-0tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount.kshlib
+28-75tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_remount.ksh
+156-752 files

OpenZFS/src f9bf31f.github/workflows/scripts qemu-3-deps-vm.sh

ZTS: zfs_unshare_006_pos.ksh enable usershares

Ensure samba usershares are enabled in the CI test environment for
the zfs_unshare_006_pos test case.  By default they are disabled
in the Ubuntu 26.04 LTS and must be enabled.

Reviewed-by: Tino Reichardt <milky-zfs at mcmilk.de>
Reviewed-by: George Melikov <mail at gmelikov.ru>
Reviewed-by: Tony Hutter <hutter2 at llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Closes #18547
DeltaFile
+3-0.github/workflows/scripts/qemu-3-deps-vm.sh
+3-01 files

OpenZFS/src d64dcd2tests/zfs-tests/tests/functional/stat statx_dioalign.ksh

ZTS: statx_dioalign.ksh update to stride_dd

The uutils 0.8.0 version of dd appears to diverge from GNU behavior
and does not fail when an unaligned write O_DIRECT write is issued.
Update the test case to use stride_dd which is provided by the ZTS
so the expected syscall behavior can be verified.

Reviewed-by: Tino Reichardt <milky-zfs at mcmilk.de>
Reviewed-by: George Melikov <mail at gmelikov.ru>
Reviewed-by: Tony Hutter <hutter2 at llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Closes #18547
DeltaFile
+6-5tests/zfs-tests/tests/functional/stat/statx_dioalign.ksh
+6-51 files

OpenZFS/src c59d690tests/zfs-tests/tests/functional/devices devices_common.kshlib

ZTS: Pass dec instead of hex to mknod

On Ubuntu 26.04 the default mknod command returns an error when
provided the major and minor numbers in hex.  Switch to passing
decimal values.

Reviewed-by: Tino Reichardt <milky-zfs at mcmilk.de>
Reviewed-by: George Melikov <mail at gmelikov.ru>
Reviewed-by: Tony Hutter <hutter2 at llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Closes #18547
DeltaFile
+6-6tests/zfs-tests/tests/functional/devices/devices_common.kshlib
+6-61 files

OpenZFS/src bd2f0aa.github/workflows/scripts qemu-3-deps-vm.sh

CI: Fix qemu-guest-agent systemd enable

The qemu-guest-agent.service for Debian and Ubuntu does
not contain an install section which prevents it from
being enabled.  Add a drop-in override file so it can
be enabled and the service started on boot.

Reviewed-by: Tino Reichardt <milky-zfs at mcmilk.de>
Reviewed-by: George Melikov <mail at gmelikov.ru>
Reviewed-by: Tony Hutter <hutter2 at llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Closes #18547
DeltaFile
+9-1.github/workflows/scripts/qemu-3-deps-vm.sh
+9-11 files

OpenZFS/src 5fde52c. README.md, .github/workflows zfs-qemu.yml

CI: Add Ubuntu 26.04 builder

The Ubuntu 26.04 LTS, named "Resolute Raccoon, was released on
April 23, 2026.  Add to the supported releases in README.md and
add a CI builder for it.

Reviewed-by: Tino Reichardt <milky-zfs at mcmilk.de>
Reviewed-by: George Melikov <mail at gmelikov.ru>
Reviewed-by: Tony Hutter <hutter2 at llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Closes #18547
DeltaFile
+23-2.github/workflows/scripts/qemu-3-deps-vm.sh
+4-4.github/workflows/zfs-qemu.yml
+5-0.github/workflows/scripts/qemu-2-start.sh
+1-1README.md
+33-74 files

OpenZFS/src e5473afmodule/os/linux/spl spl-kmem.c

spl_kvmalloc: remove __GFP_COMP before calling vmalloc()

In cb1833023 we stopped using it for KM_VMEM allocations, since its not
a valid flag for vmalloc(). However, there's a fallback path for
non-KM_VMEM allocations to use vmalloc(), and we need to remove
__GFP_COMP there too to avoid a warning.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18558
DeltaFile
+6-0module/os/linux/spl/spl-kmem.c
+6-01 files

OpenZFS/src ea7fd8alib/libzfs libzfs_pool.c

libzfs_pool: add docstrings to several public functions

Cover a number of frequently-used functions that previously had no
documentation.

Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Tony Hutter <hutter2 at llnl.gov>
Signed-off-by: Christos Longros <chris.longros at gmail.com>
Closes #18538
DeltaFile
+41-1lib/libzfs/libzfs_pool.c
+41-11 files

OpenZFS/src 536c06bconfig kernel.m4

config: show progress output for kernel API checks

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18554
DeltaFile
+111-3config/kernel.m4
+111-31 files

OpenZFS/src 3f44da7. README.md, .github/workflows zfs-qemu.yml

CI: remove FreeBSD 13.5 (EOL April 30, 2026)

FreeBSD 13.5 and stable/13 reached End-of-Life on April 30, 2026 and no
longer receive security support, so they fall outside README.md's stated
support policy.

Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Signed-off-by: Christos Longros <chris.longros at gmail.com>
Closes #18553
DeltaFile
+0-17.github/workflows/scripts/qemu-2-start.sh
+3-3.github/workflows/zfs-qemu.yml
+1-1README.md
+4-213 files

OpenZFS/src eed67e4module/zfs zap.c

zap: split objset+object implementations to use a dnode

For the functions that don't (yet) have _by_dnode() variants, give them
the same treatment as the previous commit - pull their implementation
into a _by_dnode() function, with the original as a simple wrapper.

This lets them all follow the same uniform pattern, and lays the
groundwork for further cleanup in other non-dnode parts of the ZAP
subsystem.

Note that it would be trivial to expose these new _by_dnode() functions,
but there's no need to do that until there's an external need for them.

Also note that there's no change yet to the following, which are not
simple zap_t operations in the same way:

 - zap_contains: wrapper around other ops
 - zap_increment: wrapper around other opts
 - zap_*_int(): wrappers around other ops

    [8 lines not shown]
DeltaFile
+72-23module/zfs/zap.c
+72-231 files

OpenZFS/src bd02c10module/zfs zap.c

zap: make the _by_dnode() op variants be the primary implementation

The existing pattern for each operation is to have a "frontend" function
that takes an object referenced by either a objset+object pair (eg
zap_add()) or an existing dnode (eg zap_add_by_dnode()). Those functions
obtain a locked zap_t for the given object from either zap_lockdir() or
zap_lockdir_by_dnode(). That zap_t, the operation args, and the refcount
tag for lockdir() are then passed through to through to the "backend"
function (eg zap_add()), which does the work and then releases calls
zap_unlockdir() to release the zap_t.

This pattern is overcomplicated, in at least three ways:

- Both frontends for each operation have to make the call to
  zap_lockdir(), which has multiple args that must be the same for both.

- Frontends need to pass the refcount tag to the backend so it can
  call zap_unlockdir() correctly, which makes the signature more
  complicated.

    [28 lines not shown]
DeltaFile
+156-273module/zfs/zap.c
+156-2731 files

OpenZFS/src 891e379man/man7 vdevprops.7, module/os/linux/zfs vdev_disk.c

Fix failfast default and usage

The feature that added a failfast property to vdevs unfortunately did
not correctly set the default at creation time, so many vdevs do not
actually have the property set. In addition, when the property is
used, the failfast flag is not checked correctly, resulting in the
feature mostly not working as intended.

Set the failfast property to the default value at vdev allocation time.
The value will be read in from the ZAP as normal when the vdev metadata
is loaded.  Allow the property to be set on any vdev and have it be
inherited from the root or top-level vdev.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Tony Hutter <hutter2 at llnl.gov>
Signed-off-by: Paul Dagnelie <paul.dagnelie at klarasystems.com>
Closes #18410
DeltaFile
+115-0tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_inherit.ksh
+21-9module/zfs/vdev.c
+9-3module/zcommon/zpool_prop.c
+7-1module/os/linux/zfs/vdev_disk.c
+4-1man/man7/vdevprops.7
+2-2tests/runfiles/common.run
+158-163 files not shown
+161-179 files

OpenZFS/src 40a8765include/sys zap_impl.h

zap_impl: use flex array field for mzap_phys_t.mz_chunks

mz_phys_t is always a full-block allocation, with mz_chunks[] as an
array over the rest of the block past the header.

Recent Linux compiled with CONFIG_UBSAN will complain about this:

    UBSAN: array-index-out-of-bounds in module/zfs/zap.c:1236:28
    index 2 is out of range for type 'mzap_ent_phys_t [1]'

The fix is straightforward; simply convert this field to a flex member.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18550
DeltaFile
+2-1include/sys/zap_impl.h
+2-11 files

OpenZFS/src 6fb72fdmodule/zfs zio.c

zio_ddt_write: compute have_dvas after taking dde_io_lock

In zio_ddt_write(), have_dvas and is_ganged were computed before
dde_io_lock was taken. A concurrent zio_ddt_child_write_done() error
path calls ddt_phys_unextend() under dde_io_lock, which can zero
DVA[0] while another thread is between computing have_dvas and taking
dde_io_lock. That thread then uses the stale have_dvas=1 to call
ddt_bp_fill(), copying the zeroed DVA into the BP. A zero DVA resolves
as a hole, producing blocks that read back as zeros with no checksum
error (silent data corruption).

Fix by moving have_dvas and is_ganged computation to after dde_io_lock
is taken, so they always reflect the current state of dde->dde_phys.

Regression introduced by a41ef36858 ("DDT: Reduce global DDT lock
scope during writes").

Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>

    [3 lines not shown]
DeltaFile
+15-9module/zfs/zio.c
+15-91 files

OpenZFS/src 2f283c9include/sys zap_impl.h, module/zfs zap_fat.c zap.c

zap: remove refcount tags from backend functions

Since we now never need to unlock/lock an existing zap_t, we don't need
to thread through the refcount tag everywhere, which lets us simplify a
lot of calls.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18546
DeltaFile
+13-20module/zfs/zap_fat.c
+8-10module/zfs/zap.c
+6-9include/sys/zap_impl.h
+3-7module/zfs/zap_impl.c
+3-3module/zfs/zap_micro.c
+33-495 files

OpenZFS/src c8f9b4cinclude/sys zap_impl.h, module/zfs zap_fat.c zap_impl.c

zap: lift and simplify zap_t lock upgrade

Most fatzap write ops only take the READER zap_t lock, because the
header block only needs to be updated when a change would add or remove
a leaf block or spill the ptrtbl. When this happens, the lock is
upgraded to WRITER so those changes can be made.

If the lock can't be upgraded directly (not least because
rw_tryupgrade() is a no-op on Linux and userspace), then it has to be
dropped and re-acquired, that is, zap_unlock() and then zap_lock().

However, this method is far heavier than it needs to be, and adds
complication because it fully releases the zap_t, the header dbuf and
the dnode. This gives a window where the dbuf can be evicted and so the
zap_t destroyed. In addition to the IO overhead if this happens, this
means the zap_t returned by zap_lock() may be different to the original,
which means all callers need to be prepared for it to change.

zap_shrink() used an alternate method of simply dropping and reacquiring

    [18 lines not shown]
DeltaFile
+9-46module/zfs/zap_fat.c
+37-0module/zfs/zap_impl.c
+4-14module/zfs/zap.c
+12-0include/sys/zap_impl.h
+0-1module/zfs/zap_micro.c
+62-615 files

OpenZFS/src 18d910binclude/sys zap_impl.h, module/zfs zap_micro.c zap_impl.c

mzap_create_impl: use zap_lock_by_dnode()

The only reason this used zap_lock_impl() directly was to avoid an extra
dbuf hold, but there's no real reason to do that. Just use
zap_lock_by_dnode(), and then zap_lock_impl() can be de-exported.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18546
DeltaFile
+4-5module/zfs/zap_micro.c
+0-4include/sys/zap_impl.h
+1-1module/zfs/zap_impl.c
+5-103 files

OpenZFS/src d3523f9module/zfs zap_impl.c

zap_lock: make it be a simple wrapper around zap_lock_by_dnode()

The only real difference between zap_lock() and zap_lock_by_dnode() is
that the former takes and releases its own dnode hold. If we make it
just delegate to zap_lock_by_dnode(), then the dbuf hold and release can
be handled there, in one place.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18546
DeltaFile
+2-11module/zfs/zap_impl.c
+2-111 files

OpenZFS/src e4b0d59include/sys zap_impl.h, module/zfs zap.c zap_impl.c

zap: rename 'lockdir' to 'lock'

The "dir" part is a holdover from prehistoric times, where ZAPs were
just the filesystem directory object.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18546
DeltaFile
+69-69module/zfs/zap.c
+6-6module/zfs/zap_impl.c
+6-6module/zfs/zap_fat.c
+4-5module/zfs/zap_micro.c
+4-4include/sys/zap_impl.h
+89-905 files