OpenZFS/src f5942d9man/man7 dracut.zfs.7, scripts spdxcheck.pl

SPDX: fix incorrect license tags

These already had SPDX tags and so were misidentifed as CDDL-1.0 in
eb9098ed47. Return them to what they were supposed to be.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18914
DeltaFile
+3-0scripts/spdxcheck.pl
+0-1tests/zfs-tests/cmd/renameat2.c
+0-1man/man7/dracut.zfs.7
+3-23 files

OpenZFS/src 5158ad4scripts spdxcheck.pl

spdxcheck: detect multiple tags within a file

Since a single tag can express multiple options, enforce that only a
single tag be present.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18914
DeltaFile
+9-2scripts/spdxcheck.pl
+9-21 files

OpenZFS/src 1b24a34tests/zfs-tests/cmd clone_after_trunc.c, tests/zfs-tests/tests/functional/block_cloning block_cloning_after_trunc.ksh

license: fix CDDL license headers identified by spdxcheck

All missed in 4b05f927dc by virtue of being "close enough".

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18914
DeltaFile
+11-1tests/zfs-tests/tests/functional/block_cloning/block_cloning_after_trunc.ksh
+10-0tests/zfs-tests/cmd/clone_after_trunc.c
+1-5tests/zfs-tests/tests/functional/mmp/mmp_zhack_reclaim.ksh
+2-3tests/zfs-tests/tests/functional/rsend/send_invalid.ksh
+4-1tests/zfs-tests/tests/functional/cli_root/zhack/zhack_metaslab_leak.ksh
+4-1tests/zfs-tests/tests/functional/cli_root/zhack/zhack_label_repair_004.ksh
+32-114 files not shown
+46-1610 files

OpenZFS/src 7de6623scripts spdxcheck.pl

spdxcheck: check CDDL-1.0 tags for correct license boilerplate

Now that we have a preferred, canonical form, we can enforce it.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18914
DeltaFile
+80-2scripts/spdxcheck.pl
+80-21 files

OpenZFS/src ccc9023lib/libzfs libzfs_pool.c, man/man1 zhack.1

mmp: tell a failed uberblock claim apart from remote activity

When the claim could not write to every device the config expects
present, spa_activity_check_claim() replaced the error from
mmp_claim_uberblock() with EREMOTEIO, so an operator whose peer died
together with its mirror legs was told another host holds the pool,
which sends them looking for a host that is not there.

Report the cause instead.  A shortfall has two causes worth telling
apart, so mmp_claim_uberblock() now counts the writes it issues
alongside the ones that succeed.  A leaf the config expects present but
which cannot be written is never issued one, so too few issued means a
device is absent, which persists across retries and is what
"zhack mmp reclaim" recovers; that returns ENODEV.  Enough issued but
too few good means the writes reached present devices and failed, which
a retry may clear; that stays EIO.  The issued count is gated exactly as
the good count is so the two describe the same set of leaves.

Both get a case in spa_ld_activity_result() and both still return

    [28 lines not shown]
DeltaFile
+37-8module/zfs/mmp.c
+40-3module/zfs/spa.c
+28-1lib/libzfs/libzfs_pool.c
+18-3tests/zfs-tests/tests/functional/mmp/mmp_zhack_reclaim.ksh
+2-6tests/zfs-tests/tests/functional/mmp/mmp_degraded_import.ksh
+3-2man/man1/zhack.1
+128-236 files

OpenZFS/src b64a7fdtests/runfiles linux.run, tests/zfs-tests/tests Makefile.am

ZTS: add coverage for zhack mmp reclaim

Six scenarios: a stranded pool is recovered and the claim then accepts
it, a live host sharing a leg is still refused, both top-level vdevs
are counted after a recovery, a pool without multihost is left alone,
a log vdev leg is not touched, and a raidz member is not touched.

Every recovery assertion re-imports as a third hostid.  zhack exports
cleanly under its own hostid, so importing again as the same host
takes the exported-and-matching-hostid path, skips the activity check
entirely, and would leave the claim unexercised and the test vacuous.

The assertions read req_writes and good_writes from the claim's own
dbgmsg line, which 20176224e added.  That is the only observable of
the claim arithmetic, at the cost of coupling the test to a debug
message this change does not control.

mmp_pool_destroy() used a bare "pgrep zhack", which matches any
process whose name merely contains zhack.  A ksh script named

    [6 lines not shown]
DeltaFile
+290-0tests/zfs-tests/tests/functional/mmp/mmp_zhack_reclaim.ksh
+9-2tests/zfs-tests/tests/functional/mmp/mmp.kshlib
+1-1tests/runfiles/linux.run
+1-0tests/zfs-tests/tests/Makefile.am
+301-34 files

OpenZFS/src 4304062cmd zhack.c, include/sys mmp.h

zhack: add "mmp reclaim" to recover a pool stranded by MMP

When a host fails together with the mirror legs attached to it, the
surviving labels still describe those legs as present, so the MMP
uberblock claim keeps demanding a write to every one of them and no
later import can satisfy it.  The pool cannot be imported by any host
again.

Add "zhack mmp reclaim", which imports once with the claim's required
write count relaxed for the mirror legs this host cannot open, marks
those leaves offline so that the ordinary imports which follow
succeed, and exports.

The relaxation is confined to userspace.  mmp_claim_relaxed is
declared under #ifndef _KERNEL, and module/Kbuild.in builds the module
with -D_KERNEL, so the flag cannot exist in a kernel module.  libzpool
does not define _KERNEL and so gets the check.  This follows the
zfeature_checks_disable pattern zhack already uses around the same
import, and is stronger, since that flag does exist in the kernel.

    [20 lines not shown]
DeltaFile
+178-0cmd/zhack.c
+58-2man/man1/zhack.1
+29-0module/zfs/mmp.c
+5-0include/sys/mmp.h
+270-24 files

OpenZFS/src 35d3574tests/zfs-tests/tests/functional/rsend send_doall.ksh send-cpL_varied_recsize.ksh

license: update URL in all headers

These all used the short-form header already, but with the old URL.
Update them to the new, to fully match the standard form.

Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <robn at despairlabs.com>
Closes #18904
DeltaFile
+1-1tests/zfs-tests/tests/functional/rsend/send_doall.ksh
+1-1tests/zfs-tests/tests/functional/rsend/send-cpL_varied_recsize.ksh
+1-1tests/zfs-tests/tests/functional/rsend/send-c_volume.ksh
+1-1tests/zfs-tests/tests/functional/rsend/send-c_verify_ratio.ksh
+1-1tests/zfs-tests/tests/functional/rsend/send-c_verify_contents.ksh
+1-1tests/zfs-tests/tests/functional/rsend/send-c_stream_size_estimate.ksh
+6-6536 files not shown
+542-542542 files

OpenZFS/src 8b81a53cmd/zed zed_conf.h zed_conf.c, man/man8 zed.8.in zfs_prepare_disk.8.in

license: convert zed/LLNL CDDL headers to a standard form

This was a slightly different structure, but the same information.
Switch to the standard header, but leave the additional copyright
notice.

Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <robn at despairlabs.com>
Closes #18904
DeltaFile
+11-9man/man8/zfs_prepare_disk.8.in
+10-9man/man8/zed.8.in
+10-7cmd/zed/zed_conf.h
+10-7cmd/zed/zed_conf.c
+10-7cmd/zed/zed.h
+10-7cmd/zed/zed.c
+61-4610 files not shown
+161-11616 files

OpenZFS/src 4b05f92. configure.ac, cmd zarcstat.in dbufstat.in

license: convert all "fenced" CDDL headers to standard form

These all used the older, more verbose version of the header. The more
recent short form is clearer and altogether nicer. Use it!

Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <robn at despairlabs.com>
Closes #18904
DeltaFile
+7-18include/os/freebsd/spl/sys/ccompile.h
+7-18configure.ac
+7-18cmd/zed/agents/fmd_serd.h
+7-18cmd/zed/agents/fmd_serd.c
+7-18cmd/zarcstat.in
+7-18cmd/dbufstat.in
+42-1082,700 files not shown
+17,057-42,0672,706 files

OpenZFS/src eec144acmd/zstream zstream_queue.h zstream_queue.c

zstream: zstream_queue bug fixes and simplifications

This PR makes several changes to `zstream_queue.c` aimed at
bulletproofing and simplification.

### Remove thread pool spindown

This PR removes code that decomissioned worker threads once the last
remaining queue had completed. The interlock between this operation and
the creation of new queues complicated the locking system significantly
and is known to have introduced at least two subtle locking bugs. With
this change, the thread pool will be created once and retained until
the process exits.

### Remove lock-free queue scoring

The code is designed to work correctly even without scoring threads
holding the queue mutexes of the queues they're examining. However,
I've confirmed through performance testing that lock-free operation

    [39 lines not shown]
DeltaFile
+134-180cmd/zstream/zstream_queue.c
+5-1cmd/zstream/zstream_queue.h
+139-1812 files

OpenZFS/src b4f70cbmodule/zfs ddt.c

Fix negative time overflows in DDT pruning

- Account DDT entries created after prune start to histogram bin 0
(now) instead of the last one (long ago) due to negative overflow.
 - Return error when requested to prune for more days than passed
since the epoch.

Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin at TrueNAS.com>
Closes #18886
DeltaFile
+7-4module/zfs/ddt.c
+7-41 files

OpenZFS/src 45eb50amodule/nvpair nvpair.c

nvpair: i_get_value_size() string array handling tweak

The strnlen() function needs to be given the length of the remaining
region to behave as intended, but it was given the length of the total
region on packed strings.

Reported-by: Grok 4.5 Build Beta
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Alek Pinchuk <Alek.Pinchuk at connectwise.com>
Signed-off-by: Richard Yao <richard at ryao.dev>
Closes #18877
DeltaFile
+15-0module/nvpair/nvpair.c
+15-01 files

OpenZFS/src 60fa372module/nvpair nvpair.c

nvpair: Improve native handling of unterminated strings

This continues the work done in 59dc88602e23a436440e4164c6d9401da8f0dff2
and parallels what is already done for XDR encoding.

Reported-by: Grok 4.5 Build Beta
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Alek Pinchuk <Alek.Pinchuk at connectwise.com>
Signed-off-by: Richard Yao <richard at ryao.dev>
Closes #18876
DeltaFile
+20-3module/nvpair/nvpair.c
+20-31 files

OpenZFS/src 28afe8b.github codeql-cpp.yml, .github/codeql/custom-queries/cpp AssignmentOfComparisonAsCondition.ql

CodeQL: Flag implicit compare-then-assign in branch conditions

Implicit compare-then-assign in branch conditions is buggy since
developers often mean assign-then-compare, but sometimes actually mean
compare-then-assign. GCC's -Wparentheses was originally meant to catch
assignment in place of comparison, requiring an extra set of parentheses
to turn this off. This had the happy coincidence of making developers
explicit about assign-then-compare vs compare-then-assign.

An outer level of extra parentheses will inhibit -Wparentheses warnings.
This often results in assign-then-compare being made explicit, but
instead of turning `if (x = foo() < 0)` into `if ((x = foo()) < 0)`, a
developer might write `if ((x = foo() < 0))`, which turns off the
warning, without fixing the problem. This happened in openzfs/zfs#18874.
There are other potential variations, such as `if ((x = (foo()) < 0))`,
which also suppresses GCC's warning, but fails to actually do anything
since the intended explicit parentheses to specify compare-then-assign
are around the right operand of the boolean operator, rather than around
the boolean operator, yet we have the additional parentheses needed to

    [43 lines not shown]
DeltaFile
+96-0.github/codeql/custom-queries/cpp/AssignmentOfComparisonAsCondition.ql
+1-0.github/codeql-cpp.yml
+97-02 files

OpenZFS/src f81e3bfmodule/zfs brt.c

Parallelize brt_pending_apply() for multiple vdevs

Unlike DDT, sorted by the checksum prefix, BRT uses salted hash.
It means that we can't pre-sort the accesses for better caching,
and with BRT size getting bigger that dbuf cache, there is a high
chance that each lookup will require a 8KB block decompression.
It is not as bad as for 32KB DDT block, but still.

Since each vdev in BRT is completely independent, running several
brt_pending_apply_vdev() instances in parallel should increase both
CPU and (in case of ARC miss) pool utilization.

Reviewed-by: Rob Norris <rob.norris at truenas.com>
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin at TrueNAS.com>
Closes #18860
DeltaFile
+39-7module/zfs/brt.c
+39-71 files

OpenZFS/src c91a759include/sys spa_impl.h spa.h, module/zfs brt.c

Parallelize cloning of deduplicated blocks

When block cloning is used on deduplicated blocks, the additional
references are accounted in DDT instead of BRT.  Previously it was
done by brt_pending_apply_vdev(), calling ddt_addref() for each
block with DEDUP flag in the block pointer.  The process was single-
threaded, and caused a bottleneck in the sync context, since with
large DDT ddt_addref() needs to decompress 32KB ZAP leaf for each
added block.

This patch changes how pending blocks with DEDUP flag are handled.
Inspead of storing them in per-vdev bv_pending_tree, sorted by
offset (which sorting makes no sense for later DDT updates), store
them in one of 16 AVL trees, sharded and sorted by their checksum
prefix.  This way we can simultaneously reduce lock contention on
pools with small number of vdevs, process the shards by separate
sync threads accessing/decompressing different ZAP leaves, and
access ZAP leaves in hash order to increase chances of decompressed
dbuf cache hits.

    [9 lines not shown]
DeltaFile
+176-36module/zfs/brt.c
+20-0include/sys/brt_impl.h
+1-0include/sys/spa_impl.h
+1-0include/sys/spa.h
+198-364 files

OpenZFS/src eb808b3module/zfs arc.c

arc: add a few invariant checks in release builds

Convert a couple ASSERTs invariants to VERIFYs to enforce them
in release builds to be able to root-case #18782 kernel panic,
whenever it happens again.

Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Andriy Tkachuk <atkachuk at wasabi.com>
Closes #18840
(cherry picked from commit 023d44b9ef68f1eff6b97d98c6a16cdb4b93cf76)
DeltaFile
+7-6module/zfs/arc.c
+7-61 files

OpenZFS/src 216de07module/zfs arc.c

arc: fix race between arc_release() and arc_read_done()

Consider the following scenario:

1. arc_release() is called on hdr with one buf, but which has
   IO_IN_PROGRESS (reading more raw data in encypted pool while
   keeping decrypted data in buf).
2. arc_release() moves hdr to anon state and discards its identity.
3. arc_read_done() is called, adds the 2nd buf to hdr, increasing
   b_refcnt to 2.

Now we have hdr in anon state with two bufs and without identity.

Or here's a racing scenario:

1. arc_release() checked that hdr is not in anon state, but before
   taking hash_lock
2. arc_read_done() takes hash_lock, moves hdr to anon state, in
   case of an error.

    [25 lines not shown]
DeltaFile
+41-13module/zfs/arc.c
+41-131 files

OpenZFS/src e8e3076include/os/linux/zfs/sys zfs_vfsops_os.h zfs_ctldir.h, module/os/linux/zfs zfs_vfsops.c zpl_ctldir.c

Linux: rewrite snapshot automount facility

This commit has a near-total rewrite of the snapshot mount/expire
facility, to try and modernise it, fix a lot of structural and
implementation issues and improve performance.

Because its a change in architecture, not just implementation, it's not
really been possible to incrementally move the implementation from the
old to the new. So, the source commentary is intended as a standalone
description of how it all works, while this commit message describes
what's changed for readers who know the previous version.

The main conceptual difference is that the previous version assumed that
there would only ever be one mount per snapshot dataset at most, and
that that mount would be on the matching `.zfs/snapshot/<snapname>`
mountpoint, and that this subsystem would be the one responsible for
unmounting. Those limitations just don't exist, as Linux mounts can be
duplicated, moved around, attached to other namespaces, even deleted,
without actually removing access to the filesystem and all without the

    [100 lines not shown]
DeltaFile
+878-725module/os/linux/zfs/zfs_ctldir.c
+403-40module/os/linux/zfs/zpl_ctldir.c
+62-0include/os/linux/zfs/sys/zpl.h
+9-8include/os/linux/zfs/sys/zfs_ctldir.h
+4-12module/os/linux/zfs/zfs_vfsops.c
+1-1include/os/linux/zfs/sys/zfs_vfsops_os.h
+1,357-7866 files

OpenZFS/src b55f7f3config kernel.m4 kernel-workqueue.m4, include/os/linux Makefile.am

Linux 5.19/6.17: handle differences in how to flush delay workqueue

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847
DeltaFile
+77-0config/kernel-workqueue.m4
+41-0include/os/linux/kernel/linux/workqueue_compat.h
+2-0config/kernel.m4
+1-0include/os/linux/Makefile.am
+121-04 files

OpenZFS/src a2a6458config kernel.m4 kernel-follow-down-one.m4, include/os/linux/kernel/linux vfs_compat.h

Linux 6.3: follow_down() gains flags arg

We need the flags arg to trigger the snapshot mount. For earlier
kernels, we can emulate it with vfs_path_lookup()

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847
DeltaFile
+70-0config/kernel-follow-down.m4
+36-0include/os/linux/kernel/linux/vfs_compat.h
+0-23config/kernel-follow-down-one.m4
+2-2config/kernel.m4
+108-254 files

OpenZFS/src 50b7b50config kernel.m4 kernel-fs-context.m4, include/os/linux/kernel/linux vfs_compat.h

Linux 6.18 compat: vfs_parse_fs_string() takes 3 args

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847
DeltaFile
+25-0config/kernel-fs-context.m4
+10-0include/os/linux/kernel/linux/vfs_compat.h
+2-0config/kernel.m4
+37-03 files

OpenZFS/src f11ec72tests/runfiles linux.run, tests/zfs-tests/tests Makefile.am

ZTS: test that a foreign mount on the snapdir can be detached

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847
DeltaFile
+50-0tests/zfs-tests/tests/functional/snapdir/snapdir_mount_foreign.ksh
+1-1tests/runfiles/linux.run
+1-0tests/zfs-tests/tests/Makefile.am
+52-13 files

OpenZFS/src 1a9f0b5tests/runfiles linux.run, tests/zfs-tests/tests Makefile.am

ZTS: test that ongoing access doesn't prevent snapdir detach

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847
DeltaFile
+80-0tests/zfs-tests/tests/functional/snapdir/snapdir_mount_fd_hold.ksh
+1-1tests/runfiles/linux.run
+1-0tests/zfs-tests/tests/Makefile.am
+82-13 files

OpenZFS/src 11d5900tests/runfiles linux.run, tests/zfs-tests/tests Makefile.am

ZTS: test multiple snapshot automounts via multiple base dataset mounts

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847
DeltaFile
+68-0tests/zfs-tests/tests/functional/snapdir/snapdir_mount_multiple.ksh
+2-1tests/runfiles/linux.run
+1-0tests/zfs-tests/tests/Makefile.am
+71-13 files

OpenZFS/src 3101e16tests/runfiles linux.run, tests/zfs-tests/tests Makefile.am

ZTS: test snapdir shutdown behaviour when automount is moved elsewhere

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847
DeltaFile
+70-0tests/zfs-tests/tests/functional/snapdir/snapdir_mount_expire_move.ksh
+64-0tests/zfs-tests/tests/functional/snapdir/snapdir_mount_move.ksh
+2-1tests/runfiles/linux.run
+2-0tests/zfs-tests/tests/Makefile.am
+138-14 files

OpenZFS/src 626dca3tests/runfiles linux.run, tests/zfs-tests/tests Makefile.am

ZTS: test snapdir shutdown behaviour when automount is bound elsewhere

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847
DeltaFile
+65-0tests/zfs-tests/tests/functional/snapdir/snapdir_mount_expire_bind.ksh
+59-0tests/zfs-tests/tests/functional/snapdir/snapdir_mount_bind.ksh
+1-1tests/runfiles/linux.run
+2-0tests/zfs-tests/tests/Makefile.am
+127-14 files

OpenZFS/src 32f4b3atests/zfs-tests/tests/functional/snapdir snapdir_admin_create_destroy.ksh

ZTS: snapdir_admin_create_destroy: use makedir helper

The rust-coreutils (uutils) mkdir calls llistxattr() immediately after
calling mkdir(), which triggers the automount, and so prevents rmdir
from seeing and deleting the mountpoint dir.

Switching over to our helper that we know only calls mkdir() fixes that
up.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847
DeltaFile
+1-1tests/zfs-tests/tests/functional/snapdir/snapdir_admin_create_destroy.ksh
+1-11 files

OpenZFS/src 1c696d0tests/zfs-tests/cmd Makefile.am .gitignore, tests/zfs-tests/include commands.cfg

ZTS: makedir helper command

The system mkdir command may do other things besides the mkdir()
syscall, which is a problem when we're trying to test the syscall
specifically. This helper only does the mkdir() syscall.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes #18847:w
DeltaFile
+33-0tests/zfs-tests/cmd/makedir.c
+2-1tests/zfs-tests/cmd/.gitignore
+1-0tests/zfs-tests/include/commands.cfg
+1-0tests/zfs-tests/cmd/Makefile.am
+37-14 files