Compare commits

..

197 Commits

Author SHA1 Message Date
Tony Hutter
743334913e Tag 2.4.0
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
2025-12-18 09:31:29 -08:00
Tony Hutter
2143bff328 CI: Change timeout values
The 'Setup QEMU' CI step updates and installs all packages necessary to
startup QEMU.  Typically the step takes a little over a minute, but
we've seen cases where it can take legitimately take more than 45min
minutes.  Change the timeout to 60 minutes.

In addition, change the 'Install dependencies' timeout to 60min since
we've also seen timeouts there.

Lastly, remove all timeouts from the zfs-qemu-packages workflow.
We do this so that we can always build packages from a branch, even if
the time it takes to do a CI step changes over time.  It's ok to
eliminate the timeouts from the zfs-qemu-packages completely since that
workflow is only run manually.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #18056
2025-12-18 09:31:29 -08:00
Brian Behlendorf
42411327cb Tag 2.4.0-rc5
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
2025-12-10 10:21:29 -08:00
Ameer Hamza
47319ef7a6 ZTS: Add test for snapshot automount race
Add snapshot_019_pos to verify parallel snapshot automount operations
don't cause AVL tree panic. Regression test for commit 4ce030e025.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #18035
2025-12-10 10:21:29 -08:00
Ameer Hamza
0bcbee6040 Fix snapshot automount race causing duplicate mounts and AVL tree panic
Multiple threads racing to automount the same snapshot can both spawn
mount helper processes that successfully complete, causing both parent
threads to attempt AVL tree registration and triggering a VERIFY()
panic in avl_add(). This occurs because the fsconfig/fsmount API lacks
the serialization provided by traditional mount() via lock_mount().

The fix adds a per-entry mutex (se_mtx) to zfs_snapentry_t that
serializes mount and unmount operations on the same snapshot. The first
mount thread creates a pending entry with se_spa=NULL and holds se_mtx
during the helper execution. Concurrent mounts find the pending entry
and return success without spawning duplicate helpers. Unmount waits on
se_mtx if a mount is pending, ensuring proper serialization. This allows
different snapshots to mount in parallel while preventing the AVL panic.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #17943
2025-12-10 10:21:29 -08:00
Ameer Hamza
74bbdda1ef Fix snapshot automount expiry cancellation deadlock
A deadlock occurs when snapshot expiry tasks are cancelled while holding
locks. The snapshot expiry task (snapentry_expire) spawns an umount
process and waits for it to complete. Concurrently, ARC memory pressure
triggers arc_prune which calls zfs_exit_fs(), attempting to cancel the
expiry task while holding locks. The umount process spawned by the
expiry task blocks trying to acquire locks held by arc_prune, which is
blocked waiting for the expiry task to complete. This creates a circular
dependency: expiry task waits for umount, umount waits for arc_prune,
arc_prune waits for expiry task.

Fix by adding non-blocking cancellation support to taskq_cancel_id().
The zfs_exit_fs() path calls zfsctl_snapshot_unmount_delay() to
reschedule the unmount, which needs to cancel any existing expiry task.
It now uses non-blocking cancellation to avoid waiting while holding
locks, breaking the deadlock by returning immediately when the task is
already running.

The per-entry se_taskqid_lock has been removed, with all taskqid
operations now protected by the global zfs_snapshot_lock held as
WRITER. Additionally, an se_in_umount flag prevents recursive waits when
zfsctl_destroy() is called during unmount. The taskqid is now only
cleared by the caller on successful cancellation; running tasks clear
their own taskqid upon completion.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #17941
2025-12-10 10:21:29 -08:00
Ameer Hamza
663dc86de2 Fix taskq NULL pointer dereference on timer race
Remove unsafe timer_pending() check in taskq_cancel_id() that created a
race where:
- Timer expires and timer_pending() returns FALSE
- task_done() frees task with tqent_func = NULL
- Timer callback executes and queues freed task
- Worker thread crashes executing NULL function

Always call timer_delete_sync() unconditionally to ensure timer callback
completes before task is freed.

Reliably reproducible by injecting mdelay(10) after setting CANCEL flag
to widen the race window, combined with frequent task cancellations
(e.g., snapshot automount expiry).

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #17942
2025-12-10 10:21:29 -08:00
Brian Behlendorf
145c606c60 Linux 6.18 compat: META (#18039)
Update the META file to reflect compatibility with the 6.18
kernel.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
2025-12-10 10:21:29 -08:00
Rob Norris
c9845a1332 Linux: work around use of GPL-only symbol kasan_flag_enabled
We may not be able to avoid our code referencing the symbol, but we can
ensure that a symbol of that name is available to the linker during
build, and so not require linking the GPL-exported version.

Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #18009
Closes #18040
2025-12-10 10:21:29 -08:00
Chunwei Chen
028d66b9dd Fix ddtprune causing space leak
In zio_ddt_free, if a pruned dde is still in ddt, it would do nothing
and cause space leak.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Signed-off-by: Chunwei Chen <david.chen@nutanix.com>
Closes #17982
Closes #17983
2025-12-10 10:21:29 -08:00
Tony Hutter
206487b9b1 CI: Fix Ubuntu 22.01 rsend failures
For whatever reason, the single `log_note` in the `directory_diff`
function causes the function to stop executing on Ubuntu 22.  This
causes most of the rsend tests to fail.  Remove the line since it's only
informational.

Signed-off-by: Tony Hutter <hutter2@llnl.gov>
2025-12-10 10:21:29 -08:00
Alex
f8572e2a97 Fix a declaration position of the nth_page.
Compilation time bug introduced by 87df5e4 commit.
Fix for the compilation error(Linux kernel 6.18.0):
"zfs/module/os/linux/zfs/abd_os.c:920:32: error: implicit declaration
of function ‘nth_page’; did you mean ‘pte_page’?
[-Werror=implicit-function-declaration]".

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: agiUnderground <alex.dev.cv@gmail.com>
Closes #18034
2025-12-10 10:21:29 -08:00
Brian Behlendorf
8c1eaea952 CI: exclude signed-off-by/reviewed-by from 72 char limit
Allow an author or reviewer's name and email address to exceed
the 72 character limit enforced by the commitcheck target.

Reviewed-by: RageLtMan <rageltman@sempervictus>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #18030
2025-12-10 10:21:29 -08:00
bspengler-oss
25d755e108 Fix HIGHMEM/kmap API violation in zfs_uiomove_bvec_impl()
Fix another instance where ZFS assumes multiple pages can be
mapped at once via zfs_kmap_local(), resulting in crashes and
potential memory corruption on HIGHMEM-enabled (typically 32-bit)
systems.

Reviewed-by: RageLtMan <rageltman@sempervictus>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: bspengler-oss <94915855+bspengler-oss@users.noreply.github.com>
Closes #15668
Closes #18030
2025-12-10 10:21:29 -08:00
bspengler-oss
5946eeb8df Preserve LIFO ordering of kmap ops in abd_raidz_gen_iterate()
ZFS typically preserves proper LIFO ordering regarding map/unmap
operations that wrap the Linux kernel's kmap interfaces that
require such ordering, but one instance in abd_raidz_gen_iterate()
did not.

Similar issues have been fixed in the Linux kernel in the past,
see for instance CVE-2025-39899 for userfaultfd.

Reviewed-by: RageLtMan <rageltman@sempervictus>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: bspengler-oss <94915855+bspengler-oss@users.noreply.github.com>
Closes #15668
Closes #18030
2025-12-10 10:21:29 -08:00
bspengler-oss
5e271995d1 Fix interaction of abd_iter_map()/abd_iter_unmap() with HIGHMEM
HIGHMEM kmap interfaces operate on only a single page at a time
yet ZFS hadn't accounted for this, resulting in crashes and
potential memory corruption on HIGHMEM (typically 32-bit) systems.
This was caught by PaX's KERNSEAL feature as it makes use of
HIGHMEM functionality on x64.

On typical 64-bit systems, this issue wouldn't have been observed,
as the map interfaces simply fall back to returning an address in
lowmem where the contiguous pages can be accessed directly.

Joint work with the PaX Team, tested by Mark van Dijk

Reviewed-by: RageLtMan <rageltman@sempervictus>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: bspengler-oss <94915855+bspengler-oss@users.noreply.github.com>
Closes #15668
Closes #18030
2025-12-10 10:21:29 -08:00
Mark Johnston
a2f768f61f FreeBSD: Fix a potential null dereference in zfs_freebsd_fsync()
In general it's possible for a vnode to not have an associated VM
object.  This happens in particular with named pipes, which have
some distinct VOPs, defined in zfs_fifoops.  Thus, this chunk of
zfs_freebsd_fsync() needs to check for the FIFO case, like other
vm_object_mightbedirty() callers do.

(Note that vn_flush_cached_data() calls are predicated on
zn_has_cached_data() returning true, and it checks for a NULL v_object
pointer already.)

Fixes: ef4058fcdc
Reported-by: Collin Funk <collin.funk1@gmail.com>
Reviewed-by: Sean Eric Fagan <sef@FreeBSD.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Mark Johnston <markj@FreeBSD.org>
Closes #18015
2025-12-10 10:21:29 -08:00
Alan Somers
872266a5f3 During CI, use nproc instead of sysctl -n hw.ncpu
The latter may give the wrong result if cpusets are in use.

Sponsored by:	ConnectWise
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by:	Alan Somers <asomers@gmail.com>
Closes #18012
2025-12-10 10:21:29 -08:00
Brian Behlendorf
ed87bc593f ZTS: Add slow_vdev_degraded_sit_out retry
While not common the draid3 vdev type has been observed to
not always sit out a vdev when run in the CI.  To prevent
continued false positives allow the test to be retried up
to three times before considering it a failure.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #18003
2025-12-10 10:21:29 -08:00
Alexander Motin
e1f0baa546 FreeBSD: Remove HAVE_INLINE_FLSL use
These macros are deprecated in FreeBSD kernel for several years,
and unneeded for much longer.  Instead, similar to Linux, let
kernel let compiler do the right things.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #18004
2025-12-10 10:21:29 -08:00
Alexander Motin
071369803e raidz_test: Restore rand_data protection
It feels dirty to modify protection of a memory allocated via libc,
but at least we should try to restore it before freeing.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17977
2025-12-10 10:21:29 -08:00
Alexander Motin
6e10a51b74 raidz_test: Fix ZIO ABDs initialization
- When filling ABDs of several segments, consider offset.
 - "Corrupt" ABDs with actually different data to fail something.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17977
2025-12-10 10:21:29 -08:00
Alexander Motin
001ce40cd4 raidz_test: Set io_offset reasonably
- io_offset of 1 makes no sense.  Set default to 0.
 - Initialize io_offset in all cases.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17977
2025-12-10 10:21:29 -08:00
Alexander Motin
68c1df8db3 ZFS: Enable more logs for raidz_001_neg
The output is not so big here, so lets collect something useful.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17977
2025-12-10 10:21:29 -08:00
Alexander Motin
a41ef36858 DDT: Reduce global DDT lock scope during writes
Before this change DDT lock was taken 4 times per written block,
and as effectively a pool-wide lock it can be highly congested.
This change introduces a new per-entry dde_io_lock, protecting some
fields during I/O ready and done stages, so that we don't need the
global lock there.

According to my write tests on 64-thread system with 4KB blocks this
significantly reduce the global lock contention, reducing CPU usage
from 100% to expected ~80%, and increasing write throughput by 10%.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17960
2025-12-10 10:21:29 -08:00
Alexander Motin
a785ddc5f3 DDT: Switch to using wmsums for lookup stats
ddt_lookup() is a very busy code under a highly congested global
lock.  Anything we can save here is very important.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17980
2025-12-10 10:21:29 -08:00
Alexander Motin
2aad3dee23 DDT: Make children writes inherit allocator
Even though unlike gang children it is not so critical for dedup
children to inherit parent's allocator, there is still no reason
for them to have allocation policy different from normal writes.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17961
2025-12-10 10:21:29 -08:00
Tony Hutter
cdbe788a39 CI: zfs-test-packages: Add in new repos
Test install from our new repos: zfs-latest, zfs-legacy,
zfs-2.3, zfs-2.2, from the zfs-test-packages workflow.
This on-demand workflow is use to verify that the zfs RPMs
in the repos are correct.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #17956
2025-12-10 10:21:29 -08:00
Rob Norris
d12eb47d96 config/kmap_atomic: initialise test data
6.18 changes kmap_atomic() to take a const pointer. This is no problem
for the places we use it, but Clang fails the test due to a warning
about being unable to guarantee that uninitialised data will definitely
not change. Easily solved by forcibly initialising it.

Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #17954
2025-12-10 10:21:29 -08:00
Rob Norris
304810208e zvol_id: make array length properly known at compile time
Using strlen() in an static array declaration is a GCC extension. Clang
calls it "gnu-folding-constant" and warns about it, which breaks the
build. If it were widespread we could just turn off the warning, but
since there's only one case, lets just change the array to an explicit
size.

Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #17954
2025-12-10 10:21:29 -08:00
Rob Norris
aa091a17bd Linux: bump -std to gnu11
Linux switched from -std=gnu89 to -std=gnu11 in 5.18
(torvalds/linux@e8c07082a8). We've always overridden that with gnu99
because we use some newer features.

More recent kernels are using C11 features in headers that we include.
GCC generally doesn't seem to care, but more recent versions of Clang
seem to be enforcing our gnu99 override more strictly, which breaks the
build in some configurations.

Just bumping our "override" to match the kernel seems to be the easiest
workaround. It's an effective no-op since 5.18, while still allowing us
to build on older kernels.

Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #17954
2025-12-10 10:21:29 -08:00
Alexx Saver
f45622ff42 chksum: run 256K benchmark on demand, preserve chksum_stat_data
Reviewed-by: Tino Reichardt <milky-zfs@mcmilk.de>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexx Saver <lzsaver.eth@ethermail.io>
Co-authored-by: Adam Moss <c@yotes.com>
Closes #17945
Closes #17946
2025-12-10 10:21:29 -08:00
Alexander Motin
2e09f166f0 FreeBSD: Fix uninitialized variable error
On FreeBSD errno is defined as (* __error()), which means compiler
can't say whether two consecutive reads will return the same.
And without this knowledge the reported error is formally right.

Caching of the errno in local variable fixes the issue.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17975
2025-12-10 10:21:29 -08:00
Shreshth3
c8ecd63acd zpool: fix special vdev -v -o conflict
Right now, running `zpool list` with -v and -o passed
does not work properly for special vdevs. This commit
fixes that problem.

See the discussion on #17839.
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Shreshth Srivastava <shreshthsrivastava2@gmail.com>
Closes #17932
2025-12-10 10:21:29 -08:00
Brian Behlendorf
d06ebddee4 CI: Add smatch static analysis workflow
Smatch is an actively maintained kernel-aware static analyzer
for C with a low false positive rate.  Since the code checker
can be run relatively quickly against the entire OpenZFS code
base (15 min) it makes sense to add it as a GitHub Actions
workflow.  Today smatch reports a significant numbers warnings
so the workflow is configured to always pass as long as the
analysis was run.  The results are available for reference.
Long term it would ideal to resolve all of the errors/warnings
at which point the workflow can be updated to fail when new
problems are detected.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Toomas Soome <tsoome@me.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17935
2025-12-09 15:34:45 -08:00
Toomas Soome
040c533280 cmd/zpool cstyle issues
add missing headers.
usage() is no-return, so anything after call to it is unreachable code.
use (void) cast where we do ignore return value.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Toomas Soome <tsoome@me.com>
Closes #17885
2025-12-09 15:34:13 -08:00
Brian Behlendorf
099f69ff5d Tag 2.4.0-rc4
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
2025-11-12 13:10:09 -08:00
Brian Behlendorf
7a919fb70c Update all ABI files
Refresh all ABI files using the CI generated files to reflect
the library interfaces to be published for the 2.4 release.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17911
2025-11-12 13:07:36 -08:00
Brian Behlendorf
5714090fb9 libspl: hide zfs_tunable_* symbols
The zfs_tunable_* functions are a public interface which are
part of the internal libspl convenience library.  They should
be hidden to prevent an unnecessary ABI change in installed
libraries which link against libspl (e.g. libzfs_core, libuutil).

We do already leak long standing libspl symbols.  This commit is
solely intended to prevent leaking these new ones until this is
properly sorted out.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17911
2025-11-12 13:07:32 -08:00
Brian Behlendorf
5b2489caf2 Bump SONAME of libzfs and libzpool
The ABI of libzfs and libzpool have breaking changes since the
last major release.  Bump the SONAME for the upcoming 2.4 release
branch to libzfs7 and libzpool7.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17911
2025-11-12 13:07:28 -08:00
Brian Behlendorf
ff536b1538 Bump SONAME on libnvpair
The nvlist_snprintf() function was added to the ABI of libnvpair.
No other symbols were modified or removed.  Bump the library-info
SONAME current and age args to reflect this is a minor library
version update.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17911
2025-11-12 13:07:23 -08:00
Adi-Goll
7ebb5e9b3f Reduce timeout to zero when running inside a container
Detect container environments and set timeout to zero unless
ZFS_MODULE_TIMEOUT is already set. This avoids an unnecessary ten
second delay after running zfs/zpool commands in a container where
/dev/zfs is unavailable.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Adi Gollamudi <adigollamudi@gmail.com>
Closes #15165
Closes #17922
2025-11-12 13:07:20 -08:00
Mariusz Zaborski
1e8c96d7d5 Add knob to disable slow io notifications
Introduce a new vdev property `VDEV_PROP_SLOW_IO_REPORTING` that
allows users to disable notifications for slow devices.
This prevents ZED and/or ZFSD from degrading the pool due to slow
I/O.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Mariusz Zaborski <oshogbo@FreeBSD.org>
Closes 17477
2025-11-12 13:07:14 -08:00
Alexander Motin
41878d57ea Add BRT support to zpool prefetch command
Implement BRT (Block Reference Table) prefetch functionality similar
to existing DDT prefetch.  This allows preloading BRT metadata into
ARC to improve performance for block cloning operations and frees
of earlier cloned blocks.

Make -t parameter optional.  When omitted, prefetch all supported
metadata types (both DDT and BRT now).

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17890
2025-11-12 13:07:09 -08:00
Alexander Motin
002bc3da6a BRT: Increase block size from 4KB to 8KB
According to my observations, BRT ZAPs are typically compressible
3:1 for data and 2:1 for indirects.  With ashift=12, typical these
days, it means increasing the block sizes to 8KB we may get most
of possible compression, reducing on-disk and in-ARC BRT footprint
in half by the cost of some compression/decompression overhead,
but without real write inflation, only some dirty data increase.

Increase to 32KB similar to DDT could further increase compression
and storage efficiency, but at the cost of write inflation and
much bigger dirty data increase, which we can not properly control
now.  So lets leave this for a time when BRT log gets implemented.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17916
2025-11-12 13:07:04 -08:00
Alexander Motin
e895c76194 ZAP: Remove dmu_object_info_from_dnode() call
dmu_object_info_from_dnode() takes two locks and copies plenty of
data that we don't need in zap_lockdir_impl().  Just read dn_type
directly in this hot path.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17921
2025-11-12 13:07:00 -08:00
Rob Norris
ac0bc4cc00 spa_misc: add an API for spa_namespace_lock
This is useful as debugging support, as it lets namespace lock
operations be traced directly. It will also be useful for future work to
reduce the use of spa_namespace_lock, traditionally a source of
difficult deadlocks.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17906
2025-11-12 13:06:54 -08:00
Alexander Motin
e305c7d596 BRT: Fix ranges to blocks conversion math
BRT_RANGESIZE_TO_NBLOCKS() takes number of ranges as its argument.
To get number of blocks we should multiply it by the entry size,
not divide by it, as it was due to missing parentheses.

Before #17875 this could cause small memory corruptions for vdevs
bigger than 64TB, but the change made the bug more noticeable.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17886
Closes #17915
2025-11-12 13:06:48 -08:00
Adi-Goll
e1734111fd Update man page description of zpool rewind
Update description of zpool import --rewind-to-checkpoint in
man/man7/zpoolconcepts.7 to explain that rewinding automatically
discards a checkpoint.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Adi Gollamudi <adigollamudi@gmail.com>
Closes #12646
Closes #17918
2025-11-12 13:06:43 -08:00
Alexander Motin
aaf374bd40 ZIO: Set minimum number of free issue threads to 32
Free issue threads might block waiting for synchronous DDT, BRT or
GANG header reads. So unlike other taskqs using ZTI_SCALE to scale
with number of CPUs, here we also need some amount of threads to
potentially saturate pool reads.  I am not sure we always want the
96 threads we had before ZTI_SCALE introduction at #11966 on small
systems, but lets make it at least 32.

While here, make free taskqs configurable, similar to read and
write ones.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17903
2025-11-12 13:06:39 -08:00
rmacklem
583db40030 FreeBSD: Add support for _PC_CASE_INSENSITIVE
FreeBSD now has a pathconf name called _PC_CASE_INSENSITIVE
used to check if a file system performs case insensitive
name lookups.

This patch adds support for this name.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rick Macklem <rmacklem@uoguelph.ca>
Closes #17908
2025-11-12 13:06:36 -08:00
Brian Behlendorf
84dd55510b zstd: disable intrinsics
Disable the aarch64 NEON SIMD intrinsics for kernel builds.  Safely
using them in the kernel context requires saving/restoring the FPU
registers which is not currently done.

Additionally, remove the aarch64 optimized PREFETCH_L1 and PREFETCH_L2
instruction.  Rely on the more portable compiler built ins.

This lets us remove the problematic workaround in the aarch64_compat.h
header which undefines the __aarch64__ macro.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Tino Reichardt <milky-zfs@mcmilk.de>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17904
Closes #17852
2025-11-12 13:06:22 -08:00
Adi-Goll
015729a11b Fix typo in vdev_raidz.c
Change the spelling of "begining" on line 4875 to
"beginning".

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Adi Gollamudi <adigollamudi@gmail.com>
Closes #17905
2025-11-12 13:06:19 -08:00
Toomas Soome
4fd926ab40 libzfs: ignoring unreachable code
We have infinite loop and on certain condition, we exit this loop
and thread with pthread_exit(). But also after this loop,
we have a code to perform pthread_cleanup_pop() and return from the
thread.

The  problem is that modern compilers are able to recognize that we
actually never get to the statements after loop and therefore
it is dead code there.

I think, instead of pthread_exit(), it is better to break out of loop
and let the last statements to work as intended. This is because
we do need to keep pthread_cleanup_pop() anyhow. Of course,
it is matter of taste if we want to use return or pthread_exit as very
last statement in this function.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Igor Kozhukhov <igor@dilos.org>
Signed-off-by: Toomas Soome <tsoome@me.com>
Closes #17900
2025-11-12 13:06:15 -08:00
Rob Norris
7b121388fb man: describe zfs-rewrite method and properties
We've heard anecdotes that suggest some
confusion/surprise/disappointment that a changed recordsize is not
applied during rewrite. Until such time as we actually can do that, we
can at least explicitly mention it at something that doesn't work.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17898
2025-11-12 13:06:10 -08:00
Alexander Ziaee
055e908d47 zfs-jail.8: Add introductory sentence, refactor
Add an introductory sentance explaining why the reader may want to use
this command, and establishing the requirement that the jail must be
running. Move other requirements from the description of the subcommands
to follow this for flow and structure. Move the caveat that this is for
FreeBSD down to a cannonical CAVEATS section, and crossreference Linux's
equivelant functionality. Mention that this utility can not be used to
delegate the root directory of the jail to that section also.

Reported by: Jan Brankamp <crest@rlwinm.de>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Signed-off-by: Alexander Ziaee <ziaee@FreeBSD.org>
Closes #17883
2025-11-12 13:06:06 -08:00
Tony Hutter
a2a34d9212 Linux 6.17 compat: Fix broken projectquota on 6.17
We need to specifically use the FX_XFLAG_* macros in zpl_ioctl_*attr()
codepaths, and the FS_*_FL macros in the zpl_ioctl_*flags() codepaths.
The earlier code just assumes the FS_*_FL macros for both codepaths.
The 6.17 kernel add a bitmask check in copy_fsxattr_from_user() that
exposed this error via failing 'projectquota' ZTS tests.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #17884
Closes #17869
2025-11-12 13:06:01 -08:00
Paul Dagnelie
dda711dbb5 Fix gang write late_arrival bug
When a write comes in via dmu_sync_late_arrival, its txg is equal to the
open TXG. If that write gangs, and we have not yet activated the new
gang header feature, and the gang header we pick can store a larger gang
header, we will try to schedule the upgrade for the open TXG + 1. In
debug mode, this causes an assertion to trip. This PR sets the TXG for
activating the feature to be the larger of either the current open TXG
or the syncing TXG + 1.

Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Closes #17824
2025-11-12 13:05:54 -08:00
Tino Reichardt
be1e5d599b CI: Update FreeBSD versions and ci-type handling
Update FreeBSD versions:
- add FreeBSD 15.0-STABLE
- add FreeBSD 16.0-CURRENT

So we use the latest versions of each line now:
  - Freebsd 14.3 (RELEASE)
  - FreeBSD 15.0 (STABLE)
  - FreeBSD 16.0 (CURRENT)

In commits - you may specify which type of CI should run:
- ZFS-CI-Type: quick
- ZFS-CI-Type: linux
- ZFS-CI-Type: freebsd
- ZFS-CI-Type: full

Reviewed-by: Alexx Saver <lzsaver@users.noreply.github.com>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tino Reichardt <milky-zfs@mcmilk.de>
Closes #17896
2025-11-12 13:05:49 -08:00
Toomas Soome
612e8f1e57 get_key_material_https: label 'kfdok' defined but not used
The label 'kfdok' is only used with O_TMPFILE, we need to use
the same #ifdef around this label.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Toomas Soome <tsoome@me.com>
Closes #17894
2025-11-12 13:05:45 -08:00
Robert Evans
5582e8b08e Update dnode_next_offset_level to accept blkid instead of offset
Currently this function uses L0 offsets which:
1. is hard to read since it maps offsets to blkid and back each call
2. necessitates dnode_next_block to handle edge cases at limits
3. makes it hard to tell if the traversal can loop infinitely

Instead, update this and dnode_next_offset to work in (blkid, index).
This way the blkid manipulations are clear, and it's also clear that
the traversal always terminates since blkid goes one direction.

I've also considered updating dnode_next_offset to operate on blkid.
Callers use both patterns, so maybe another PR can split the cases?

While here tidy up dnode_next_offset_level comments.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Robert Evans <evansr@google.com>
Closes #17792
2025-11-12 13:05:40 -08:00
jamisiveshkumar
c9835dab1f Fix capitalization typo in README.md
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Signed-off-by: Sivesh Kumar <siveshjami@gmail.com>
Closes #17889
2025-11-12 13:05:35 -08:00
Alexander Motin
67fc49433f Cleanup ZIO_FLAG_IO_RETRY vs TRYHARD usage
In cases where all issued ZIOs must succeed, and we can't do
anything clever about the errors, we should just explicitly set
ZIO_FLAG_TRYHARD and let OS to do all the reasonable retries.

In other cases, where retries can be different from the original,
for example, some ZIOs are allowed to fail due to redundancy, or
we can disable aggregation on retrial to get at least some of
the data, we can do first pass without TRYHARD, and only if needed
retry with ZIO_FLAG_IO_RETRY (which implies TRYHARD semantics).

Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17877
2025-11-12 13:05:31 -08:00
Alexander Motin
e3acd0a728 Fix caching of DDT log and BRT
Both DDT log and BRT counters we read on pool import and then only
append or overwrite in full blocks.  We don't need them in DMU or
ARC caches.  Fortunately we have DMU_UNCACHEDIO for this now.

Even more we don't need BRT in non-evictable metadata DMU caches,
since it will likely never fit there, while block the cache from
its original users.  Since DMU_OT_IS_METADATA_CACHED() has no way
to differentiate the new metadata types, mark BRT with storage
type of DMU_OT_DDT_ZAP.  As side effect it will also put it on
dedup device, but that should actually be right.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17875
2025-11-12 13:05:25 -08:00
Alexander Motin
178a8be216 BRT: Round bv_entcount up to BRT_BLOCKSIZE
Since we set bv_mos_brtvdev block size, and since we keep dirty
bitmap at the same granularity, we should keep the allocations
and writes done with.  Otherwise it makes the last block write
short, that will be odd once we implement writing of only dirty
blocks, but also requires read-modify-write on DMU layer.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17875
2025-11-12 13:05:21 -08:00
Joseph Anthony Pasquale Holsten
29567f13f6 autogen.sh: remove workaround for automake <1.14, needed for EL <=7
Ultimately this is a revert of 779ac93, which according to
@nabijaczleweli is to paper over automake <1.14's lack of
%reldir% support.

As I understand it, EL8 is the lowest current build target.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Joseph Holsten <joseph@josephholsten.com>
Closes #17878
2025-11-12 13:05:16 -08:00
Brian Behlendorf
e8d2e08345 Retire ZoL patch scripts
Remove the out of date helper scripts originally used to port
Illumos commits to the ZoL repository.  Due to layout changes
made to this repository they're no longer entirely correct.
Remove them to make it clear they're no longer being used or
actively maintained.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17880
2025-11-12 13:05:11 -08:00
Alexander Motin
5847626175 Pass flags to more DMU write/hold functions
Over the time many of DMU functions got flags argument to control
prefetch, caching, etc.  Few functions though left without it, even
though closer look shown that many of them do not require prefetch
due to their access pattern.  This patch adds the flags argument to
dmu_write(), dmu_buf_hold_array() and dmu_buf_hold_array_by_bonus(),
passing DMU_READ_NO_PREFETCH where applicable.

I am going to also pass DMU_UNCACHEDIO to some of them later.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17872
2025-11-12 13:04:58 -08:00
Quartz
9a9e06e5dd man: Update zpool-event subclass names and document new types
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Quartz <yyhran@163.com>
Closes #17868
2025-11-12 13:04:51 -08:00
Toomas Soome
82d59f7666 ZTS: autotrim_config.ksh is missing pool type
functional/trim tests do create pools of different types to test
trim, autotrim_config.ksh is missing the type from zpool
create command line while we are looping over different pool
types.

Sponsored-by: Edgecast Cloud LLC.
Signed-off-by: Toomas Soome <tsoome@me.com>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17874
2025-11-12 13:04:47 -08:00
Ryan Libby
672fea2a50 FreeBSD zio_crypt.c: initialize uio variables before access
In zio_crypt_key_wrap and zio_crypt_key_unwrap, the cuio_s variable was
not initialized before the calls to zfs_uio_init, leading to
uninitialized access to cuio_s.uio_offset.  Initialize it to avoid gcc
warnings.

Similar issue as fixed in 2bf152021 ("Fix gcc uninitialized warning in
FreeBSD zio_crypt.c")

Signed-off-by: Ryan Libby <rlibby@FreeBSD.org>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17863
2025-11-12 13:04:42 -08:00
Rob Norris
ad6eee2b9b mailmap/AUTHORS: update with recent new contributors
We’re not always on the same page, but at least we’re in the same book.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #17860
2025-11-12 13:04:35 -08:00
Rob Norris
f43839e7fd ZTS: fail test run if test runner crashes unexpectedly
zfs-tests.sh executes test-runner.py to do the actual test work. Any
exit code < 4 is interpreted as success, with the actual value
describing the outcome of the tests inside.

If a Python program crashes in some way (eg an uncaught exception), the
process exit code is 1.

Taken together, this means that test-runner.py can crash during setup,
but return a "success" error code to zfs-tests.sh, which will report and
exit 0. This in turn causes the CI runner to believe the test run
completed successfully.

This commit addresses this by making zfs-tests.sh interpret an exit code
of 255 as a failure in the runner itself. Then, in test-runner.py, the
"fail()" function defaults to a 255 return, and the main function gets
wrapped in a generic exception handler, which prints it and calls
fail().

All together, this should mean that any unexpected failure in the test
runner itself will be propagated out of zfs-tests.sh for CI or any other
calling program to deal with.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17858
2025-11-12 12:57:59 -08:00
Tony Hutter
814f9afba7 Tag 2.4.0-rc3
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
2025-10-21 09:52:08 -07:00
Jean-Sébastien Pédron
6f6e1c90ae FreeBSD: zfs_getpages: Don't zero freshly allocated pages
Initially, `zfs_getpages()` is provided with an array of busy pages by
the vnode pager. It then tries to acquire the range lock, but if there
is a concurrent `zfs_write()` running and fails to acquire that range
lock, it "unbusies" the pages to avoid a deadlock with `zfs_write()`.
After that, it grabs the pages again and retries to acquire the range
lock, and so on.

Once it got the range lock, it filters out valid pages, then copy DMU
data to the remaining invalid pages.

The problem is that freshly allocated zero'd pages it grabbed itself are
marked as valid. Therefore they are skipped by the second part of the
function and DMU data is never copied to these pages. This causes mapped
pages to contain zeros instead of the expected file content.

This was discovered while working on RabbitMQ on FreeBSD. I could
reproduce the problem easily with the following commands:

    git clone https://github.com/rabbitmq/rabbitmq-server.git
    cd rabbitmq-server/deps/rabbit

    gmake distclean-ct RABBITMQ_METADATA_STORE=mnesia \
      ct-amqp_client t=cluster_size_3:leader_transfer_stream_send

The testsuite fails because there is a sendfile(2) that can happen
concurrently to a write(2) on the same file. This leads to sendfile(2)
or read(2) (after the sendfile) sending/returning data with zeros, which
causes a function to crash.

The patch consists of not setting the `VM_ALLOC_ZERO` flag when
`zfs_getpages()` grabs pages again. Then, the last page is zero'd if it
is invalid, in case it would be partially filled with the end of the
file content. Other pages are either valid (and will be skipped) or they
will be entirely overwritten by the file content.

Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Mark Johnston <markj@FreeBSD.org>
Signed-off-by: Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
Closes #17851
2025-10-21 09:50:43 -07:00
Rob Norris
aeff23939a Linux 6.18: generic_drop_inode() and generic_delete_inode() renamed
Sponsored-by: https://despairlabs.com/sponsor/
Signed-off-by: Rob Norris <robn@despairlabs.com>
2025-10-21 09:50:43 -07:00
Rob Norris
7730109762 sha256_generic: make internal functions a little more private
Linux 6.18 has conflicting prototypes for various sha256_* and sha512_*
functions, which we get through a very long include chain. That's tough
to fix right now; easier is just to rename our internal functions.

Sponsored-by: https://despairlabs.com/sponsor/
Signed-off-by: Rob Norris <robn@despairlabs.com>
2025-10-21 09:50:43 -07:00
Rob Norris
2778832e22 Linux 6.18: namespace type moved to ns_common
The namespace type has moved from the namespace ops struct to the
"common" base namespace struct. Detect this and define a macro that does
the right thing for both versions.

Sponsored-by: https://despairlabs.com/sponsor/
Signed-off-by: Rob Norris <robn@despairlabs.com>
2025-10-21 09:50:43 -07:00
Rob Norris
005c631499 Linux 6.18: replace write_cache_pages()
Linux 6.18 removed write_cache_pages() without a usable replacement.
Here we implement a minimal zpl_write_cache_pages() that find the dirty
pages within the mapping, gets them into the expected state and hands
them off to zfs_putpage(), which handles the rest.

Sponsored-by: https://despairlabs.com/sponsor/
Signed-off-by: Rob Norris <robn@despairlabs.com>
2025-10-21 09:50:43 -07:00
Rob Norris
04d0f83f4e Linux 6.18: block_device_operations->getgeo takes struct gendisk*
Sponsored-by: https://despairlabs.com/sponsor/
Signed-off-by: Rob Norris <robn@despairlabs.com>
2025-10-21 09:50:43 -07:00
Rob Norris
49f078997a Linux 6.18: convert ida_simple_* calls
ida_simple_get() and ida_simple_remove() are removed in 6.18. However,
since 4.19 they have been simple wrappers around ida_alloc() and
ida_free(), so we can just use those directly.

Sponsored-by: https://despairlabs.com/sponsor/
Signed-off-by: Rob Norris <robn@despairlabs.com>
2025-10-21 09:50:43 -07:00
Rob Norris
3fb241157f Linux 6.18: replace nth_page()
Sponsored-by: https://despairlabs.com/sponsor/
Signed-off-by: Rob Norris <robn@despairlabs.com>
2025-10-21 09:50:43 -07:00
Andrew Walker
799bda73e2 Fix return value for setting zvol threading
We must return -1 instead of ENOENT if the special zvol threading
property set function can't locate the dataset (this would typically
happen with an encypted and unmounted zvol) so that the operation
gets inserted properly into the nvlist for operations to set. This
is because we want the property to be set once the zvol is
decrypted again.

Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Ameer Hamza <ahamza@ixsystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Andrew Walker <awalker@ixsystems.com>
Closes #17836
2025-10-21 09:50:43 -07:00
Shreshth3
b0106a1b74 zdb: fix bug with -A flag
Fixes #10544.

According to the manpage, zdb -A should
ignore all assertions. But it currently
does not do that. This commit fixes
this bug.

Signed-off-by: Shreshth Srivastava <shreshthsrivastava2@gmail.com>
Reviewed-by: Rob Norris <rob.norris@klarasystems.com>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17825
2025-10-21 09:50:43 -07:00
Andrew Walker
084f8d0077 Fix ZFS_READONLY implementation on Linux
MS-FSCC 2.6 is the governing document for
DOS attribute behavior. It specifies the following:

For a file, applications can read the file but
cannot write to it or delete it. For a directory,
applications cannot delete it, but applications can
create and delete files from the directory.

Signed-off-by: Andrew Walker <awalker@ixsystems.com>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Ameer Hamza <ahamza@ixsystems.com>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17837
2025-10-21 09:50:43 -07:00
Brian Behlendorf
7987d4deb4 Update device removal documentation
Make a minor update to the 'zpool remove' man page to clarify both
raidz and draid pools do not support removal, and change sector to
ashift which is what we actually care about.

Update the big theory comment in vdev_removal.c to accurately reflect
which types of vdevs can be removed.  Furthermore, I've added some
discussion for the casual reader to briefly explain the top-level
vdev removal restrictions.  This has been a common area of confusion
and it's not intuitive where they come from without understanding
the implementation details.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17847
2025-10-21 09:50:43 -07:00
Rob Norris
1956417b54 mmap_seek: print error code and text on failure
If lseek() returns an unexpected error, it's useful to know the error
code to help connect it to the trouble spot inside the module.

Since the two seek functions should be basically identical, lift them
into a single generic function.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Robert Evans <evansr@google.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17843
2025-10-21 09:50:43 -07:00
Ameer Hamza
3378a324df CI: Fix FreeBSD 15.0 by staying on ALPHA4 due to broken ALPHA5 image
FreeBSD 15.0-ALPHA5 image fails to boot on cloud VMs due to missing
/boot/efi mount point, causing the system to drop to single user mode
where SSH cannot start. Work around this by staying on ALPHA4 and
setting IGNORE_OSVERSION=yes to bypass pkg's kernel version mismatch
prompt during bootstrap. This allows CI to proceed with ALPHA4 until we
have a stable FreeBSD 15.0 image.

Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17846
2025-10-21 09:50:43 -07:00
Shreshth3
f16fa115d1 arc: fix small typos
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Rob Norris <rob.norris@klarasystems.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Signed-off-by: Shreshth Srivastava <shreshthsrivastava2@gmail.com>
Closes #17840
2025-10-21 09:50:43 -07:00
Rob Norris
f0c76f8a7b libzpool/cmn_err: remove suppression, add stop option, cleanup
A small uplift of the cmn_err() and panic() calls in userspace:

- remove the suppression on CE_NOTE. We have very few of these calls in
  a standard build, it's convenient for "print debugging".

- make prefixes clear and consistent.

- add LIBZPOOL_PANIC_STOP environment variable to send SIGSTOP to the
  process group on a panic, rather than abort(), so all threads remain
  alive for inspection.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17834
2025-10-21 09:50:43 -07:00
Mark Johnston
c1f55bff8b Fix the type of the raidz_outlier_check_interval_ms parameter
It's an hrtime_t, which is an unsigned long long.  In practice this is
just a U64.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Rob Norris <rob.norris@klarasystems.com>
Signed-off-by: Mark Johnston <markj@FreeBSD.org>
Closes #17833
2025-10-21 09:50:43 -07:00
Alexander Motin
f0bff230f9 Suppress some ashift warnings
Do not warn about vdev ashifts being smaller then physical ashifts
in a pool status if the pool ashift property set and vdev ashift
satisfies it (bigger or equal), since user explicitly requested
this.  The ashift of individual vdevs are still reported.

Do not warn about vdev ashifts in zpool import, since it doesn't
matter much, and we don't even report individual vdevs ashifts
there.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Rob Norris <rob.norris@klarasystems.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17830
2025-10-21 09:50:43 -07:00
Alexander Motin
b9356f06ed Explicit set ashift for non-leaf vdevs
Before this change ashift property was applied only to a leaf
vdevs.  As result, it worked only as a minimal value for parent
vdevs, since bigger physical_ashift value reported by any child
could be used instead when deciding parent's ashift, as if the
ashift property was never set.

This change explicitly passes ZPOOL_CONFIG_ASHIFT to all vdevs,
allowing override for parents only if the passed value is below
logical_ashift and so unacceptable.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Rob Norris <rob.norris@klarasystems.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17826
2025-10-21 09:50:43 -07:00
Ameer Hamza
30a3e609a2 zpool_reopen_004_pos: Clear label from offline disk after destroy
zpool_reopen_004_pos destroys a pool with an offline disk, leaving its
label intact. In TrueNAS local repo, zpool_reopen_005_pos is skipped,
causing zpool_reopen_007_pos to fail as it doesn't use -f flag when
creating pools unlike zpool_reopen_005_pos.

Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17831
2025-10-21 09:50:43 -07:00
Dag-Erling Smørgrav
964dfc3176 FreeBSD: Correct _PC_MIN_HOLE_SIZE
The actual minimum hole size on ZFS is variable, but we always report
SPA_MINBLOCKSIZE, which is 512.  This may lead applications to believe
that they can reliably create holes at 512-byte boundaries and waste
resources trying to punch holes that ZFS ends up filling anyway.

* In the general case, if the vnode is a regular file, return its
  current block size, or the record size if the file is smaller than
  its own block size.  If the vnode is a directory, return the dataset
  record size.  If it is neither a regular file nor a directory,
  return EINVAL.

* In the control directory case, always return EINVAL.

Signed-off-by: Dag-Erling Smørgrav <des@FreeBSD.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17750
2025-10-21 09:50:43 -07:00
Shreshth3
e4a393cf78 Add missing include statement
Resolve a build failure for user applications that include <sys/uio.h>.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Shreshth Srivastava <shreshthsrivastava2@gmail.com>
Closes #17781
Closes #17814
2025-10-21 09:50:43 -07:00
Tony Hutter
e09c86cb1f zvol: verify IO type is supported
ZVOLs don't support all block layer IO request types.  Add a check for
the IO types we do support.  Also, remove references to
io_is_secure_erase() since they are not supported on ZVOLs.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #17803
2025-10-21 09:50:43 -07:00
Mateusz Guzik
6c73fd8eeb Annotate arc_buf_is_shared as __maybe_unused
Otherwise the compiler warns about it on production FreeBSD builds.

The routine proved resilient to attempts to ifdef on debug.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Closes #17818
2025-10-21 09:50:43 -07:00
Tino Reichardt
9050ecb75c CI: Switch FreeBSD 15 to 15.0-ALPHA4 and add FreeBSD 16
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tino Reichardt <milky-zfs@mcmilk.de>
Closes #17815
2025-10-21 09:50:43 -07:00
Ivan Shapovalov
cf9163f250 zdb: adjust block histogram binning strategy
Previously, a bin included all blocks _starting_ from given size
(e.g., a "4K" bin would include all blocks within the [4K; 8K) region).
This is counter-intuitive and does not match the typical use-case of the
block histogram (that is, to estimate disk usage considering how ZFS'
block allocation works). In other words, if I'm looking at the "4K" row,
I'm interested in records that _fit into_ a 4K block.

Adjust the binning strategy such that a bin includes all blocks _up to_
given size, such that e.g. a "4K" bin would include all blocks within
the (2K; 4K] region.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Closes #16999
2025-10-21 09:50:43 -07:00
Ivan Shapovalov
250e2ec229 zdb: factor out block histogram bin number computation
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Closes #16999
2025-10-21 09:50:43 -07:00
Ivan Shapovalov
968cfc3df2 zdb: add --class=(normal|special|...) to filter blocks by alloc class
When counting blocks to generate block size histograms (`-bb`), accept a
`--class=` argument (as a comma-separated list of either "normal",
"special", "dedup" or "other") to only consider blocks that belong to
these metaslab classes.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Closes #16999
2025-10-21 09:50:43 -07:00
Ivan Shapovalov
627b530059 zdb: add --bin=(lsize|psize|asize) arg to control histogram binning
When counting blocks to generate block size histograms (`-bb`), accept a
`--bin=` argument to force placing blocks into all three bins based on
*this* size.

E.g. with `--bin=lsize`, a block with lsize=512K, psize=128K, asize=256K
will be placed into the "512K" bin in all three output columns. This
way, by looking at the "512K" row the user will be able to determine
how well was ZFS able to compress blocks of this logical size.

Conversely, with `--bin=psize`, by looking at the "128K" row the user
will be able to determine how much overhead was incurred for storage
of blocks of this physical size.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Closes #16999
2025-10-21 09:50:43 -07:00
Ivan Shapovalov
6809137db5 zdb: convert ALLOCATED_OPT into anonymous enum
We are adding more long-only options, so use an enum for all of them
to avoid manually numbering these constants.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Closes #16999
2025-10-21 09:50:43 -07:00
Rob Norris
3e7e19e028 pool_iter_refresh: don't refresh pools twice
In "all pools" mode, pool_iter_refresh() will call zpool_iter(), which
will call zpool_refresh_stats() before calling add_pool(). If we already
have the pool, this is a different handle, so we just release it and
return. Back in pool_iter_refresh(), we then call zpool_stats_refresh()
again for our handle on the same pool.

All together, this means we're doing two ZFS_IOC_POOL_STATS calls into
the kernel for every pool in the system. This isn't wrong, but it does
double the pressure on global locks.

Instead, we add a new function zpool_refresh_stats_from_handle() that
simply copies the pool config and state from one handle to another, and
use it to update our handle before we release it in add_pool(), so we
only have one call per pool per interval.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17807
2025-10-21 09:50:43 -07:00
Rob Norris
4c84b77bc4 pool_iter_refresh: don't flag existing pools as refreshed
zpool_iter() passes the callback a new instance of zpool_handle_t each
time, so the existing handle in the pool_list AVL never actually gets a
refresh. Internally, that means its zpool_config is never updated, and
the old config is never moved to zpool_old_config. As a result,
print_iostat() never sees any updated config, and so repeats the first
line forever.

This is the simplest workaround: just don't mark existing pools as
refreshed. pool_list_refresh() will see this and refresh them.
The downside is a second call to ZFS_IOC_POOL_STATS for existing pools,
because zpool_iter() just called it for the handle we threw away.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17807
2025-10-21 09:50:43 -07:00
Rob Norris
37d8d4619f zpool iostat: update pool counter when skipping boot row
When skipping the boot row (with -y), the early loop meant we weren't
updating the "last_npools" count. That means the count never advanced
past zero, so cb_iteration was always reset to 0, leading to it being
"stuck" on the boot line, printing the header and nothing else forever.

Updating the pool counter on every loop sorts that out: it advances,
cb_iteration moves properly, and normal rows are printed.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17807
2025-10-21 09:50:43 -07:00
Ameer Hamza
1585a10a85 Make mount/share errors non-fatal for zfs create/clone
If zfs_mount_and_share() fails, the error propagates to zfs create/clone
commands despite successful operation. If create/clone operations were
successful, there's no point in making zfs_mount_and_share() failures
fatal.

Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17799
2025-10-21 09:50:43 -07:00
Igor Ostapenko
b9d1e28a71 ddt prune: Add SCL_ZIO deadlock workaround
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Igor Kozhukhov <igor@dilos.org>
Signed-off-by: Igor Ostapenko <igor.ostapenko@klarasystems.com>
Closes #17793
2025-10-21 09:50:43 -07:00
Igor Ostapenko
01180a63bd spa_config: Rename spa_config_enter_mmp() to spa_config_enter_priority()
Originally this was created for MMP, but now new cases are emerging
where the same mechanism is required. Hence the name's generalization.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Igor Kozhukhov <igor@dilos.org>
Signed-off-by: Igor Ostapenko <igor.ostapenko@klarasystems.com>
Closes #17793
2025-10-21 09:50:43 -07:00
Robert Evans
ead0fb736d zinject: Introduce ready delay fault injection
This adds a pause to the ZIO pipeline in the ready stage for
matching I/O (data, dnode, or raw bookmark).

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Akash B <akash-b@hpe.com>
Signed-off-by: Robert Evans <evansr@google.com>
Closes #17787
2025-10-21 09:50:43 -07:00
Paul Dagnelie
073b34b3ee Fix display of default xattr to show 'sa'
When the default value of the xattr property was changed from 'dir' to
'sa', the code that displays the property's value was not affected. The
problem with this state of affairs is that 1) user tooling that
specifically looked for 'sa' before will be confused now that the code
displays 'on' instead. And 2) users may be confused when manually
running the commands about which specific type of xattr is in use unless
they are up to date on the latest zfs changes.

The fix here is to show the actual type always, rather than 'on' if we
happen to be using the default. This turns out to be easy to do, by
simply reordering the list of xattr values in the properties code. When
the property is displayed, we iterate down the table until we find a row
with a matching value, and use that row's name as the
display. Reordering the row fixes the display without affecting any
other code.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Closes #17801
2025-10-21 09:50:43 -07:00
Shreshth3
c0d63f5435 docs: fix a few small typos (#17804)
Signed-off-by: Shreshth Srivastava <shreshthsrivastava2@gmail.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
2025-10-21 09:50:43 -07:00
Brian Behlendorf
2f50d67409 Tag 2.4.0-rc2
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
2025-09-30 12:49:15 -07:00
nav1s
0939787e83 manuals: fix typos in zpool-upgrade man page
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Signed-off-by: nav1s <nav1s@proton.me>
Closes #17797
2025-09-29 16:50:57 -07:00
hoshinomori
f3295ec763 range_tree: drop duplicate zfs_ prefix from rs_set_fill_raw
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: hoshinomori <hoshinomori@owarisekai.moe>
Closes #17800
2025-09-29 16:50:53 -07:00
Rob Norris
35ec4b14ab zpool iostat: refresh pool list every interval
When running zpool iostat in interval mode, it would not notice any new
pools created or imported, and would forget any destroyed or exported,
so would not notice if they came back. This leads to outputting "no
pools available" every interval until killed.

It looks like this was at least intended to work; the comment above
zpool_do_iostat() indicates that it is expected to "deal with pool
creation/destruction" and that pool_list_update() would detect new
pools. That call however was removed in 3e43edd2c5, though its unclear
if that broke this behaviour and it wasn't noticed, or if it never
worked, or if something later broke it. That said, the lack of
pool_list_update() is only part of the reason it doesn't work properly.

The fundamental problem is that the various things involved in
refreshing or updating the list of pools would aggressively ignore,
remove, skip or fail on pools that stop existing, or that already exist.
Mostly this meant that once a pool is removed from the list, it will
never be seen again. Restoring pool_list_update() to the
zpool_do_iostat() loop only partially fixes this - it would find "new"
pools again, but only in the "all pools" (no args) mode, and because its
iterator callback add_pool() would abort the iterator if it already has
a pool listed, it would only add pools if there weren't any already.

So, this commit reworks the structure somewhat. pool_list_update()
becomes pool_list_refresh(), and will ensure the state of all pools in
the list are updated. In the "all pools" mode, it will also add new
pools and remove pools that disappear, but when a fixed list of pools is
used, the list doesn't change, only the state of the pools within it.

The rest of the commit is adjusting things for this much simpler
structure. Regardless of the mode in use, pool_list_refresh() will
always do the right thing, so the driver code can just get on with the
display.

Now that pools can appear and disappear, I've made it so the header (if
enabled) is re-printed when the list changes, so that its easier to see
what's happening if the column widths change.

Since this is all rather complicated, I've included tests for the "all
pools" and "set of pools" modes.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Igor Kozhukhov <igor@dilos.org>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17786
2025-09-29 16:50:49 -07:00
Tony Hutter
abda34b1c0 CI: Add ZTS -O option, log Setup Testing Machines step
Add a -O option to zfs-test.sh to dump debug information on test
timeout.  The debug info includes:

- 30 lines from 'top'
- /proc/<PID>/stack output of process with highest CPU usage
- Last lines strace-ing process with highest CPU usage
- /proc/sysrq-trigger kernel stack traces

All debug information gets dumped to /dev/kmsg (Linux only).

In addition, print out the VM console lines from the "Setup Testing
Machines" step.  We have often see VMs timeout at this step and don't
know why.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #17753
2025-09-29 16:50:46 -07:00
Tony Hutter
9079f986ae zvol: Fix blk-mq sync
The zvol blk-mq codepaths would erroneously send FLUSH and TRIM
commands down the read codepath, rather than write.  This fixes
the issue, and updates the zvol_misc_fua test to verify that
sync writes are actually happening.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Ameer Hamza <ahamza@ixsystems.com>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #17761
Closes #17765
2025-09-29 16:50:43 -07:00
Brian Behlendorf
a9bcf4faf3 CI: Switch FreeBSD 15 to 15.0-ALPHA3
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17795
2025-09-29 16:50:39 -07:00
Brian Behlendorf
ca9b89bd2d CI: Remove Buildbot references
The Buildbot CI infrastructure has been fully replaced by GitHub
Actions.  Remove any lingering references from the repository.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17794
2025-09-29 16:50:35 -07:00
Brian Behlendorf
654a2ccc74 Linux 6.17 compat: META
Update the META file to reflect compatibility with the 6.17
kernel.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17789
2025-09-26 12:16:17 -07:00
Brian Behlendorf
ddecc5ff21 CI: update perf and bpftools with the kernel packages
When updating a Fedora instance to an experimental kernel make sure
to include the matching versioned perf and bpftool packages.  This
helps ensure there are no unexpected conflicts which would prevent
the new packages from being installed.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17791
2025-09-26 12:16:14 -07:00
patrickxia
e1a6ec42d4 zdb: add ZFS_KEYFORMAT_RAW support for -K option
This change adds support for ZFS_KEYFORMAT_RAW to zdb_derive_key in 
zdb.c. The implementation reads the raw key from the file specified 
by the -K option which is consistent with how raw keys are handled in 
the other parts of ZFS, along with a check to ensure that the keyfile 
doesn't have too many bytes.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Patrick Xia <patrickx@google.com>
Closes #17783
2025-09-25 12:08:20 -07:00
Robert Evans
460858dfd6 dnode_next_offset: backtrack if lower level does not match
This changes the basic search algorithm from a single search up and down
the tree to a full depth-first traversal to handle conditions where the
tree matches at a higher level but not a lower level.

Normally higher level blocks always point to matching blocks, but there
are cases where this does not happen:

1. Racing block pointer updates from dbuf_write_ready.

   Before f664f1ee7f (#8946), both dbuf_write_ready and
   dnode_next_offset held dn_struct_rwlock which protected against
   pointer writes from concurrent syncs.

   This no longer applies, so sync context can f.e. clear or fill all
   L1->L0 BPs before the L2->L1 BP and higher BP's are updated.

   dnode_free_range in particular can reach this case and skip over L1
   blocks that need to be dirtied. Later, sync will panic in
   free_children when trying to clear a non-dirty indirect block.

   This case was found with ztest.

2. txg > 0, non-hole case. This is #11196.

   Freeing blocks/dnodes breaks the assumption that a match at a higher
   level implies a match at a lower level when filtering txg > 0.

   Whenever some but not all L0 blocks are freed, the parent L1 block is
   rewritten. Its updated L2->L1 BP reflects a newer birth txg.

   Later when searching by txg, if the L1 block matches since the txg is
   newer, it is possible that none of the remaining L1->L0 BPs match if
   none have been updated.

   The same behavior is possible with dnode search at L0.

   This is reachable from dsl_destroy_head for synchronous freeing.
   When this happens open context fails to free objects leaving sync
   context stuck freeing potentially many objects.

   This is also reachable from traverse_pool for extreme rewind where it
   is theoretically possible that datasets not dirtied after txg are
   skipped if the MOS has high enough indirection to trigger this case.

In both of these cases, without backtracking the search ends prematurely
as ESRCH result implies no more matches in the entire object.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Akash B <akash-b@hpe.com>
Signed-off-by: Robert Evans <evansr@google.com>
Closes #16025
Closes #11196
2025-09-25 12:08:17 -07:00
Brian Behlendorf
954fe5e1be Add interface to interface spa_get_worst_case_min_alloc() function
Provide an interface to retrieve the lowest and highest minimum
allocation size for the normal allocation class.  This can be used
by external consumers of the DMU to estimate potential wasted
capacity when setting the recordsize for an object.

The new "min_alloc" and "max_alloc" keys are added to the pool
configuration and used by default_volblocksize() to warn when
an ineffecient block size is requested.  For older kmods which
don't yet include the new keys fallback to the previous logic.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17758
2025-09-25 12:08:14 -07:00
Brian Behlendorf
d33d0cac5a Fix 'zpool add' safety check corner cases
Three cases were discovered where 'zpool add' would fail to
warn when adding vdevs to a pool with a mismatched replication
level.  These are:

  1. When a pool contains mixed file and disk vdevs.
  2. When a pool contains an active dRAID distributed spare
  3. When a pool contains an active hot spare

The lack of warnings are caused by get_replication() assessing
the current pool configuration an inconsistent and disabling
the mismatched replication check for the new pool configuration
after 'zpool add'.  This change updates get_replication() to
be slightly more tolerant in the non-fatal case.

The zpool_add_010_pos.ksh test case was split in to separate
tests: zpool_add_warn_create.ksh, pool_add_warn_degraded.ksh,
and zpool_add_warn_removal.  These test were extended to
include coverage for dRAID pools and the three scenarios
described above.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17780
2025-09-25 12:08:09 -07:00
Brian Behlendorf
9bd8f4379c ZTS: update upgrade_readonly_pool.ksh
Modify the test case to use the `zfs mount` command instead
of directly calling the mount command, create a dedicated dataset,
and use the default mount point.  These changes are intended to
preserve the intent of the original test case and resolve some
spurious mount failures which have been observed by the CI.

Reviewed-by: Igor Kozhukhov <igor@dilos.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17785
2025-09-25 12:08:06 -07:00
jozzsi
6dad2f61a3 contrib: dracut: install dependent kernel modules
Eliminates the need for the following workaround

> Add other drivers to dracut:

```
if grep mpt3sas /proc/modules; then
  echo 'force_drivers+=" mpt3sas "'  >> /etc/dracut.conf.d/zfs.conf
fi
if grep virtio_blk /proc/modules; then
  echo 'filesystems+=" virtio_blk "' >> /etc/dracut.conf.d/fs.conf
fi
```

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Jo Zzsi <jozzsicsataban@gmail.com>
Closes #17762
2025-09-25 12:08:02 -07:00
Alexander Motin
61a68554de zdb: Fix asize overflow in verify_livelist_allocs()
Spacemap entry might be too big to fit into a block pointer ashift.
We hit an assertion trying to run `zdb -bvy` on a large pool.  But
it seems the code does not really need size there, since we only
need to search for a range of offsets, so setting it to zero should
just make btree return position just before the first entry.  I
suspect the previous code could actually miss the first entry
due to this if its size was smaller.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Igor Kozhukhov <igor@dilos.org>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17764
2025-09-25 12:07:55 -07:00
trick2011
9bcda0b5fe Use "vdev" instead of "devices" when referring to vdevs
Update documentation to use the correct terminology.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: trick2011 <trick2011@users.noreply.github.com>
Closes #17734
Closes #17755
2025-09-25 12:07:52 -07:00
Tony Hutter
2380e0b679 ZTS: Fix stale symlinks with zfs-helpers.sh
zfs-helpers.sh is a utility script that sets up udev symlinks so you
can run ZTS from a local ZFS git workspace.  However, it doesn't check
that the udev symlinks point to the current workspace.  They may point
to an old workspace that has been deleted.  This means the udev rules
never get executed, which in turn causes the zvol tests to fail.

This commit removes old symlinks that do not point to the current
ZFS workspace.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #17766
2025-09-25 12:07:47 -07:00
jozzsi
83066c9627 contrib: dracut: always include zfs kernel module
This commit fixes the issue and includes the zfs kernel
module even when dracut is used in hostonly mode.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Jo Zzsi <jozzsicsataban@gmail.com>
Closes #17754
2025-09-25 12:07:43 -07:00
Alan Somers
ef9b7dde91 Fix a printf format specifier on FreeBSD/i386
This is breaking the build on FreeBSD/i386.  Originally committed
downstream as https://github.com/freebsd/freebsd-src/commit/2d76470b701

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by:	Alan Somers <asomers@gmail.com>
Sponsored by:	ConnectWise
Closes #17705
2025-09-17 16:34:24 -07:00
Alan Somers
9c6f72021d Fix atomic-alignment warnings in libspl on FreeBSD/i386
On i386, Clang complains about misaligned atomic operations.  Silence
these warnings to fix the build on FreeBSD/i386.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by:	Alan Somers <asomers@gmail.com>
Sponsored by:	ConnectWise
Closes #17708
2025-09-17 16:34:19 -07:00
Rob Norris
15a6b982c5 linux/super: add tunable to request immediate reclaim of unused dentries
Traditionally, unused dentries would be cached in the dentry cache until
the associated entry is no longer on disk. The cached dentry continues
to hold an inode reference, causing the inode to be pinned (see previous
commit).

Here we implement the dentry op d_delete, which is roughly analogous to
the drop_inode superblock op, and add a zfs_delete_dentry tunable to
control its behaviour. By default it continues the traditional
behaviour, but when the tunable is enabled, we signal that an unused
dentry should be freed immediately, releasing its inode reference, and
so allowing that inode to be deleted if no longer in use.

Sponsored-by: Klara, Inc.
Sponsored-by: Fastmail Pty Ltd
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17746
2025-09-17 16:34:14 -07:00
Rob Norris
42b9995f88 linux/super: add tunable to request immediate reclaim of unused inodes
Traditionally, unused inodes would be held on the superblock inode cache
until the associated on-disk file is removed or the kernel requests
reclaim.  On filesystems with millions of rarely-used files, this can be
a lot of unusable memory.

Here we implement the superblock drop_inode method, and add a
zfs_delete_inode tunable to control its behaviour. By default it
continues the traditional behaviour, but when the tunable is enabled, we
signal that the inode should be deleted immediately when the last
reference is dropped, rather than cached. This releases the associated
data to the dbuf cache and ARC, allowing them to be reclaimed normally.

Sponsored-by: Klara, Inc.
Sponsored-by: Fastmail Pty Ltd
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17746
2025-09-17 16:34:09 -07:00
buzzingwires
a056b3c341 Add typesets to zhack label repair test scripts
As a quality assurance measure, `typeset` is added to local variable
declarations to actually enforce their intended scope.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: buzzingwires <buzzingwires@outlook.com>
Closes #17732
2025-09-17 16:34:04 -07:00
buzzingwires
5f7253ca11 Refactor zhack label repair and fix -c regression on nonzero TXG
This commit fixes a likely regression introduced by 64db435 where the
checksum repair functionality (`-c` or default behavior) will perform
checks and access data associated with the newer undetach (`-u`)
functionality, resulting in a failure when an uberblock's TXG is not 0
as required by `-u` but not `-c`

Additionally, code is refactored for better separation of tasks.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: buzzingwires <buzzingwires@outlook.com>
Closes #17732
2025-09-17 16:33:59 -07:00
Rob Norris
e3eb3ca3dc man: add silent rules for mancheck
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17747
2025-09-17 16:33:52 -07:00
Rob Norris
d0084a4109 mancheck: allow single files
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17747
2025-09-17 16:33:48 -07:00
Rob Norris
4698208c78 Shellcheck.am: add silent rules for shellcheck and checkbashisms
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17747
2025-09-17 16:33:42 -07:00
Alexander Motin
406f76b7e3 CI: Switch FreeBSD 15 to 15.0-ALPHA2
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17749
2025-09-15 12:44:05 -07:00
Igor Ostapenko
1ca4cd8a33 Fix txg_log_time ZAP key typo
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Igor Ostapenko <igor.ostapenko@klarasystems.com>
Sponsored-by: Klara, Inc.
Closes #17748
2025-09-15 12:44:01 -07:00
Kyle Evans
8b548776ff zfsprops(7): attempt to clarify the keylocation description
The current description is somewhat difficult to parse through, and in
some cases is a little unclear as to the behavior.

Split it into a paragraphs based on the three distinct behaviors you
may get: prompt, file URL, HTTP(S) URL.  The descriptions of the file
and HTTP(s) behavior seems fine, but prompt is a little vague- expand
on it and make it clear that the behavior is actively based on whether
the inquisitor of key-data is provided with a tty for stdin or not.

Also clarify *why* one shouldn't "place keys which should be kept secret
on the command line" and note that you *have* to supply the key via
stdin if it's a raw key, just to be sure.

Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Closes #17742
2025-09-15 12:43:57 -07:00
Brian Behlendorf
a4cb155e8d ZTS: default to random data in fill_fs
Update the fill_fs helper function to request a random fill pattern
when the "data" argument isn't specified.  This ensures the default
behavior is to perform a more realistic fill of incompressible blocks.

Additionally, update a few test cases to specify a random fill.

Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17739
2025-09-15 12:43:52 -07:00
Brian Behlendorf
53c8d7071d ZTS: Fix zfs_send_delegation_user test
Correct the path in the common.run file.  The zfs_send_delegation_user
test is installed under cli_user not cli_root.

Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17740
2025-09-15 12:43:48 -07:00
Rob Norris
da33cfd436 vdev_disk_close: take disk write lock before destroying it
Many IO operations are submitted to the kernel async, and so the zio can
complete and followup actions before the submission call returns. If one
of the followup actions closes the disk (eg during pool create/import),
the initiator may be left holding a lock on the disk at destruction.

Instead, take the write lock before finishing up and decoupling the disk
state from the vdev proper. The caller will hold until all IO is
submitted and locks released.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17719
2025-09-15 12:43:44 -07:00
Alexander Motin
efdb4bf07a Fix two infinite loops if dmu_prefetch_max set to zero
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17692
Closes #17729
2025-09-15 12:43:39 -07:00
Paul Dagnelie
cac483dbd4 Fix time database update calculations
The time database update math assumed that the timestamps were in
nanoseconds, but at some point in the development or review process they
changed to seconds. This PR fixes the math to use seconds instead.
    
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Closes #17735
2025-09-15 12:43:34 -07:00
Brian Behlendorf
c9de42e089 ZTS: refreserv/refreserv_raidz improvements
Several small changes intended to make this test reliable.

- Leave the default compression enabled for the pool and switch
  to using /dev/urandom as the data source.  Functionally this
  shouldn't impact the test but it's preferable to test with
  the pool defaults when possible.

- Verify the device is created and removed as required.  Switch
  to a unique volume name for a more clarity in the logs.

- Use the ZVOL_DEVDIR to specify the device path.

- Speed up the test by creating the pool with an ashift=12 and
  testing 4K, 8K, 128K volblocksizes.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17725
2025-09-12 15:05:26 -07:00
Alexander Motin
41c6eaac8b Fix type in dbrrd_closest()
For ABS() to work, the argument must be signed, but rrdd_time is
uint64_t.  Clang noticed it.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Mariusz Zaborski <mariusz.zaborski@klarasystems.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Fixes #16853
Closes #17733
2025-09-12 15:05:22 -07:00
Alexander Motin
b5d41deca9 FreeBSD: Satisfy ASSERT_VOP_IN_SEQC()
zfs_aclset_common() might be called for newly created or not even
created vnodes, that triggers assertions on newer FreeBSD versions
with DEBUG_VFS_LOCKS included into INVARIANTS.  In the first case
make sure to call vn_seqc_write_begin()/_end(), in the second just
skip the assertion.

The similar has to be done for project management IOCTL and file-
bases extended attributes, since those are not going through VFS.

Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17722
2025-09-12 15:05:18 -07:00
Paul Dagnelie
2f41193a26 Make new zhack test a little more reliable
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Closes #17728
2025-09-12 15:05:14 -07:00
Chunwei Chen
95d677efde Fix ddle memleak in ddt_log_load
In ddt_log_load(), when removing dup entry from flushing tree, it doesn't
free the entry causing memleak.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Chunwei Chen <david.chen@nutanix.com>
Co-authored-by: Chunwei Chen <david.chen@nutanix.com>
Closes #17657
Closes #17730
2025-09-12 15:05:10 -07:00
JT Pennington
43a9d9ac57 Add send:encrypted test
Create tests for the new send:encrypted permission

Sponsored-by: Klara, Inc.
Sponsored-by: Karakun AG
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: JT Pennington <jt.pennington@klarasystems.com>
Closes #17543
2025-09-12 15:05:05 -07:00
Allan Jude
6c4ede4026 ZFS allow send:encrypted
A new `zfs allow` permissions that ONLY allows sending replication
streams in raw (encrypted) mode, so encrypted data will not be
decrypted as part of the replication process.

Sponsored-by: Klara, Inc.
Sponsored-by: Karakun AG
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Co-authored-by: JT Pennington <jt.pennington@klarasystems.com>
Signed-off-by: Allan Jude <allan@klarasystems.com>
Closes #17543
2025-09-12 15:05:02 -07:00
Tony Hutter
4a7a04630d zed: Add synchronous zedlets
Historically, ZED has blindly spawned off zedlets in parallel and never
worried about their completion order.  This means that you can
potentially have zedlets for event number 2 starting before zedlets for
event number 1 had finished.  Most of the time this is fine, and it
actually helps a lot when the system is getting spammed with hundreds
of events.

However, there are times when you want your zedlets to be executed
in sequence with the event ID.  That is where synchronous zedlets
come in.

ZED will wait for all previously spawned zedlets to finish before
running a synchronous zedlet.  Synchronous zedlets are guaranteed to be
the only zedlet running.  No other zedlets may run in parallel with a
synchronous zedlet.  Users should be careful to only use synchronous
zedlets when needed, since they decrease parallelism.

To make a zedlet synchronous, simply add a "-sync-" immediately
following the event name in the zedlet's file name:

	EVENT_NAME-sync-ZEDLETNAME.sh

For example, if you wanted a synchronous statechange script:

	statechange-sync-myzedlet.sh

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #17335
2025-09-11 15:58:59 -07:00
Brian Behlendorf
3dc345851c Prevent scrubbing a read-only pool
While it would be nice to be able to scrub a pool imported read-only
this will currently trip an ASSERT.  Before we can support this there
are some designs challenges which need to be thought through first.

For starters, a read-only import skips reading certain information 
from disk which it knows won't be needed, such as the space maps.
Furthermore, the scrub process expects to be checkpoint it's progress, 
update the on disk error log, and issue repair IO.  None of which 
would be possible when the pool is imported read-only.  

Each of these wrinkles can certainly be handled, but that will take 
some signifcant work.  In the meanwhile we disable the 'zpool scrub' 
command when the pool is imported read-only.

Reviewed-by: Alan Somers <asomers@gmail.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #17527
Closes #17717
2025-09-11 15:58:52 -07:00
Paul Dagnelie
df55ba7c49 Detect a slow raidz child during reads
A single slow responding disk can affect the overall read
performance of a raidz group.  When a raidz child disk is
determined to be a persistent slow outlier, then have it
sit out during reads for a period of time. The raidz group
can use parity to reconstruct the data that was skipped.

Each time a slow disk is placed into a sit out period, its
`vdev_stat.vs_slow_ios count` is incremented and a zevent
class `ereport.fs.zfs.delay` is posted.

The length of the sit out period can be changed using the
`raid_read_sit_out_secs` module parameter.  Setting it to
zero disables slow outlier detection.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Contributions-by: Don Brady <don.brady@klarasystems.com>
Contributions-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17227
2025-09-10 15:31:30 -07:00
Paul Dagnelie
0df85ec27c Remove RAIDZ reconstruct flags from debug defaults
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Closes #17227
2025-09-10 15:31:25 -07:00
Tony Hutter
123bfc32f3 ZTS: Print warning if running ZTS user_run test locally
Print a warning if you're attempting to run a ZTS test that calls
'user_run', and the ephemeral user doesn't have permissions to
access the test binaries.

This can happen if you're running ZTS from a local git repo.  In
that case the test user (say, 'testuser1') may need access to the
ZTS binaries in:

/home/<your_username>/zfs/tests/zfs-tests/bin/

... but 'testuser1' doesn't have permission to enter your home dir:

/home/<your_username>

The warning will help alert users to what is going on.  This will
not be an issue when ZTS is actually installed on the system
(via 'make install' or from packages).

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #17721
2025-09-10 15:01:42 -07:00
Alan Somers
177e9d07d0 Fix the build of crypto_test on LP32 architectures
test->id is a uint64_t, not a long.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by:	Alan Somers <asomers@gmail.com>
Sponsored by:	ConnectWise
Closes #17707
2025-09-10 15:01:37 -07:00
Paul Dagnelie
e2e708241a Enable zhack to work properly with 4k sector size disks
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Closes #17576
2025-09-10 15:01:32 -07:00
Paul Dagnelie
26983d6fa7 Add allocation profile export and zhack subcommand for import
When attempting to debug performance problems on large systems, one of
the major factors that affect performance is free space
fragmentation. This heavily affects the allocation process, which is an
area of active development in ZFS. Unfortunately, fragmenting a large
pool for testing purposes is time consuming; it usually involves filling
the pool and then repeatedly overwriting data until the free space
becomes fragmented, which can take many hours. And even if the time is
available, artificial workloads rarely generate the same fragmentation
patterns as the natural workloads they're attempting to mimic.

This patch has two parts. First, in zdb, we add the ability to export
the full allocation map of the pool. It iterates over each vdev,
printing every allocated segment in the ms_allocatable range tree. This
can be done while the pool is online, though in that case the allocation
map may actually be from several different TXGs as new ones are loaded
on demand.

The second is a new subcommand for zhack, zhack metaslab leak (and its
supporting kernel changes). This is a zhack subcommand that imports a
pool and then modified the range trees of the metaslabs, allowing the
sync process to write them out normall. It does not currently store
those allocations anywhere to make them reversible, and there is no
corresponding free subcommand (which would be extremely dangerous); this
is an irreversible process, only intended for performance testing. The
only way to reclaim the space afterwards is to destroy the pool or roll
back to a checkpoint.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Closes #17576
2025-09-10 15:01:28 -07:00
Shengqi Chen
ca4f7d6d49 contrib/debian: install files into merged /usr
This commit synchronizes the debian packaging files with the distro
version (also maintained by me) as much as possible.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Colm Buckley <colm@tuatha.org>
Signed-off-by: Shengqi Chen <harry-chen@outlook.com>
Closes #17712
2025-09-10 15:01:24 -07:00
Shengqi Chen
717c57c834 cmd: rename arcstat to zarcstat
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Colm Buckley <colm@tuatha.org>
Signed-off-by: Shengqi Chen <harry-chen@outlook.com>
Closes #16357
Closes #17712
2025-09-10 15:01:20 -07:00
Shengqi Chen
743866cd2a cmd: rename arc_summary to zarcsummary
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Colm Buckley <colm@tuatha.org>
Signed-off-by: Shengqi Chen <harry-chen@outlook.com>
Closes #16357
Closes #17712
2025-09-10 15:01:16 -07:00
Shengqi Chen
5bf1500ee3 Remove renaming notice and symlinks for arcstat and arc_summary
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Colm Buckley <colm@tuatha.org>
Signed-off-by: Shengqi Chen <harry-chen@outlook.com>
Closes #16357
Closes #17712
2025-09-10 15:01:12 -07:00
Rob Norris
dc53e5c484 linux/rw_destroy: assert no holders before destroying
While rw_destroy() may do nothing on Linux, we still want to make sure
that we don't have any holders outstanding like we do for mutexes.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17718
2025-09-10 15:01:02 -07:00
Rob Norris
0df91abe82 Linux 6.17: d_set_d_op() is no longer available
We only have extremely narrow uses, so move it all into a single
function that does only what we need, with and without d_set_d_op().

Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #17621
2025-09-09 17:06:55 -07:00
Rob Norris
d469371033 config: restore ZFS_AC_KERNEL_DENTRY tests
Accidentally removed calls in ed048fdc5b.

Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #17621
2025-09-09 17:06:52 -07:00
Tony Hutter
87e35bd3ab ZTS: Fix fault_limits timeouts
fault_limits would often hit the 10min timeout and be killed on Fedora
41-42.  Investigation showed that the 'fill_fs' portion of the test,
which would fill the pool with junk data before vdev replacement, was
writing highly compressible data (~126x), which would have taxed the
CPUs, potentially causing the timeout.

The fix is to write random data and reduce the number of writes.
This has an added benefit that more real data being is written to the
pool (~1GB) vs the old way (~300-400MB).  It also speeds up the test.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #17709
2025-09-09 17:06:48 -07:00
Alan Somers
cfd640c3e8 Fix warnings about sha2_is_supported on FreeBSD/i386
This is one problem currently preventing OpenZFS from building on
FreeBSD/i386.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by:	Alan Somers <asomers@gmail.com>
Sponsored by:	ConnectWise
Closes #17704
2025-09-09 17:06:40 -07:00
Alan Somers
b23eae62be Fix the build on 32-bit FreeBSD with GCC
GCC complains about casting a 64-bit integer to a 32-bit pointer.
Originally committed downstream as
https://github.com/freebsd/freebsd-src/commit/2d76470b701

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by:	Alan Somers <asomers@gmail.com>
Sponsored by:	ConnectWise
Closes #17706
2025-09-09 17:06:37 -07:00
rmacklem
b727163db9 zfs_vnops_os.c: Add support for the _PC_CLONE_BLKSIZE name
FreeBSD now has a pathconf name called _PC_CLONE_BLKSIZE
which is the block size supported for block cloning for
the file system.  Since ZFS's block size varies per file,
return the largest size likely to be used, or zero if block
cloning is not supported.

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Rick Macklem <rmacklem@uoguelph.ca>
Closes #17645
2025-09-09 17:06:33 -07:00
Rob Norris
02fa962af0 cmd: force zarcstat/zarc_summary recreation at install
If the target already exists, lt will fail. Force it to recreate the
symlinks.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17702
2025-09-09 17:06:29 -07:00
Chunwei Chen
c755aa486d Fix wrong dedup_table_size for legacy dedup
If we call ddt_log_load() for legacy ddt, we will end up going into
ddt_log_update_stats() and filling uninitialized value into ddo_dspace.
This value will then get added to dedup_table_size during
ddt_get_dedup_object_stats().

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17019
Closes #17699

Signed-off-by: Chunwei Chen <david.chen@nutanix.com>
Co-authored-by: Chunwei Chen <david.chen@nutanix.com>
2025-09-09 17:06:24 -07:00
Shengqi Chen
34ca2b8392 Install zarcstat and zarcsummary in deb / rpm build rules
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Shengqi Chen <harry-chen@outlook.com>
Closes #16357
Closes #17695
2025-09-09 17:06:13 -07:00
Shengqi Chen
f8e2152db7 Install zarcstat and zarcsummary symlinks in Makefile
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Shengqi Chen <harry-chen@outlook.com>
Closes #16357
Closes #17695
2025-09-09 17:05:30 -07:00
Shengqi Chen
cbc6d57012 Add upcoming renaming notice for arc_summary and arcstat
They will become zarcsummary and zarcstat in 2.4.0.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Shengqi Chen <harry-chen@outlook.com>
Closes #16357
Closes #17695
2025-09-09 17:05:26 -07:00
Shengqi Chen
e5132a3382 ci: fix syntax issues in zfs-qemu.yml
Otherwise it might become `if [ == "" ]` which is ill-formed.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Shengqi Chen <harry-chen@outlook.com>
Closes #17695
2025-09-09 17:05:21 -07:00
Shengqi Chen
b5b6deb985 ci: use real head sha instead of GITHUB_SHA when generating CI type
Because GitHub creates a merge commit on top of real head, so the check
on HEAD will fail regardlessly.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Shengqi Chen <harry-chen@outlook.com>
Closes #17695
2025-09-09 17:05:17 -07:00
Maksym Shkolnyi
886f29e1f6 config: Add warning if ARCH environment variable is set
If ARCH environment variable is set it can cause the failure of the
kernel modules check during the configure step. The resulting error
will be confusing, and may looks like this:

>    checking for kernel config option compatibility... done
>    checking whether CONFIG_MODULES is defined... no
>    configure: error:
>        *** This kernel does not include the required loadable module
>        *** support!

Detect when ARCH is print a warning.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Maksym Shkolnyi <maksym.shkolnyi@workato.com>
Closes #17680
2025-09-09 17:04:39 -07:00
Rob Norris
56e8ab4a3e zvol: reject suspend attempts when zvol is shutting down
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17690
2025-09-09 17:04:32 -07:00
Brian Behlendorf
24baccb75e config: Fix LLVM-21 -Wuninitialized-const-pointer warning
LLVM-21 enables -Wuninitialized-const-pointer which results in the
following compiler warning and the bdev_file_open_by_path() interface
not being detected for 6.9 and newer kernels.  The blk_holder_ops
are not used by the ZFS code so we can safely use a NULL argument
for this check.

    bdev_file_open_by_path/bdev_file_open_by_path.c:110:54: error:
    variable 'h' is uninitialized when passed as a const pointer
    argument here [-Werror,-Wuninitialized-const-pointer]

Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #17682
Closes #17684
2025-09-09 17:04:24 -07:00
Alexander Ziaee
92d4b135b6 manuals: Audit/bump dates for last content change
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Ziaee <ziaee@FreeBSD.org>
Closes #17676
2025-09-09 17:04:19 -07:00
classabbyamp
31b9646681 linux: use sys/stat.h instead of linux/stat.h
glibc includes linux/stat.h for statx, but musl defines its own statx
struct and associated constants, which does not include STATX_MNT_ID
yet. Thus, including linux/stat.h directly should be avoided for
maximum libc compatibility.

Tested on:
  - glibc: x86_64, i686, aarch64, armv7l, armv6l
  - musl: x86_64, aarch64, armv7l, armv6l

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Tested-By: Achill Gilgenast <achill@achill.org>
Signed-off-by: classabbyamp <dev@placeviolette.net>
Closes #17675
2025-09-09 17:04:15 -07:00
Eric A. Borisch
04d991dbc4 Update pam_zfs_key.c defaultt path for FreeBSD
As described in https://github.com/freebsd/freebsd-src/pull/1305,
FreeBSD's installer defaults to zroot/home for user home directories.

For FreeBSD only, set the default prefix for pam_zfs_key to match.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Eric A. Borisch <eborisch@gmail.com>
Closes #17600
2025-09-09 17:04:06 -07:00
ofthesun9
5846a85155 Update compatibility.d files
Add an openzfs-2.4 compatibility file for the next release.

While there are no compatibility difference between Linux and
FreeBSD for 2.4 symlinks for the -linux and -freebsd names are
created for any scripts expecting that convention.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: ofthesun9 <olivier@ofthesun.net>
Closes #17672
Closes #17673
2025-09-09 17:04:01 -07:00
Shawn Bayern
8604e67dc9 Add description of default sorting behavior to zfs_list.8
The sorting logic is all in cmd/zfs/zfs_iter.c.  I borrowed
where I could from the comments in the source code, but please
note that the comment to zfs_sort() is a little imprecise, or at
least incomplete, because it doesn't give any indication of the
chronological sort that will be used by default for snapshots in
zfs_compare().

While adding this description, I took the liberty to copy-edit
the rest of the file lightly.

In those edits, I've removed "If specified, you can list
property information by the absolute pathname or the relative
pathname" because, in context, it seems more confusing than
helpful.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Shawn Bayern <sbayern@law.fsu.edu>
Closes #15713
Closes #15869
2025-09-09 17:03:55 -07:00
Ivan Shapovalov
c00c3e33bb config: add and use KERNEL_CC check for -Wno-format-zero-length
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Closes #16997
2025-09-09 17:03:49 -07:00
Ivan Shapovalov
92579489e0 config: cleanup KERNEL_CC checks, fix broken status output
If $KERNEL_CC was not defined, configure status output would print an
empty string where the kernel compiler should have been. Fix this and
simplify the code generally.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Closes #16997
2025-09-09 17:03:44 -07:00
Tony Hutter
c539d6f211 ZTS: add mount_loopback to test zfs behind loop dev
Add a test case to reproduce issue #17277:

1. Make a pool
2. Write a file to the pool
3. Mount the file as a loopback device
4. Make an XFS filesystem on the loopback device
5. Mount the XFS filesystem... <hangs>

Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Issue #17277
Closes #17329
2025-09-09 17:03:36 -07:00
Mark Johnston
2fc6bf82b6 zdb: Fix format strings on 32-bit systems
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Mark Johnston <markj@FreeBSD.org>
Closes #17665
2025-09-09 17:03:31 -07:00
youzhongyang
774a34f3ff Synchronize the update of feature refcount
The concurrent execution of feature_sync() can lead to a panic due 
to an unprotected update of the feature refcount.  Resolve this by
using the spa->spa_feat_stats_lock to synchronize the update of the 
refcount.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Youzhong Yang <yyang@mathworks.com>
Closes #17184
Closes #17632
2025-09-09 17:03:27 -07:00
Cong Zhang
e3392a5e7d Prompt user to unlock when login from dropbear
Update the zfsunlock initramfs hook to provide instructions on how
to unlock the root filesystem when appropriate.  The intent is to
make the dropbear ssh MOTD more user friendly.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Signed-off-by: Cong Zhang <13283869+congzhangzh@users.noreply.github.com>
Closes #17661
Closes #17662
2025-09-09 17:03:22 -07:00
732 changed files with 23331 additions and 45624 deletions

View File

@ -3,16 +3,13 @@
"""
Determine the CI type based on the change list and commit message.
Output format: "<type> <source>" where source is "manual" (from
ZFS-CI-Type commit tag) or "auto" (from file change heuristics).
Prints "quick manual" if:
Prints "quick" if (explicity required by user):
- the *last* commit message contains 'ZFS-CI-Type: quick'
or "quick auto" if (heuristics):
or 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 auto" (or "<type> manual" if explicitly requested).
Otherwise prints "full".
"""
import sys
@ -61,10 +58,9 @@ if __name__ == '__main__':
head, base = sys.argv[1:3]
def output_type(type, source, reason):
print(f'{prog}: will run {type} CI ({source}): {reason}',
file=sys.stderr)
print(f'{type} {source}')
def output_type(type, reason):
print(f'{prog}: will run {type} CI: {reason}', file=sys.stderr)
print(type)
sys.exit(0)
# check last (HEAD) commit message
@ -74,8 +70,7 @@ if __name__ == '__main__':
for line in last_commit_message_raw.stdout.decode().splitlines():
if line.strip().lower() == 'zfs-ci-type: quick':
output_type('quick', 'manual',
f'requested by HEAD commit {head}')
output_type('quick', f'requested by HEAD commit {head}')
# check all commit messages
all_commit_message_raw = subprocess.run([
@ -89,14 +84,11 @@ if __name__ == '__main__':
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', 'manual',
f'requested by commit {commit_ref}')
output_type('freebsd', f'requested by commit {commit_ref}')
if line.strip().lower() == 'zfs-ci-type: linux':
output_type('linux', 'manual',
f'requested by commit {commit_ref}')
output_type('linux', f'requested by commit {commit_ref}')
if line.strip().lower() == 'zfs-ci-type: full':
output_type('full', 'manual',
f'requested by commit {commit_ref}')
output_type('full', f'requested by commit {commit_ref}')
# check changed files
changed_files_raw = subprocess.run([
@ -112,10 +104,9 @@ if __name__ == '__main__':
for r in FULL_RUN_REGEX:
if r.match(f):
output_type(
'full', 'auto',
'full',
f'changed file "{f}" matches pattern "{r.pattern}"'
)
# catch-all
output_type('quick', 'auto',
'no changed file matches full CI patterns')
output_type('quick', 'no changed file matches full CI patterns')

View File

@ -6,20 +6,6 @@
set -eu
# The default 'azure.archive.ubuntu.com' mirrors can be really slow.
# Prioritize the official Ubuntu mirrors.
#
# The normal apt-mirrors.txt will look like:
#
# http://azure.archive.ubuntu.com/ubuntu/ priority:1
# https://archive.ubuntu.com/ubuntu/ priority:2
# https://security.ubuntu.com/ubuntu/ priority:3
#
# Just delete the 'azure.archive.ubuntu.com' line.
sudo sed -i '/azure.archive.ubuntu.com/d' /etc/apt/apt-mirrors.txt
echo "Using mirrors:"
cat /etc/apt/apt-mirrors.txt
# install needed packages
export DEBIAN_FRONTEND="noninteractive"
sudo apt-get -y update
@ -34,89 +20,35 @@ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -q -N ""
sudo systemctl stop docker.socket
sudo systemctl stop multipathd.socket
sudo swapoff -a
# Special case:
#
# For reasons unknown, the runner can boot-up with two different block device
# 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 ---
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sda 8:0 0 150G 0 disk
# ├─sda1 8:1 0 149G 0 part /
# ├─sda14 8:14 0 4M 0 part
# ├─sda15 8:15 0 106M 0 part /boot/efi
# └─sda16 259:0 0 913M 0 part /boot
#
# lrwxrwxrwx 1 root root 9 Jan 29 18:07 azure_root -> ../../sda
# lrwxrwxrwx 1 root root 10 Jan 29 18:07 azure_root-part1 -> ../../sda1
# lrwxrwxrwx 1 root root 11 Jan 29 18:07 azure_root-part14 -> ../../sda14
# 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 ---
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sda 8:0 0 75G 0 disk
# ├─sda1 8:1 0 74G 0 part /
# ├─sda14 8:14 0 4M 0 part
# ├─sda15 8:15 0 106M 0 part /boot/efi
# └─sda16 259:0 0 913M 0 part /boot
# sdb 8:16 0 75G 0 disk
# └─sdb1 8:17 0 75G 0 part
#
# lrwxrwxrwx 1 root root 9 Jan 29 18:07 azure_resource -> ../../sdb
# lrwxrwxrwx 1 root root 10 Jan 29 18:07 azure_resource-part1 -> ../../sdb1
# lrwxrwxrwx 1 root root 9 Jan 29 18:07 azure_root -> ../../sda
# lrwxrwxrwx 1 root root 10 Jan 29 18:07 azure_root-part1 -> ../../sda1
# lrwxrwxrwx 1 root root 11 Jan 29 18:07 azure_root-part14 -> ../../sda14
# lrwxrwxrwx 1 root root 11 Jan 29 18:07 azure_root-part15 -> ../../sda15
#
# If we have the azure_resource-part1 partition, umount it, partition it, and
# use it as our ZFS disk and swap partition. If not, just create a file VDEV
# and swap file and use that instead.
# remove default swapfile and /mnt
if [ -e /dev/disk/cloud/azure_resource-part1 ] ; then
sudo umount -l /mnt
DISK="/dev/disk/cloud/azure_resource-part1"
sudo sed -e "s|^$DISK.*||g" -i /etc/fstab
sudo wipefs -aq $DISK
sudo systemctl daemon-reload
fi
sudo swapoff -a
sudo umount -l /mnt
DISK="/dev/disk/cloud/azure_resource-part1"
sudo sed -e "s|^$DISK.*||g" -i /etc/fstab
sudo wipefs -aq $DISK
sudo systemctl daemon-reload
sudo modprobe loop
sudo modprobe zfs
if [ -e /dev/disk/cloud/azure_resource-part1 ] ; then
echo "We have two 75GB block devices"
# partition the disk as needed
DISK="/dev/disk/cloud/azure_resource"
sudo sgdisk --zap-all $DISK
sudo sgdisk -p \
# partition the disk as needed
DISK="/dev/disk/cloud/azure_resource"
sudo sgdisk --zap-all $DISK
sudo sgdisk -p \
-n 1:0:+16G -c 1:"swap" \
-n 2:0:0 -c 2:"tests" \
$DISK
sync
sleep 1
sudo fallocate -l 12G /test.ssd2
DISKS="$DISK-part2 /test.ssd2"
SWAP=$DISK-part1
else
echo "We have a single 150GB block device"
sudo fallocate -l 72G /test.ssd2
SWAP=/swapfile.ssd
sudo fallocate -l 16G $SWAP
sudo chmod 600 $SWAP
DISKS="/test.ssd2"
fi
$DISK
sync
sleep 1
# swap with same size as RAM (16GiB)
sudo mkswap $SWAP
sudo swapon $SWAP
sudo mkswap $DISK-part1
sudo swapon $DISK-part1
# JBOD 2xdisk for OpenZFS storage (test vm's)
SSD1="$DISK-part2"
sudo fallocate -l 12G /test.ssd2
SSD2=$(sudo losetup -b 4096 -f /test.ssd2 --show)
# adjust zfs module parameter and create pool
exec 1>/dev/null
@ -125,7 +57,7 @@ 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
sudo zpool create -f -o ashift=12 zpool $DISKS -O relatime=off \
sudo zpool create -f -o ashift=12 zpool $SSD1 $SSD2 -O relatime=off \
-O atime=off -O xattr=sa -O compression=lz4 -O sync=disabled \
-O redundant_metadata=none -O mountpoint=/mnt/tests

View File

@ -43,12 +43,6 @@ case "$OS" in
OSv="almalinux9"
URL="https://repo.almalinux.org/almalinux/10/cloud/x86_64/images/AlmaLinux-10-GenericCloud-latest.x86_64.qcow2"
;;
alpine3-23)
OSNAME="Alpine Linux 3.23.2"
# Alpine Linux v3.22 and v3.23 are unknown to osinfo as of 2025-12-26.
OSv="alpinelinux3.21"
URL="https://dl-cdn.alpinelinux.org/alpine/v3.23/releases/cloud/generic_alpine-3.23.2-x86_64-bios-cloudinit-r0.qcow2"
;;
archlinux)
OSNAME="Archlinux"
URL="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"
@ -78,6 +72,11 @@ 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"
@ -96,8 +95,15 @@ case "$OS" in
KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
NIC="rtl8139"
;;
freebsd14-4r)
FreeBSD="14.4-RELEASE"
freebsd14-2r)
FreeBSD="14.2-RELEASE"
OSNAME="FreeBSD $FreeBSD"
OSv="freebsd14.0"
URLxz="$FREEBSD_REL/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI.raw.xz"
KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
;;
freebsd14-3r)
FreeBSD="14.3-RELEASE"
OSNAME="FreeBSD $FreeBSD"
OSv="freebsd14.0"
URLxz="$FREEBSD_REL/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI.raw.xz"
@ -111,8 +117,8 @@ case "$OS" in
KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz"
NIC="rtl8139"
;;
freebsd14-4s)
FreeBSD="14.4-STABLE"
freebsd14-3s)
FreeBSD="14.3-STABLE"
OSNAME="FreeBSD $FreeBSD"
OSv="freebsd14.0"
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
@ -217,21 +223,13 @@ if [ ${OS:0:7} != "freebsd" ]; then
hostname: $OS
users:
- name: root
shell: /bin/bash
sudo: ['ALL=(ALL) NOPASSWD:ALL']
- name: zfs
shell: /bin/bash
sudo: ['ALL=(ALL) NOPASSWD:ALL']
- name: root
shell: $BASH
- name: zfs
sudo: ALL=(ALL) NOPASSWD:ALL
shell: $BASH
ssh_authorized_keys:
- $PUBKEY
# Workaround for Alpine Linux.
lock_passwd: false
passwd: '*'
packages:
- sudo
- bash
growpart:
mode: auto
@ -314,23 +312,3 @@ else
scp ~/src.txz "root@vm0:/tmp/src.txz"
ssh root@vm0 'tar -C / -zxf /tmp/src.txz'
fi
#
# Config for Alpine Linux similar to FreeBSD.
#
if [ ${OS:0:6} == "alpine" ]; then
while pidof /usr/bin/qemu-system-x86_64 >/dev/null; do
ssh 2>/dev/null zfs@vm0 "uname -a" && break
done
# Enable community and testing repositories.
ssh zfs@vm0 "sudo rm -rf /etc/apk/repositories"
ssh zfs@vm0 "sudo setup-apkrepos -c1"
ssh zfs@vm0 "echo '@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing' | sudo tee -a /etc/apk/repositories"
# Upgrade to edge or latest-stable.
#ssh zfs@vm0 "sudo sed -i 's#/v[0-9]\+\.[0-9]\+/#/edge/#g' /etc/apk/repositories"
#ssh zfs@vm0 "sudo sed -i 's#/v[0-9]\+\.[0-9]\+/#/latest-stable/#g' /etc/apk/repositories"
# Update and upgrade after repository setup.
ssh zfs@vm0 "sudo apk update"
ssh zfs@vm0 "sudo apk add --upgrade apk-tools"
ssh zfs@vm0 "sudo apk upgrade --available"
fi

View File

@ -3,42 +3,13 @@
######################################################################
# 3) install dependencies for compiling and loading
#
# 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
# $1: OS name (like 'fedora41')
# $2: (optional) Experimental Fedora kernel version, like "6.14" to
# install instead of Fedora defaults.
######################################################################
set -eu
function alpine() {
echo "##[group]Install Development Tools"
sudo apk add \
acl alpine-sdk attr autoconf automake bash build-base clang21 coreutils \
cpio cryptsetup curl curl-dev dhcpcd eudev eudev-dev eudev-libs findutils \
fio gawk gdb gettext-dev git grep jq libaio libaio-dev libcurl \
libtirpc-dev libtool libunwind libunwind-dev linux-headers linux-tools \
linux-virt linux-virt-dev lsscsi m4 make nfs-utils openssl-dev parted \
pax procps py3-cffi py3-distlib py3-packaging py3-setuptools python3 \
python3-dev qemu-guest-agent rng-tools rsync samba samba-server sed \
strace sysstat util-linux util-linux-dev wget words xfsprogs xxhash \
zlib-dev pamtester@testing
echo "##[endgroup]"
echo "##[group]Switch to eudev"
sudo setup-devd udev
echo "##[endgroup]"
echo "##[group]Install ksh93 from Source"
git clone --depth 1 https://github.com/ksh93/ksh.git /tmp/ksh
cd /tmp/ksh
./bin/package make
sudo ./bin/package install /
echo "##[endgroup]"
}
function archlinux() {
echo "##[group]Running pacman -Syu"
sudo btrfs filesystem resize max /
@ -56,10 +27,6 @@ function archlinux() {
function debian() {
export DEBIAN_FRONTEND="noninteractive"
echo "##[group]Wait for cloud-init to finish"
cloud-init status --wait
echo "##[endgroup]"
echo "##[group]Running apt-get update+upgrade"
sudo sed -i '/[[:alpha:]]-backports/d' /etc/apt/sources.list
sudo apt-get update -y
@ -123,11 +90,6 @@ function rhel() {
kernel-devel python3-setuptools qemu-guest-agent rng-tools rpcgen \
rpm-build rsync samba strace sysstat systemd watchdog wget xfsprogs-devel \
xxhash zlib-devel
# These are needed for building Lustre. We only install these on EL VMs since
# we don't plan to test build Lustre on other platforms.
sudo dnf install -y libnl3-devel libyaml-devel libmount-devel
echo "##[endgroup]"
}
@ -156,12 +118,6 @@ 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)
@ -184,9 +140,6 @@ case "$1" in
sudo dnf install -y kernel-abi-stablelists
echo "##[endgroup]"
;;
alpine*)
alpine
;;
archlinux)
archlinux
;;
@ -221,11 +174,6 @@ 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
@ -240,16 +188,6 @@ test -z "${ONLY_DEPS:-}" || exit 0
# Start services
echo "##[group]Enable services"
case "$1" in
alpine*)
sudo -E rc-update add qemu-guest-agent
sudo -E rc-update add nfs
sudo -E rc-update add samba
sudo -E rc-update add dhcpcd
# Remove services related to cloud-init.
sudo -E rc-update del cloud-init default
sudo -E rc-update del cloud-final default
sudo -E rc-update del cloud-config default
;;
freebsd*)
# add virtio things
echo 'virtio_load="YES"' | sudo -E tee -a /boot/loader.conf
@ -305,7 +243,7 @@ case "$1" in
esac
case "$1" in
alpine*|archlinux|freebsd*)
archlinux|freebsd*)
true
;;
*)
@ -320,7 +258,5 @@ esac
# reset cloud-init configuration and poweroff
sudo cloud-init clean --logs
if [ "$POWEROFF" == "1" ] ; then
sleep 2 && sudo poweroff &
fi
sleep 2 && sudo poweroff &
exit 0

View File

@ -350,16 +350,7 @@ fi
# save some sysinfo
uname -a > /var/tmp/uname.txt
# 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
cd $HOME/zfs
export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"
extra=""

View File

@ -58,21 +58,13 @@ for ((i=1; i<=VMs; i++)); do
fqdn: vm$i
users:
- name: root
shell: /bin/bash
sudo: ['ALL=(ALL) NOPASSWD:ALL']
- name: zfs
shell: /bin/bash
sudo: ['ALL=(ALL) NOPASSWD:ALL']
- name: root
shell: $BASH
- name: zfs
sudo: ALL=(ALL) NOPASSWD:ALL
shell: $BASH
ssh_authorized_keys:
- $PUBKEY
# Workaround for Alpine Linux.
lock_passwd: false
passwd: '*'
packages:
- sudo
- bash
growpart:
mode: auto

View File

@ -1,51 +0,0 @@
#!/usr/bin/env bash
######################################################################
# 6) Test if Lustre can still build against ZFS
######################################################################
set -e
# Build from the latest Lustre tag rather than the master branch. We do this
# under the assumption that master is going to have a lot of churn thus will be
# more prone to breaking the build than a point release. We don't want ZFS
# PR's reporting bad test results simply because upstream Lustre accidentally
# broke their build.
#
# Skip any RC tags, or any tags where the last version digit is 50 or more.
# Versions with 50 or more are development versions of Lustre.
repo=https://github.com/lustre/lustre-release.git
tag="$(git ls-remote --refs --exit-code --sort=version:refname --tags $repo | \
awk -F '_' '/-RC/{next}; /refs\/tags\/v/{if ($NF < 50){print}}' | \
tail -n 1 | sed 's/.*\///')"
echo "Cloning Lustre tag $tag"
git clone --depth 1 --branch "$tag" "$repo"
cd lustre-release
# Include Lustre patches to build against master/zfs-2.4.x. Once these
# patches are merged we can remove these lines.
patches=('https://review.whamcloud.com/changes/fs%2Flustre-release~62101/revisions/2/patch?download'
'https://review.whamcloud.com/changes/fs%2Flustre-release~63267/revisions/9/patch?download')
for p in "${patches[@]}" ; do
curl $p | base64 -d > patch
patch -p1 < patch || true
done
echo "Configure Lustre"
./autogen.sh
# EL 9 needs '--disable-gss-keyring'
./configure --with-zfs --disable-gss-keyring
echo "Building Lustre RPMs"
make rpms
ls *.rpm
# There's only a handful of Lustre RPMs we actually need to install
lustrerpms="$(ls *.rpm | grep -E 'kmod-lustre-osd-zfs-[0-9]|kmod-lustre-[0-9]|lustre-osd-zfs-mount-[0-9]')"
echo "Installing: $lustrerpms"
sudo dnf -y install $lustrerpms
sudo modprobe -v lustre
# Should see some Lustre lines in dmesg
sudo dmesg | grep -Ei 'lnet|lustre'

View File

@ -4,10 +4,7 @@
# 6) load openzfs module and run the tests
#
# called on runner: qemu-6-tests.sh
# called on qemu-vm: qemu-6-tests.sh $OS $2 $3 [--lustre|--builtin] [quick|default]
#
# --lustre: Test build lustre in addition to the normal tests
# --builtin: Test build ZFS as a kernel built-in in addition to the normal tests
# called on qemu-vm: qemu-6-tests.sh $OS $2/$3
######################################################################
set -eu
@ -41,54 +38,6 @@ function prefix() {
fi
}
function do_lustre_build() {
local rc=0
$HOME/zfs/.github/workflows/scripts/qemu-6-lustre-tests-vm.sh &> /var/tmp/lustre.txt || rc=$?
echo "$rc" > /var/tmp/lustre-exitcode.txt
if [ "$rc" != "0" ] ; then
echo "$rc" > /var/tmp/tests-exitcode.txt
fi
}
export -f do_lustre_build
# Test build ZFS into the kernel directly
function do_builtin_build() {
local rc=0
# Get currently full kernel version (like '6.18.8')
fullver=$(uname -r | grep -Eo '^[0-9]+\.[0-9]+\.[0-9]+')
# Get just the major ('6')
major=$(echo $fullver | grep -Eo '^[0-9]+')
(
set -e
wget https://cdn.kernel.org/pub/linux/kernel/v${major}.x/linux-$fullver.tar.xz
tar -xf $HOME/linux-$fullver.tar.xz
cd $HOME/linux-$fullver
make tinyconfig
./scripts/config --enable EFI_PARTITON
./scripts/config --enable BLOCK
# BTRFS_FS is easiest config option to enable CONFIG_ZLIB_INFLATE|DEFLATE
./scripts/config --enable BTRFS_FS
yes "" | make oldconfig
make prepare
cd $HOME/zfs
./configure --with-linux=$HOME/linux-$fullver --enable-linux-builtin --enable-debug
./copy-builtin $HOME/linux-$fullver
cd $HOME/linux-$fullver
./scripts/config --enable ZFS
yes "" | make oldconfig
make -j `nproc`
) &> /var/tmp/builtin.txt || rc=$?
echo "$rc" > /var/tmp/builtin-exitcode.txt
if [ "$rc" != "0" ] ; then
echo "$rc" > /var/tmp/tests-exitcode.txt
fi
}
export -f do_builtin_build
# called directly on the runner
if [ -z ${1:-} ]; then
cd "/var/tmp"
@ -100,24 +49,8 @@ if [ -z ${1:-} ]; then
for ((i=1; i<=VMs; i++)); do
IP="192.168.122.1$i"
# We do an additional test build of Lustre against ZFS if we're vm2
# on almalinux*. At the time of writing, the vm2 tests were
# completing roughly 15min before the vm1 tests, so it makes sense
# to have vm2 do the build.
#
# In addition, we do an additional test build of ZFS as a Linux
# kernel built-in on Fedora. Again, we do it on vm2 to exploit vm2's
# early finish time.
extra=""
if [[ "$OS" == almalinux* ]] && [[ "$i" == "2" ]] ; then
extra="--lustre"
elif [[ "$OS" == fedora* ]] && [[ "$i" == "2" ]] ; then
extra="--builtin"
fi
daemonize -c /var/tmp -p vm${i}.pid -o vm${i}log.txt -- \
$SSH zfs@$IP $TESTS $OS $i $VMs $extra $CI_TYPE
$SSH zfs@$IP $TESTS $OS $i $VMs $CI_TYPE
# handly line by line and add info prefix
stdbuf -oL tail -fq vm${i}log.txt \
| while read -r line; do prefix "$i" "$line"; done &
@ -137,35 +70,9 @@ if [ -z ${1:-} ]; then
exit 0
fi
#############################################
# Everything from here on runs inside qemu vm
#############################################
# Process cmd line args
OS="$1"
shift
NUM="$1"
shift
DEN="$1"
shift
BUILD_LUSTRE=0
BUILD_BUILTIN=0
if [ "$1" == "--lustre" ] ; then
BUILD_LUSTRE=1
shift
elif [ "$1" == "--builtin" ] ; then
BUILD_BUILTIN=1
shift
fi
if [ "$1" == "quick" ] ; then
export RUNFILES="sanity.run"
fi
# this part runs inside qemu vm
export PATH="$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/bin"
case "$OS" in
case "$1" in
freebsd*)
TDIR="/usr/local/share/zfs"
sudo kldstat -n zfs 2>/dev/null && sudo kldunload zfs
@ -188,42 +95,23 @@ case "$OS" in
;;
esac
# Distribution-specific settings.
case "$OS" in
# enable io_uring on el9/el10
case "$1" in
almalinux9|almalinux10|centos-stream*)
# Enable io_uring on Enterprise Linux 9 and 10.
sudo sysctl kernel.io_uring_disabled=0 > /dev/null
;;
alpine*)
# Ensure `/etc/zfs/zpool.cache` exists.
sudo mkdir -p /etc/zfs
sudo touch /etc/zfs/zpool.cache
sudo chmod 644 /etc/zfs/zpool.cache
;;
esac
# Lustre calls a number of exported ZFS module symbols. To make sure we don't
# change the symbols and break Lustre, do a quick Lustre build of the latest
# released Lustre against ZFS.
#
# Note that we do the Lustre test build in parallel with ZTS. ZTS isn't very
# CPU intensive, so we can use idle CPU cycles "guilt free" for the build.
# The Lustre build on its own takes ~15min.
if [ "$BUILD_LUSTRE" == "1" ] ; then
do_lustre_build &
elif [ "$BUILD_BUILTIN" == "1" ] ; then
# Try building ZFS directly into the Linux kernel (not as a module)
do_builtin_build &
fi
# run functional testings and save exitcode
cd /var/tmp
TAGS=$NUM/$DEN
TAGS=$2/$3
if [ "$4" == "quick" ]; then
export RUNFILES="sanity.run"
fi
sudo dmesg -c > dmesg-prerun.txt
mount > mount.txt
df -h > df-prerun.txt
$TDIR/zfs-tests.sh -vKO -s 3GB -T $TAGS
RV=$?
df -h > df-postrun.txt
echo $RV > tests-exitcode.txt

View File

@ -31,12 +31,6 @@ EOF
rm -f tmp$$
}
function showfile_tail() {
echo "##[group]$2 (final lines)"
tail -n 80 $1
echo "##[endgroup]"
}
# overview
cat /tmp/summary.txt
echo ""
@ -52,32 +46,6 @@ fi
echo -e "\nFull logs for download:\n $1\n"
for ((i=1; i<=VMs; i++)); do
# Print Lustre build test results (the build is only done on vm2)
if [ -f vm$i/lustre-exitcode.txt ] ; then
rv=$(< vm$i/lustre-exitcode.txt)
if [ $rv = 0 ]; then
vm="vm$i"
else
vm="vm$i"
touch /tmp/have_failed_tests
fi
file="vm$i/lustre.txt"
test -s "$file" && showfile_tail "$file" "$vm: Lustre build"
fi
if [ -f vm$i/builtin-exitcode.txt ] ; then
rv=$(< vm$i/builtin-exitcode.txt)
if [ $rv = 0 ]; then
vm="vm$i"
else
vm="vm$i"
touch /tmp/have_failed_tests
fi
file="vm$i/builtin.txt"
test -s "$file" && showfile_tail "$file" "$vm: Linux built-in build"
fi
rv=$(cat vm$i/tests-exitcode.txt)
if [ $rv = 0 ]; then

View File

@ -4,11 +4,7 @@
#
# USAGE:
#
# ./qemu-test-repo-vm [--install] [URL]
#
# --lookup: When testing a repo, only lookup the latest package versions,
# don't try to install them. Installing all of them takes over
# an hour, so this is much quicker.
# ./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.
@ -19,13 +15,6 @@ source /etc/os-release
OS="$ID"
VERSION="$VERSION_ID"
LOOKUP=""
if [ -n "$1" ] && [ "$1" == "--lookup" ] ; then
LOOKUP=1
shift
fi
ALTHOST=""
if [ -n "$1" ] ; then
ALTHOST="$1"
@ -53,15 +42,6 @@ function test_install {
sudo sed -i "s;baseurl=http://download.zfsonlinux.org;baseurl=$host;g" /etc/yum.repos.d/zfs.repo
fi
baseurl=$(grep -A 5 "\[$repo\]" /etc/yum.repos.d/zfs.repo | awk -F'=' '/baseurl=/{print $2; exit}')
# Just do a version lookup - don't try to install any RPMs
if [ "$LOOKUP" == "1" ] ; then
package="$(dnf list $args zfs | tail -n 1 | awk '{print $2}')"
echo "$repo ${package} $baseurl" >> $SUMMARY
return
fi
if ! sudo dnf -y install $args zfs zfs-test ; then
echo "$repo ${package}...[FAILED] $baseurl" >> $SUMMARY
return
@ -74,6 +54,7 @@ function test_install {
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
@ -94,7 +75,7 @@ almalinux*)
sudo rpm -qi zfs-release
for i in zfs zfs-kmod zfs-testing zfs-testing-kmod zfs-latest \
zfs-latest-kmod zfs-legacy zfs-legacy-kmod zfs-2.2 \
zfs-2.2-kmod zfs-2.3 zfs-2.3-kmod zfs-2.4 zfs-2.4-kmod; do
zfs-2.2-kmod zfs-2.3 zfs-2.3-kmod ; do
test_install $i $ALTHOST
done
;;
@ -102,7 +83,7 @@ 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
for i in zfs zfs-latest zfs-legacy zfs-2.2 zfs-2.3 zfs-2.4 ; do
for i in zfs zfs-latest zfs-legacy zfs-2.2 zfs-2.3 ; do
test_install $i $ALTHOST
done
;;

View File

@ -1,40 +0,0 @@
name: zfs-arm
on:
push:
pull_request:
workflow_dispatch:
jobs:
zfs-arm:
name: ZFS ARM build
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Install dependencies
timeout-minutes: 20
run: |
sudo apt-get -y remove firefox || true
.github/workflows/scripts/qemu-3-deps-vm.sh ubuntu24
# We're running the VM scripts locally on the runner, so need to fix
# up hostnames to make it work.
for ((i=0; i<=3; i++)); do
echo "127.0.0.1 vm$i" | sudo tee -a /etc/hosts
done
- name: Build modules
timeout-minutes: 30
run: |
.github/workflows/scripts/qemu-4-build-vm.sh --enable-debug ubuntu24
# Quick sanity test since we're not running the full ZTS
sudo modprobe zfs
sudo dmesg | grep -i zfs
truncate -s 100M file
sudo zpool create tank ./file
zpool status
echo "Built ZFS successfully on ARM"

View File

@ -42,12 +42,6 @@ on:
required: false
default: ""
description: "(optional) repo URL (blank: use http://download.zfsonlinux.org)"
lookup:
type: boolean
required: false
default: false
description: "(optional) do version lookup only on repo test"
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
@ -58,7 +52,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora42', 'fedora43']
os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora41', 'fedora42', 'fedora43']
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
@ -83,12 +77,7 @@ jobs:
.github/workflows/scripts/qemu-prepare-for-build.sh
mkdir -p /tmp/repo
EXTRA=""
if [ "${{ github.event.inputs.lookup }}" == 'true' ] ; then
EXTRA="--lookup"
fi
ssh zfs@vm0 '$HOME/zfs/.github/workflows/scripts/qemu-test-repo-vm.sh' $EXTRA ${{ github.event.inputs.repo_url }}
ssh zfs@vm0 '$HOME/zfs/.github/workflows/scripts/qemu-test-repo-vm.sh' ${{ github.event.inputs.repo_url }}
else
EXTRA=""
if [ -n "${{ github.event.inputs.patch_level }}" ] ; then

View File

@ -10,11 +10,6 @@ on:
required: false
default: ""
description: "(optional) Experimental kernel version to install on Fedora (like '6.14' or '6.13.3-0.rc3')"
specific_os:
type: string
required: false
default: ""
description: "(optional) Only run on this specific OS (like 'fedora42' or 'alpine3-23')"
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
@ -35,13 +30,12 @@ jobs:
id: os
run: |
ci_type="default"
ci_source="auto"
# determine CI type when running on PR
if ${{ github.event_name == 'pull_request' }}; then
head=${{ github.event.pull_request.head.sha }}
base=${{ github.event.pull_request.base.sha }}
read ci_type ci_source <<< "$(python3 .github/workflows/scripts/generate-ci-type.py $head $base)"
ci_type=$(python3 .github/workflows/scripts/generate-ci-type.py $head $base)
fi
case "$ci_type" in
@ -49,37 +43,21 @@ jobs:
os_selection='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd15-0s", "ubuntu24"]'
;;
linux)
os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "debian13", "fedora42", "fedora43", "ubuntu22", "ubuntu24"]'
os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "debian13", "fedora41", "fedora42", "fedora43", "ubuntu22", "ubuntu24"]'
;;
freebsd)
os_selection='["freebsd13-5r", "freebsd14-4r", "freebsd13-5s", "freebsd14-4s", "freebsd15-0s", "freebsd16-0c"]'
os_selection='["freebsd13-5r", "freebsd14-2r", "freebsd14-3r", "freebsd13-5s", "freebsd14-3s", "freebsd15-0s", "freebsd16-0c"]'
;;
*)
# default list
os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora42", "fedora43", "freebsd14-4r", "freebsd15-0s", "freebsd16-0c", "ubuntu22", "ubuntu24"]'
os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora42", "fedora43", "freebsd14-3r", "freebsd15-0s", "freebsd16-0c", "ubuntu22", "ubuntu24"]'
;;
esac
# Repository-level override for OS selection.
# Set vars.ZTS_OS_OVERRIDE in repo settings to restrict targets
# (e.g. '["debian13"]' or '["debian13", "fedora42"]').
# Manual ZFS-CI-Type in commit messages bypasses the override.
if [ -n "${{ vars.ZTS_OS_OVERRIDE }}" ] && [ "$ci_source" != "manual" ]; then
override='${{ vars.ZTS_OS_OVERRIDE }}'
if echo "$override" | jq -e 'type == "array"' >/dev/null 2>&1; then
os_selection="$override"
else
echo "::warning::Invalid ZTS_OS_OVERRIDE, using default"
fi
fi
if ${{ github.event.inputs.fedora_kernel_ver != '' }}; then
# They specified a custom kernel version for Fedora.
# Use only Fedora runners.
os_json=$(echo ${os_selection} | jq -c '[.[] | select(startswith("fedora"))]')
elif ${{ github.event.inputs.specific_os != '' }}; then
# Use only the specified runner.
os_json=$(jq -cn --arg os "${{ github.event.inputs.specific_os }}" '[ $os ]')
else
# Normal case
os_json=$(echo ${os_selection} | jq -c)
@ -98,8 +76,8 @@ jobs:
# debian: debian12, debian13, ubuntu22, ubuntu24
# misc: archlinux, tumbleweed
# FreeBSD variants of november 2025:
# FreeBSD Release: freebsd13-5r, freebsd14-4r, freebsd15-0r
# FreeBSD Stable: freebsd13-5s, freebsd14-4s, freebsd15-0s
# FreeBSD Release: freebsd13-5r, freebsd14-2r, freebsd14-3r
# FreeBSD Stable: freebsd13-5s, freebsd14-3s, freebsd15-0s
# FreeBSD Current: freebsd16-0c
os: ${{ fromJson(needs.test-config.outputs.test_os) }}
runs-on: ubuntu-24.04
@ -118,7 +96,7 @@ jobs:
- name: Install dependencies
timeout-minutes: 60
run: .github/workflows/scripts/qemu-3-deps.sh --poweroff ${{ matrix.os }} ${{ github.event.inputs.fedora_kernel_ver }}
run: .github/workflows/scripts/qemu-3-deps.sh ${{ matrix.os }} ${{ github.event.inputs.fedora_kernel_ver }}
- name: Build modules
timeout-minutes: 30

View File

@ -53,7 +53,6 @@ Jason Harmening <jason.harmening@gmail.com>
Jeremy Faulkner <gldisater@gmail.com>
Jinshan Xiong <jinshan.xiong@gmail.com>
John Poduska <jpoduska@datto.com>
Joseph Holsten <joseph@josephholsten.com>
Jo Zzsi <jozzsicsataban@gmail.com>
Justin Scholz <git@justinscholz.de>
Ka Ho Ng <khng300@gmail.com>
@ -73,12 +72,10 @@ Roberto Ricci <io@r-ricci.it>
Roberto Ricci <ricci@disroot.org>
Rob Norris <robn@despairlabs.com>
Rob Norris <rob.norris@klarasystems.com>
Rob Norris <rob.norris@truenas.com>
Sam Lunt <samuel.j.lunt@gmail.com>
Sanjeev Bagewadi <sanjeev.bagewadi@gmail.com>
Sebastian Wuerl <s.wuerl@mailbox.org>
SHENGYI HONG <aokblast@FreeBSD.org>
Sivesh Kumar <siveshjami@gmail.com>
Stoiko Ivanov <github@nomore.at>
Tamas TEVESZ <ice@extreme.hu>
WHR <msl0000023508@gmail.com>
@ -86,12 +83,8 @@ Yanping Gao <yanping.gao@xtaotech.com>
Youzhong Yang <youzhong@gmail.com>
# Signed-off-by: overriding Author:
Alexander Moch <mail@alexmoch.com> <amoch@ernw.de>
Alexander Moch <mail@alexmoch.com> <github@alexanderjulian.de>
Alexander Ziaee <ziaee@FreeBSD.org> <concussious@runbox.com>
delan azabani <dazabani@igalia.com> <delan@azabani.com>
Felix Schmidt <felixschmidt20@aol.com> <f.sch.prototype@gmail.com>
George Shammas <george@shamm.as> <georgyo@gmail.com>
Jean-Sébastien Pédron <dumbbell@FreeBSD.org> <jean-sebastien.pedron@dumbbell.fr>
Konstantin Belousov <kib@FreeBSD.org> <kib@kib.kiev.ua>
Olivier Certner <olce@FreeBSD.org> <olce.freebsd@certner.fr>
@ -115,7 +108,6 @@ Ned Bass <bass6@llnl.gov> <bass6@zeno1.(none)>
Tulsi Jain <tulsi.jain@delphix.com> <tulsi.jain@Tulsi-Jains-MacBook-Pro.local>
# Mappings from Github no-reply addresses
Adi Gollamudi <adigollamudi@gmail.com> <68113680+Adi-Goll@users.noreply.github.com>
ajs124 <git@ajs124.de> <ajs124@users.noreply.github.com>
Alek Pinchuk <apinchuk@axcient.com> <alek-p@users.noreply.github.com>
Aleksandr Liber <aleksandr.liber@perforce.com> <61714074+AleksandrLiber@users.noreply.github.com>
@ -133,7 +125,6 @@ bernie1995 <bernie.pikes@gmail.com> <42413912+bernie1995@users.noreply.github.co
Bojan Novković <bnovkov@FreeBSD.org> <72801811+bnovkov@users.noreply.github.com>
Boris Protopopov <boris.protopopov@actifio.com> <bprotopopov@users.noreply.github.com>
Brad Forschinger <github@bnjf.id.au> <bnjf@users.noreply.github.com>
Brad Spengler <94915855+bspengler-oss@users.noreply.github.com>>
Brandon Thetford <brandon@dodecatec.com> <dodexahedron@users.noreply.github.com>
buzzingwires <buzzingwires@outlook.com> <131118055+buzzingwires@users.noreply.github.com>
Cedric Maunoury <cedric.maunoury@gmail.com> <38213715+cedricmaunoury@users.noreply.github.com>
@ -147,7 +138,6 @@ Daniel Kobras <d.kobras@science-computing.de> <sckobras@users.noreply.github.com
Daniel Reichelt <hacking@nachtgeist.net> <nachtgeist@users.noreply.github.com>
David Quigley <david.quigley@intel.com> <dpquigl@users.noreply.github.com>
Dennis R. Friedrichsen <dennis.r.friedrichsen@gmail.com> <31087738+dennisfriedrichsen@users.noreply.github.com>
Dennis Vestergaard Værum <github@varum.dk> <6872940+dvaerum@users.noreply.github.com>
Dex Wood <slash2314@gmail.com> <slash2314@users.noreply.github.com>
DHE <git@dehacked.net> <DeHackEd@users.noreply.github.com>
Dmitri John Ledkov <dimitri.ledkov@canonical.com> <19779+xnox@users.noreply.github.com>

14
AUTHORS
View File

@ -14,7 +14,6 @@ CONTRIBUTORS:
Adam D. Moss <c@yotes.com>
Adam Leventhal <ahl@delphix.com>
Adam Stevko <adam.stevko@gmail.com>
Adi Gollamudi <adigollamudi@gmail.com>
adisbladis <adis@blad.is>
Adrian Chadd <adrian@freebsd.org>
Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
@ -33,10 +32,8 @@ CONTRIBUTORS:
Alek Pinchuk <alek@nexenta.com>
Aleksandr Liber <aleksandr.liber@perforce.com>
Aleksa Sarai <cyphar@cyphar.com>
Alex <simplecodemaster@gmail.com>
Alexander Eremin <a.eremin@nexenta.com>
Alexander Lobakin <alobakin@pm.me>
Alexander Moch <mail@alexmoch.com>
Alexander Motin <mav@freebsd.org>
Alexander Pyhalov <apyhalov@gmail.com>
Alexander Richardson <Alexander.Richardson@cl.cam.ac.uk>
@ -49,7 +46,6 @@ CONTRIBUTORS:
Alex McWhirter <alexmcwhirter@triadic.us>
Alex Reece <alex@delphix.com>
Alex Wilson <alex.wilson@joyent.com>
Alexx Saver <lzsaver.eth@ethermail.io>
Alex Zhuravlev <alexey.zhuravlev@intel.com>
Allan Jude <allanjude@freebsd.org>
Allen Holl <allen.m.holl@gmail.com>
@ -93,7 +89,6 @@ CONTRIBUTORS:
Arun KV <arun.kv@datacore.com>
Arvind Sankar <nivedita@alum.mit.edu>
Attila Fülöp <attila@fueloep.org>
Austin Wise <AustinWise@gmail.com>
Avatat <kontakt@avatat.pl>
Bart Coddens <bart.coddens@gmail.com>
Basil Crow <basil.crow@delphix.com>
@ -115,7 +110,6 @@ CONTRIBUTORS:
Boris Protopopov <boris.protopopov@nexenta.com>
Brad Forschinger <github@bnjf.id.au>
Brad Lewis <brad.lewis@delphix.com>
Brad Spengler <bspengler-oss@users.noreply.github.com>
Brandon Thetford <brandon@dodecatec.com>
Brian Atkinson <bwa@g.clemson.edu>
Brian Behlendorf <behlendorf1@llnl.gov>
@ -202,9 +196,7 @@ CONTRIBUTORS:
David Quigley <david.quigley@intel.com>
Debabrata Banerjee <dbanerje@akamai.com>
D. Ebdrup <debdrup@freebsd.org>
delan azabani <dazabani@igalia.com>
Dennis R. Friedrichsen <dennis.r.friedrichsen@gmail.com>
Dennis Vestergaard Værum <github@varum.dk>
Denys Rtveliashvili <denys@rtveliashvili.name>
Derek Dai <daiderek@gmail.com>
Derek Schrock <dereks@lifeofadishwasher.com>
@ -231,7 +223,6 @@ CONTRIBUTORS:
Eric Desrochers <eric.desrochers@canonical.com>
Eric Dillmann <eric@jave.fr>
Eric Schrock <Eric.Schrock@delphix.com>
Erik Larsson <catacombae@gmail.com>
Ethan Coe-Renner <coerenner1@llnl.gov>
Etienne Dechamps <etienne@edechamps.fr>
Evan Allrich <eallrich@gmail.com>
@ -264,7 +255,6 @@ CONTRIBUTORS:
George Diamantopoulos <georgediam@gmail.com>
George Gaydarov <git@gg7.io>
George Melikov <mail@gmelikov.ru>
George Shammas <george@shamm.as>
George Wilson <gwilson@delphix.com>
Georgy Yakovlev <ya@sysdump.net>
Gerardwx <gerardw@alum.mit.edu>
@ -353,7 +343,6 @@ CONTRIBUTORS:
Joe Stein <joe.stein@delphix.com>
John-Mark Gurney <jmg@funkthat.com>
John Albietz <inthecloud247@gmail.com>
John Cabaj <john.cabaj@canonical.com>
John Eismeier <john.eismeier@gmail.com>
John Gallagher <john.gallagher@delphix.com>
John Layman <jlayman@sagecloud.com>
@ -369,7 +358,6 @@ CONTRIBUTORS:
Jorgen Lundman <lundman@lundman.net>
Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Jose Luis Duran <jlduran@gmail.com>
Joseph Holsten <joseph@josephholsten.com>
Josh Soref <jsoref@users.noreply.github.com>
Joshua M. Clulow <josh@sysmgr.org>
José Luis Salvador Rufo <salvador.joseluis@gmail.com>
@ -634,7 +622,6 @@ CONTRIBUTORS:
Simon Guest <simon.guest@tesujimath.org>
Simon Howard <fraggle@soulsphere.org>
Simon Klinkert <simon.klinkert@gmail.com>
Sivesh Kumar <siveshjami@gmail.com>
Sowrabha Gopal <sowrabha.gopal@delphix.com>
Spencer Kinny <spencerkinny1995@gmail.com>
Srikanth N S <srikanth.nagasubbaraoseetharaman@hpe.com>
@ -717,7 +704,6 @@ CONTRIBUTORS:
Windel Bouwman <windel@windel.nl>
Wojciech Małota-Wójcik <outofforest@users.noreply.github.com>
Wolfgang Bumiller <w.bumiller@proxmox.com>
Wolfgang Hoschek <wolfgang.hoschek@mac.com>
XDTG <click1799@163.com>
Xin Li <delphij@FreeBSD.org>
Xinliang Liu <xinliang.liu@linaro.org>

4
META
View File

@ -1,10 +1,10 @@
Meta: 1
Name: zfs
Branch: 1.0
Version: 2.4.99
Version: 2.4.0
Release: 1
Release-Tags: relext
License: CDDL
Author: OpenZFS
Linux-Maximum: 6.19
Linux-Maximum: 6.18
Linux-Minimum: 4.18

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
CLEANFILES =
dist_noinst_DATA =
INSTALL_DATA_HOOKS =
@ -133,7 +132,6 @@ cstyle:
! -name 'zfs_config.*' ! -name '*.mod.c' \
! -name 'opt_global.h' ! -name '*_if*.h' \
! -name 'zstd_compat_wrapper.h' \
! -path './module/zstd/zstd-in.c' \
! -path './module/zstd/lib/*' \
! -path './include/sys/lua/*' \
! -path './module/lua/l*.[ch]' \

View File

@ -30,42 +30,6 @@ We have a [Code of Conduct](./CODE_OF_CONDUCT.md).
OpenZFS is released under a CDDL license.
For more details see the NOTICE, LICENSE and COPYRIGHT files; `UCRL-CODE-235197`
# Supported Kernels and Distributions
## Linux
Given the wide variety of Linux environments, we prioritize development and testing on stable, supported kernels and distributions.
### Kernel ([kernel.org](https://kernel.org))
All **longterm** kernels from [kernel.org](https://kernel.org) are supported. **stable** kernels are usually supported in the next OpenZFS release.
**Supported longterm kernels**: **6.18**, **6.12**, **6.6**, **6.1**, **5.15**, **5.10**.
### Red Hat Enterprise Linux (RHEL)
All RHEL (and compatible systems: AlmaLinux OS, Rocky Linux, etc) on the **full** or **maintenance** support tracks are supported.
**Supported RHEL releases**: **8.10**, **9.7**, **10.1**.
### Ubuntu
All Ubuntu **LTS** releases are supported.
**Supported Ubuntu releases**: **24.04 “Noble”**, **22.04 “Jammy”**.
### Debian
All Debian **stable** and **LTS** releases are supported.
**Supported Debian releases**: **13 “Trixie”**, **12 “Bookworm”**, **11 “Bullseye”**.
### Other Distributions
Generally, if a distribution is following an LTS kernel, it should work well with OpenZFS.
## FreeBSD
All FreeBSD releases receiving [security support](https://www.freebsd.org/security/#sup) are supported by OpenZFS.
**Supported FreeBSD releases**: **15.0**, **14.4**, **13.5**.
# Supported Kernels
* The `META` file contains the officially recognized supported Linux kernel versions.
* Supported FreeBSD versions are any supported branches and releases starting from 13.0-RELEASE.

View File

@ -1,4 +1,3 @@
#!/bin/sh
# SPDX-License-Identifier: CDDL-1.0
autoreconf -fiv "$(dirname "$0")" && rm -rf "$(dirname "$0")"/autom4te.cache

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
bin_SCRIPTS =
bin_PROGRAMS =
sbin_SCRIPTS =
@ -36,8 +35,8 @@ zhack_SOURCES = \
zhack_LDADD = \
libzpool.la \
libzfs_core.la \
libnvpair.la \
librange_tree.la
libnvpair.la
ztest_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS)
ztest_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS)

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
raidz_test_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS)
raidz_test_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS)

View File

@ -33,7 +33,6 @@
#include <sys/vdev_raidz_impl.h>
#include <assert.h>
#include <stdio.h>
#include <libzpool.h>
#include "raidz_test.h"
static int *rand_data;

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
zdb_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS)
zdb_CFLAGS = $(AM_CFLAGS) $(LIBCRYPTO_CFLAGS)
@ -14,8 +13,6 @@ zdb_LDADD = \
libzdb.la \
libzpool.la \
libzfs_core.la \
libnvpair.la \
libbtree.la \
librange_tree.la
libnvpair.la
zdb_LDADD += $(LIBCRYPTO_LIBS)

View File

@ -36,7 +36,6 @@
* Copyright (c) 2021 Toomas Soome <tsoome@me.com>
* Copyright (c) 2023, 2024, Klara Inc.
* Copyright (c) 2023, Rob Norris <robn@despairlabs.com>
* Copyright (c) 2026, TrueNAS.
*/
#include <stdio.h>
@ -87,12 +86,9 @@
#include <sys/brt.h>
#include <sys/brt_impl.h>
#include <zfs_comutil.h>
#include <sys/vdev_raidz.h>
#include <sys/vdev_raidz_impl.h>
#include <sys/zstd/zstd.h>
#include <sys/backtrace.h>
#include <libzpool.h>
#include <libnvpair.h>
#include <libzutil.h>
#include <libzfs_core.h>
@ -742,16 +738,13 @@ usage(void)
"[-U <cache>]\n\t\t<poolname> [<vdev> [<metaslab> ...]]\n"
"\t%s -O [-K <key>] <dataset> <path>\n"
"\t%s -r [-K <key>] <dataset> <path> <destination>\n"
"\t%s -r [-K <key>] -O <dataset> <object-id> <destination>\n"
"\t%s -R [-A] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
"\t\t<poolname> <vdev>:<offset>:<size>[:<flags>]\n"
"\t%s -f [-H] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
"\t\t[<poolname>[/<dataset | objset id>] [<object | range> ...]]\n"
"\t%s -E [-A] word0:word1:...:word15\n"
"\t%s -S [-AP] [-e [-V] [-p <path> ...]] [-U <cache>] "
"<poolname>\n\n",
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname,
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
cmdname, cmdname, cmdname, cmdname, cmdname);
(void) fprintf(stderr, " Dataset name must include at least one "
"separator character '/' or '@'\n");
@ -790,8 +783,6 @@ usage(void)
"dataset(s)\n");
(void) fprintf(stderr, " -D --dedup-stats "
"dedup statistics\n");
(void) fprintf(stderr, " -f --file-layout "
"display a file's layout across raidz disks\n");
(void) fprintf(stderr, " -E --embedded-block-pointer=INTEGER\n"
" decode and display block "
"from an embedded block pointer\n");
@ -824,7 +815,6 @@ usage(void)
(void) fprintf(stderr, " -y --livelist "
"perform livelist and metaslab validation on any livelists being "
"deleted\n\n");
(void) fprintf(stderr, " Below options are intended for use "
"with other options:\n");
(void) fprintf(stderr, " -A --ignore-assertions "
@ -837,8 +827,6 @@ usage(void)
"groups\n");
(void) fprintf(stderr, " -G --dump-debug-msg "
"dump zfs_dbgmsg buffer before exiting\n");
(void) fprintf(stderr, " -H --scripting-mode "
"dump output in a format that is scripting friendly\n");
(void) fprintf(stderr, " -I --inflight=INTEGER "
"specify the maximum number of checksumming I/Os "
"[default is 200]\n");
@ -2144,8 +2132,7 @@ dump_ddt_object(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
(void) printf("%s: object=%llu\n", name,
(u_longlong_t)ddt->ddt_object[type][class]);
zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class],
dump_opt['P'] > 0);
zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class]);
if (dump_opt['D'] < 4)
return;
@ -2222,7 +2209,7 @@ dump_all_ddts(spa_t *spa)
if (dump_opt['D'] > 1) {
(void) printf("DDT histogram (aggregated over all DDTs):\n");
ddt_get_dedup_histogram(spa, &ddh_total);
zpool_dump_ddt(&dds_total, &ddh_total, dump_opt['P'] > 0);
zpool_dump_ddt(&dds_total, &ddh_total);
}
dump_dedup_ratio(&dds_total);
@ -2655,7 +2642,6 @@ snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp,
if (bp_freed)
(void) snprintf(blkbuf + strlen(blkbuf),
buflen - strlen(blkbuf), " %s", "FREE");
(void) snprintf(blkbuf + strlen(blkbuf),
buflen - strlen(blkbuf),
" cksum=%016llx:%016llx:%016llx:%016llx",
@ -2666,74 +2652,6 @@ snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp,
}
}
static void
inverse_text(boolean_t on)
{
if (isatty(STDOUT_FILENO)) {
if (on)
fputs("\x1b[7m", stdout);
else
fputs("\x1b[m", stdout);
}
}
static void
print_file_layout_line(int line, int first_disk, int last_disk, int ashift,
raidz_row_t *rr)
{
if (first_disk != 0) {
/* Account for empty columns */
for (int c = 0; c < first_disk; c++) {
(void) printf("%s%s", (c == 0) ? "" : " ",
line == 0 ? "` ` ` ` ` " : " ` ` ` ` `");
}
}
/*
* Check if we need to account for out of order disks in raidz1.
* Here flip means the disks in first two column were exchanged.
*/
boolean_t flip = rr->rr_firstdatacol == 1 &&
(rr->rr_offset & (1ULL << 20));
for (int c = 0; c < rr->rr_cols; c++) {
raidz_col_t *rc = &rr->rr_col[c];
char colname[8];
boolean_t pcol = flip ? (c == 1) : (c < rr->rr_firstdatacol);
if (rc->rc_devidx > last_disk)
continue;
(void) snprintf(colname, sizeof (colname), "%c%d",
pcol ? 'P' : 'D', (flip && c < 2) ? 0 :
pcol ? c : c - rr->rr_firstdatacol);
(void) printf("%s", (rc->rc_devidx == 0) ? "" : " ");
if (pcol)
inverse_text(B_TRUE);
if (line == 0) {
(void) printf("%3s %5d", colname,
(int)(rc->rc_size >> ashift));
} else {
(void) printf("%10llx",
(u_longlong_t)((rc->rc_offset +
VDEV_LABEL_START_SIZE) >> ashift));
}
if (pcol)
inverse_text(B_FALSE);
if (rc->rc_devidx == last_disk) {
/* empty columns */
for (int c = last_disk + 1; c < rr->rr_cols; c++) {
(void) printf(" %s",
line == 0 ? "` ` ` ` ` " : " ` ` ` ` `");
}
break;
}
}
(void) printf("\n");
}
static u_longlong_t
print_indirect(spa_t *spa, blkptr_t *bp, const zbookmark_phys_t *zb,
const dnode_phys_t *dnp)
@ -2780,133 +2698,17 @@ print_indirect(spa_t *spa, blkptr_t *bp, const zbookmark_phys_t *zb,
return (offset);
}
static void
print_file_layout_raidz(vdev_t *vd, blkptr_t *bp, uint64_t file_offset,
boolean_t last)
{
/*
* RAIDZ file data layout
*
* Use vdev_raidz_map_alloc() to get the actual layout
*/
const dva_t *dva = bp->blk_dva;
zio_t zio = {0};
zio.io_size = P2ROUNDUP_TYPED(BP_GET_PSIZE(bp),
1ULL << vd->vdev_ashift, uint64_t);
zio.io_offset = DVA_GET_OFFSET(&dva[0]);
zio.io_type = ZIO_TYPE_READ;
zio.io_abd = abd_alloc_for_io(zio.io_size, B_FALSE);
vdev_raidz_t *vdrz = vd->vdev_tsd;
raidz_map_t *rm = vdev_raidz_map_alloc(&zio, vd->vdev_ashift,
vd->vdev_children, vdrz->vd_nparity);
raidz_row_t *rr = rm->rm_row[0];
/*
* Account for out of order disks in raidz1.
* For now just reverse them back and adjust for it later.
*/
if (rr->rr_firstdatacol == 1 && (zio.io_offset & (1ULL << 20))) {
uint64_t devidx = rr->rr_col[0].rc_devidx;
rr->rr_col[0].rc_devidx = rr->rr_col[1].rc_devidx;
rr->rr_col[1].rc_devidx = devidx;
}
if (!dump_opt['H']) {
int last_disk = vd->vdev_children - 1;
int first_disk = rr->rr_col[0].rc_devidx;
(void) printf("%12llx", (u_longlong_t)file_offset);
print_file_layout_line(0, first_disk, last_disk,
vd->vdev_ashift, rr);
(void) printf("%*c", 12, ' ');
print_file_layout_line(1, first_disk, last_disk,
vd->vdev_ashift, rr);
/* Check for split row */
if (first_disk != 0) {
(void) printf("%*c", 12, ' ');
print_file_layout_line(0, 0, first_disk - 1,
vd->vdev_ashift, rr);
(void) printf("%*c", 12, ' ');
print_file_layout_line(1, 0, first_disk - 1,
vd->vdev_ashift, rr);
}
/* seperate rows with a line */
(void) printf("%*c", 12, ' ');
for (int c = 0; c < vd->vdev_children; c++) {
(void) printf("%s%10s", (c == 0) ?
(last ? " └─" : " ├─") : "──",
"──────────");
}
(void) printf("─%s\n", last ? "" : "");
} else {
static uint64_t next_offset = 0;
if (next_offset != file_offset) {
(void) printf("skip hole\t-\t%llx\n",
(u_longlong_t)((file_offset - next_offset) >>
vd->vdev_ashift));
}
next_offset = file_offset + BP_GET_LSIZE(bp);
for (int c = 0; c < rr->rr_cols; c++) {
raidz_col_t *rc = &rr->rr_col[c];
char *path = vd->vdev_child[rc->rc_devidx]->vdev_path;
// c < rr->rr_firstdatacol
if (rc->rc_size == 0)
continue;
(void) printf("%s\t%llu\t%d\n",
zfs_basename(path),
(u_longlong_t)(rc->rc_offset +
VDEV_LABEL_START_SIZE)/512,
(int)rc->rc_size/512);
}
}
}
static void
print_file_layout(spa_t *spa, blkptr_t *bp, const zbookmark_phys_t *zb,
const dnode_phys_t *dnp)
{
if (!BP_IS_EMBEDDED(bp)) {
ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type);
ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level);
}
ASSERT(zb->zb_level >= 0);
if (BP_IS_HOLE(bp))
return;
if (BP_IS_EMBEDDED(bp))
return;
const dva_t *dva = bp->blk_dva;
vdev_t *vd = spa->spa_root_vdev->vdev_child[DVA_GET_VDEV(&dva[0])];
uint64_t file_offset = blkid2offset(dnp, bp, zb);
if (strcmp("raidz", vd->vdev_ops->vdev_op_type) == 0) {
boolean_t last = (file_offset + BP_GET_LSIZE(bp)) >=
(dnp->dn_used & ~0x03ffULL);
print_file_layout_raidz(vd, bp, file_offset, last);
}
}
static int
visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
blkptr_t *bp, const zbookmark_phys_t *zb)
{
u_longlong_t offset = 0;
u_longlong_t offset;
int err = 0;
if (BP_GET_BIRTH(bp) == 0)
return (0);
if (dump_opt['f']) {
if (BP_GET_LEVEL(bp) == 0)
print_file_layout(spa, bp, zb, dnp);
} else {
print_indirect(spa, bp, zb, dnp);
}
offset = print_indirect(spa, bp, zb, dnp);
if (BP_GET_LEVEL(bp) > 0 && !BP_IS_HOLE(bp)) {
arc_flags_t flags = ARC_FLAG_WAIT;
@ -2958,63 +2760,6 @@ dump_indirect(dnode_t *dn)
zbookmark_phys_t czb;
(void) printf("Indirect blocks:\n");
SET_BOOKMARK(&czb, dmu_objset_id(dn->dn_objset),
dn->dn_object, dnp->dn_nlevels - 1, 0);
for (int j = 0; j < dnp->dn_nblkptr; j++) {
czb.zb_blkid = j;
(void) visit_indirect(dmu_objset_spa(dn->dn_objset), dnp,
&dnp->dn_blkptr[j], &czb);
}
(void) printf("\n");
}
static int
dump_indirect_layout(dnode_t *dn)
{
dnode_phys_t *dnp = dn->dn_phys;
zbookmark_phys_t czb;
spa_t *spa = dmu_objset_spa(dn->dn_objset);
int ashift = spa->spa_root_vdev->vdev_child[0]->vdev_ashift;
int children = spa->spa_root_vdev->vdev_child[0]->vdev_children;
if (strcmp(spa->spa_root_vdev->vdev_child[0]->vdev_ops->vdev_op_type,
"raidz") != 0) {
(void) fprintf(stderr, "file layout only supports raidz\n");
return (ENOTSUP);
}
/*
* Start layout with a header
*/
if (dump_opt['H']) {
(void) printf("DISK\t\tLBA\t\tCOUNT\n");
} else {
char diskhdr[16];
(void) printf("%12s: %d\n", "block size", dn->dn_datablksz);
(void) printf("%12s: %s%d\n", "vdev_type",
spa->spa_root_vdev->vdev_child[0]->vdev_ops->vdev_op_type,
(int)vdev_get_nparity(spa->spa_root_vdev->vdev_child[0]));
(void) printf("%12s: %d\n", "sector size", 1 << ashift);
(void) printf("%12s: %d\n\n", "child disks", children);
(void) printf("%*c ", 12, ' ');
for (int c = 0; c < children; c++) {
(void) snprintf(diskhdr, sizeof (diskhdr),
"V%d:DISK-%d", 0, c);
(void) printf(" %10s ", diskhdr);
}
(void) printf("\n");
(void) printf("%12s", "FILE OFFSET");
for (int c = 0; c < children; c++)
(void) printf("%s%10s", (c == 0) ? " ┌─" : "──",
"──────────");
(void) printf("─┐\n");
}
SET_BOOKMARK(&czb, dmu_objset_id(dn->dn_objset),
dn->dn_object, dnp->dn_nlevels - 1, 0);
@ -3025,7 +2770,6 @@ dump_indirect_layout(dnode_t *dn)
}
(void) printf("\n");
return (0);
}
static void
@ -3286,6 +3030,7 @@ dump_full_bpobj(bpobj_t *bpo, const char *name, int indent)
if (dump_opt['d'] < 5)
return;
if (indent == 0) {
(void) bpobj_iterate_nofree(bpo, dump_bpobj_cb, NULL, NULL);
(void) printf("\n");
@ -3643,14 +3388,14 @@ zdb_derive_key(dsl_dir_t *dd, uint8_t *key_out)
static char encroot[ZFS_MAX_DATASET_NAME_LEN];
static boolean_t key_loaded = B_FALSE;
static int
static void
zdb_load_key(objset_t *os)
{
dsl_pool_t *dp;
dsl_dir_t *dd, *rdd;
uint8_t key[WRAPPING_KEY_LEN];
uint64_t rddobj;
int err = 0;
int err;
dp = spa_get_dsl(os->os_spa);
dd = os->os_dsl_dataset->ds_dir;
@ -3663,13 +3408,9 @@ zdb_load_key(objset_t *os)
dsl_dir_rele(rdd, FTAG);
if (!zdb_derive_key(dd, key))
err = EINVAL;
dsl_pool_config_exit(dp, FTAG);
fatal("couldn't derive encryption key");
if (err != 0) {
fprintf(stderr, "couldn't derive encryption key\n");
return (err);
}
dsl_pool_config_exit(dp, FTAG);
ASSERT3U(dsl_dataset_get_keystatus(dd), ==, ZFS_KEYSTATUS_UNAVAILABLE);
@ -3686,20 +3427,16 @@ zdb_load_key(objset_t *os)
dsl_crypto_params_free(dcp, (err != 0));
fnvlist_free(crypto_args);
if (err != 0) {
fprintf(stderr,
"couldn't load encryption key for %s: %s\n",
if (err != 0)
fatal(
"couldn't load encryption key for %s: %s",
encroot, err == ZFS_ERR_CRYPTO_NOTSUP ?
"crypto params not supported" : strerror(err));
return (err);
}
ASSERT3U(dsl_dataset_get_keystatus(dd), ==, ZFS_KEYSTATUS_AVAILABLE);
printf("Unlocked encryption root: %s\n", encroot);
key_loaded = B_TRUE;
return (0);
}
static void
@ -3742,30 +3479,15 @@ open_objset(const char *path, const void *tag, objset_t **osp)
path, strerror(err));
return (err);
}
/*
* Only try to load the key and unlock the dataset if it is
* actually encrypted; otherwise we'll just crash. Just
* ignore the -K switch entirely otherwise; it's useful to be
* able to provide even if it's not needed.
*/
if ((*osp)->os_encrypted) {
dsl_dataset_long_hold(dmu_objset_ds(*osp), tag);
dsl_pool_rele(dmu_objset_pool(*osp), tag);
err = zdb_load_key(*osp);
/* succeeds or dies */
zdb_load_key(*osp);
/* release it all */
dsl_dataset_long_rele(dmu_objset_ds(*osp), tag);
dsl_dataset_rele(dmu_objset_ds(*osp), tag);
if (err != 0) {
*osp = NULL;
return (err);
}
} else {
dmu_objset_rele(*osp, tag);
}
}
int ds_hold_flags = key_loaded ? DS_HOLD_FLAG_DECRYPT : 0;
@ -3774,7 +3496,6 @@ open_objset(const char *path, const void *tag, objset_t **osp)
if (err != 0) {
(void) fprintf(stderr, "failed to hold dataset '%s': %s\n",
path, strerror(err));
*osp = NULL;
return (err);
}
dsl_dataset_long_hold(dmu_objset_ds(*osp), tag);
@ -4413,6 +4134,7 @@ dump_object(objset_t *os, uint64_t object, int verbosity,
start = end;
}
}
out:
if (db != NULL)
dmu_buf_rele(db, FTAG);
@ -4420,60 +4142,6 @@ out:
dnode_rele(dn, FTAG);
}
static void
dump_object_file_layout(objset_t *os, uint64_t object, int verbosity)
{
(void) verbosity;
dmu_buf_t *db = NULL;
dmu_object_info_t doi;
dnode_t *dn;
boolean_t dnode_held = B_FALSE;
int error;
char osname[ZFS_MAX_DATASET_NAME_LEN];
dmu_objset_name(os, osname);
(void) printf("%12s: '%s'\n", "objset", osname);
(void) printf("%12s: %d\n", "object", (int)object);
if (object == 0) {
dn = DMU_META_DNODE(os);
dmu_object_info_from_dnode(dn, &doi);
} else {
/*
* Encrypted datasets will have sensitive bonus buffers
* encrypted. Therefore we cannot hold the bonus buffer and
* must hold the dnode itself instead.
*/
error = dmu_object_info(os, object, &doi);
if (error)
fatal("dmu_object_info() failed, errno %u", error);
if (!key_loaded && os->os_encrypted &&
DMU_OT_IS_ENCRYPTED(doi.doi_bonus_type)) {
error = dnode_hold(os, object, FTAG, &dn);
if (error)
fatal("dnode_hold() failed, errno %u", error);
dnode_held = B_TRUE;
} else {
error = dmu_bonus_hold(os, object, FTAG, &db);
if (error)
fatal("dmu_bonus_hold(%llu) failed, errno %u",
object, error);
dn = DB_DNODE((dmu_buf_impl_t *)db);
}
}
error = dump_indirect_layout(dn);
if (db != NULL)
dmu_buf_rele(db, FTAG);
if (dnode_held)
dnode_rele(dn, FTAG);
if (error)
zdb_exit(1);
}
static void
count_dir_mos_objects(dsl_dir_t *dd)
{
@ -4662,7 +4330,7 @@ dump_objset(objset_t *os)
zdb_nicenum(refdbytes, numbuf, sizeof (numbuf));
if (verbosity >= 4 || dump_opt['d']) {
if (verbosity >= 4) {
(void) snprintf(blkbuf, sizeof (blkbuf), ", rootbp ");
(void) snprintf_blkptr(blkbuf + strlen(blkbuf),
sizeof (blkbuf) - strlen(blkbuf), os->os_rootbp);
@ -4685,21 +4353,21 @@ dump_objset(objset_t *os)
flags = zopt_object_ranges[i].zor_flags;
object = obj_start;
if (object == 0 || obj_start == obj_end) {
dump_object(os, object, verbosity,
&print_header, NULL, flags);
} else {
if (object == 0 || obj_start == obj_end)
dump_object(os, object, verbosity, &print_header, NULL,
flags);
else
object--;
}
while ((dmu_object_next(os, &object, B_FALSE, 0) == 0) &&
object <= obj_end) {
dump_object(os, object, verbosity,
&print_header, NULL, flags);
dump_object(os, object, verbosity, &print_header, NULL,
flags);
}
}
if (zopt_object_args > 0) {
(void) printf("\n");
return;
}
@ -4782,32 +4450,6 @@ dump_objset(objset_t *os)
}
}
static void
dump_file_data_layout(objset_t *os)
{
uint64_t object;
int verbosity = dump_opt['d'];
unsigned i;
uint64_t obj_start;
uint64_t obj_end;
for (i = 0; i < zopt_object_args; i++) {
obj_start = zopt_object_ranges[i].zor_obj_start;
obj_end = zopt_object_ranges[i].zor_obj_end;
object = obj_start;
if (object == 0 || obj_start == obj_end)
dump_object_file_layout(os, object, verbosity);
else
object--;
while ((dmu_object_next(os, &object, B_FALSE, 0) == 0) &&
object <= obj_end) {
dump_object_file_layout(os, object, verbosity);
}
}
}
static void
dump_uberblock(uberblock_t *ub, const char *header, const char *footer)
{
@ -6039,6 +5681,7 @@ dump_one_objset(const char *dsname, void *arg)
!dmu_objset_is_snapshot(os)) {
global_feature_count[SPA_FEATURE_LIVELIST]++;
}
dump_objset(os);
close_objset(os, FTAG);
fuid_table_destroy();
@ -8119,7 +7762,7 @@ dump_simulated_ddt(spa_t *spa)
(void) printf("Simulated DDT histogram:\n");
zpool_dump_ddt(&dds_total, &ddh_total, dump_opt['P'] > 0);
zpool_dump_ddt(&dds_total, &ddh_total);
dump_dedup_ratio(&dds_total);
}
@ -9858,11 +9501,9 @@ main(int argc, char **argv)
{"dedup-stats", no_argument, NULL, 'D'},
{"exported", no_argument, NULL, 'e'},
{"embedded-block-pointer", no_argument, NULL, 'E'},
{"file-layout", no_argument, NULL, 'f'},
{"automatic-rewind", no_argument, NULL, 'F'},
{"dump-debug-msg", no_argument, NULL, 'G'},
{"history", no_argument, NULL, 'h'},
{"scripting-mode", no_argument, NULL, 'H'},
{"intent-logs", no_argument, NULL, 'i'},
{"inflight", required_argument, NULL, 'I'},
{"checkpointed-state", no_argument, NULL, 'k'},
@ -9902,7 +9543,7 @@ main(int argc, char **argv)
};
while ((c = getopt_long(argc, argv,
"AbBcCdDeEfFGhHiI:kK:lLmMNo:Op:PqrRsSt:TuU:vVx:XYyZ",
"AbBcCdDeEFGhiI:kK:lLmMNo:Op:PqrRsSt:TuU:vVx:XYyZ",
long_options, NULL)) != -1) {
switch (c) {
case 'b':
@ -9912,7 +9553,6 @@ main(int argc, char **argv)
case 'd':
case 'D':
case 'E':
case 'f':
case 'G':
case 'h':
case 'i':
@ -9936,7 +9576,6 @@ main(int argc, char **argv)
case 'A':
case 'e':
case 'F':
case 'H':
case 'k':
case 'L':
case 'P':
@ -10076,10 +9715,6 @@ main(int argc, char **argv)
(void) fprintf(stderr, "-p option requires use of -e\n");
usage();
}
if (dump_opt['H'] && !dump_opt['f']) {
(void) fprintf(stderr, "-H option requires use of -f\n");
usage();
}
#if defined(_LP64)
/*
* ZDB does not typically re-read blocks; therefore limit the ARC
@ -10119,7 +9754,7 @@ main(int argc, char **argv)
verbose = MAX(verbose, 1);
for (c = 0; c < 256; c++) {
if (dump_all && strchr("ABeEfFkKlLNOPrRSXy", c) == NULL)
if (dump_all && strchr("ABeEFkKlLNOPrRSXy", c) == NULL)
dump_opt[c] = 1;
if (dump_opt[c])
dump_opt[c] += verbose;
@ -10320,7 +9955,7 @@ main(int argc, char **argv)
* which imports the pool to the namespace if it's
* not in the cachefile.
*/
if (dump_opt['O'] && !dump_opt['r']) {
if (dump_opt['O']) {
if (argc != 2)
usage();
dump_opt['v'] = verbose + 3;
@ -10333,11 +9968,7 @@ main(int argc, char **argv)
if (argc != 3)
usage();
dump_opt['v'] = verbose;
if (dump_opt['O']) {
object = strtoull(argv[1], NULL, 0);
} else {
error = dump_path(argv[0], argv[1], &object);
}
if (error != 0)
fatal("internal error: %s", strerror(error));
}
@ -10491,7 +10122,7 @@ retry_lookup:
flagbits['z'] = ZOR_FLAG_ZAP;
flagbits['A'] = ZOR_FLAG_ALL_TYPES;
if (argc > 0 && (dump_opt['d'] || dump_opt['f'])) {
if (argc > 0 && dump_opt['d']) {
zopt_object_args = argc;
zopt_object_ranges = calloc(zopt_object_args,
sizeof (zopt_object_range_t));
@ -10517,10 +10148,7 @@ retry_lookup:
strerror(errno));
}
}
if (dump_opt['f'] && os != NULL) {
dump_file_data_layout(os);
} else if (dump_opt['B']) {
if (dump_opt['B']) {
dump_backup(target, objset_id,
argc > 0 ? argv[0] : NULL);
} else if (os != NULL) {

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
include $(srcdir)/%D%/zed.d/Makefile.am
zed_CFLAGS = $(AM_CFLAGS)
@ -38,7 +37,8 @@ zed_SOURCES = \
zed_LDADD = \
libzfs.la \
libzfs_core.la \
libnvpair.la
libnvpair.la \
libuutil.la
zed_LDADD += -lrt $(LIBATOMIC_LIBS) $(LIBUDEV_LIBS) $(LIBUUID_LIBS)
zed_LDFLAGS = -pthread

View File

@ -29,6 +29,7 @@
#include <stddef.h>
#include <string.h>
#include <libuutil.h>
#include <libzfs.h>
#include <sys/types.h>
#include <sys/time.h>
@ -95,7 +96,7 @@ typedef struct zfs_case {
uint32_t zc_version;
zfs_case_data_t zc_data;
fmd_case_t *zc_case;
list_node_t zc_node;
uu_list_node_t zc_node;
id_t zc_remove_timer;
char *zc_fru;
er_timeval_t zc_when;
@ -125,7 +126,8 @@ zfs_de_stats_t zfs_stats = {
/* wait 15 seconds after a removal */
static hrtime_t zfs_remove_timeout = SEC2NSEC(15);
static list_t zfs_cases;
uu_list_pool_t *zfs_case_pool;
uu_list_t *zfs_cases;
#define ZFS_MAKE_RSRC(type) \
FM_RSRC_CLASS "." ZFS_ERROR_CLASS "." type
@ -172,8 +174,8 @@ zfs_case_unserialize(fmd_hdl_t *hdl, fmd_case_t *cp)
zcp->zc_remove_timer = fmd_timer_install(hdl, zcp,
NULL, zfs_remove_timeout);
list_link_init(&zcp->zc_node);
list_insert_head(&zfs_cases, zcp);
uu_list_node_init(zcp, &zcp->zc_node, zfs_case_pool);
(void) uu_list_insert_before(zfs_cases, NULL, zcp);
fmd_case_setspecific(hdl, cp, zcp);
@ -204,8 +206,8 @@ zfs_other_serd_cases(fmd_hdl_t *hdl, const zfs_case_data_t *zfs_case)
next_check = gethrestime_sec() + CASE_GC_TIMEOUT_SECS;
}
for (zcp = list_head(&zfs_cases); zcp != NULL;
zcp = list_next(&zfs_cases, zcp)) {
for (zcp = uu_list_first(zfs_cases); zcp != NULL;
zcp = uu_list_next(zfs_cases, zcp)) {
zfs_case_data_t *zcd = &zcp->zc_data;
/*
@ -255,8 +257,8 @@ zfs_mark_vdev(uint64_t pool_guid, nvlist_t *vd, er_timeval_t *loaded)
/*
* Mark any cases associated with this (pool, vdev) pair.
*/
for (zcp = list_head(&zfs_cases); zcp != NULL;
zcp = list_next(&zfs_cases, zcp)) {
for (zcp = uu_list_first(zfs_cases); zcp != NULL;
zcp = uu_list_next(zfs_cases, zcp)) {
if (zcp->zc_data.zc_pool_guid == pool_guid &&
zcp->zc_data.zc_vdev_guid == vdev_guid) {
zcp->zc_present = B_TRUE;
@ -302,8 +304,8 @@ zfs_mark_pool(zpool_handle_t *zhp, void *unused)
/*
* Mark any cases associated with just this pool.
*/
for (zcp = list_head(&zfs_cases); zcp != NULL;
zcp = list_next(&zfs_cases, zcp)) {
for (zcp = uu_list_first(zfs_cases); zcp != NULL;
zcp = uu_list_next(zfs_cases, zcp)) {
if (zcp->zc_data.zc_pool_guid == pool_guid &&
zcp->zc_data.zc_vdev_guid == 0)
zcp->zc_present = B_TRUE;
@ -319,8 +321,8 @@ zfs_mark_pool(zpool_handle_t *zhp, void *unused)
if (nelem == 2) {
loaded.ertv_sec = tod[0];
loaded.ertv_nsec = tod[1];
for (zcp = list_head(&zfs_cases); zcp != NULL;
zcp = list_next(&zfs_cases, zcp)) {
for (zcp = uu_list_first(zfs_cases); zcp != NULL;
zcp = uu_list_next(zfs_cases, zcp)) {
if (zcp->zc_data.zc_pool_guid == pool_guid &&
zcp->zc_data.zc_vdev_guid == 0) {
zcp->zc_when = loaded;
@ -387,7 +389,8 @@ zpool_find_load_time(zpool_handle_t *zhp, void *arg)
static void
zfs_purge_cases(fmd_hdl_t *hdl)
{
zfs_case_t *zcp, *next;
zfs_case_t *zcp;
uu_list_walk_t *walk;
libzfs_handle_t *zhdl = fmd_hdl_getspecific(hdl);
/*
@ -407,8 +410,8 @@ zfs_purge_cases(fmd_hdl_t *hdl)
/*
* Mark the cases as not present.
*/
for (zcp = list_head(&zfs_cases); zcp != NULL;
zcp = list_next(&zfs_cases, zcp))
for (zcp = uu_list_first(zfs_cases); zcp != NULL;
zcp = uu_list_next(zfs_cases, zcp))
zcp->zc_present = B_FALSE;
/*
@ -422,11 +425,12 @@ zfs_purge_cases(fmd_hdl_t *hdl)
/*
* Remove those cases which were not found.
*/
for (zcp = list_head(&zfs_cases); zcp != NULL; zcp = next) {
next = list_next(&zfs_cases, zcp);
walk = uu_list_walk_start(zfs_cases, UU_WALK_ROBUST);
while ((zcp = uu_list_walk_next(walk)) != NULL) {
if (!zcp->zc_present)
fmd_case_close(hdl, zcp->zc_case);
}
uu_list_walk_end(walk);
}
/*
@ -656,8 +660,8 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
zfs_ereport_when(hdl, nvl, &er_when);
for (zcp = list_head(&zfs_cases); zcp != NULL;
zcp = list_next(&zfs_cases, zcp)) {
for (zcp = uu_list_first(zfs_cases); zcp != NULL;
zcp = uu_list_next(zfs_cases, zcp)) {
if (zcp->zc_data.zc_pool_guid == pool_guid) {
pool_found = B_TRUE;
pool_load = zcp->zc_when;
@ -863,8 +867,8 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
* Pool level fault. Before solving the case, go through and
* close any open device cases that may be pending.
*/
for (dcp = list_head(&zfs_cases); dcp != NULL;
dcp = list_next(&zfs_cases, dcp)) {
for (dcp = uu_list_first(zfs_cases); dcp != NULL;
dcp = uu_list_next(zfs_cases, dcp)) {
if (dcp->zc_data.zc_pool_guid ==
zcp->zc_data.zc_pool_guid &&
dcp->zc_data.zc_vdev_guid != 0)
@ -1084,7 +1088,8 @@ zfs_fm_close(fmd_hdl_t *hdl, fmd_case_t *cs)
if (zcp->zc_data.zc_has_remove_timer)
fmd_timer_remove(hdl, zcp->zc_remove_timer);
list_remove(&zfs_cases, zcp);
uu_list_remove(zfs_cases, zcp);
uu_list_node_fini(zcp, &zcp->zc_node, zfs_case_pool);
fmd_hdl_free(hdl, zcp, sizeof (zfs_case_t));
}
@ -1112,11 +1117,23 @@ _zfs_diagnosis_init(fmd_hdl_t *hdl)
if ((zhdl = libzfs_init()) == NULL)
return;
list_create(&zfs_cases,
sizeof (zfs_case_t), offsetof(zfs_case_t, zc_node));
if ((zfs_case_pool = uu_list_pool_create("zfs_case_pool",
sizeof (zfs_case_t), offsetof(zfs_case_t, zc_node),
NULL, UU_LIST_POOL_DEBUG)) == NULL) {
libzfs_fini(zhdl);
return;
}
if ((zfs_cases = uu_list_create(zfs_case_pool, NULL,
UU_LIST_DEBUG)) == NULL) {
uu_list_pool_destroy(zfs_case_pool);
libzfs_fini(zhdl);
return;
}
if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) {
list_destroy(&zfs_cases);
uu_list_destroy(zfs_cases);
uu_list_pool_destroy(zfs_case_pool);
libzfs_fini(zhdl);
return;
}
@ -1131,18 +1148,24 @@ void
_zfs_diagnosis_fini(fmd_hdl_t *hdl)
{
zfs_case_t *zcp;
uu_list_walk_t *walk;
libzfs_handle_t *zhdl;
/*
* Remove all active cases.
*/
while ((zcp = list_remove_head(&zfs_cases)) != NULL) {
walk = uu_list_walk_start(zfs_cases, UU_WALK_ROBUST);
while ((zcp = uu_list_walk_next(walk)) != NULL) {
fmd_hdl_debug(hdl, "removing case ena %llu",
(long long unsigned)zcp->zc_data.zc_ena);
uu_list_remove(zfs_cases, zcp);
uu_list_node_fini(zcp, &zcp->zc_node, zfs_case_pool);
fmd_hdl_free(hdl, zcp, sizeof (zfs_case_t));
}
uu_list_walk_end(walk);
list_destroy(&zfs_cases);
uu_list_destroy(zfs_cases);
uu_list_pool_destroy(zfs_case_pool);
zhdl = fmd_hdl_getspecific(hdl);
libzfs_fini(zhdl);

View File

@ -82,7 +82,7 @@
#include <sys/sunddi.h>
#include <sys/sysevent/eventdefs.h>
#include <sys/sysevent/dev.h>
#include <sys/taskq.h>
#include <thread_pool.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
@ -98,7 +98,7 @@ typedef void (*zfs_process_func_t)(zpool_handle_t *, nvlist_t *, boolean_t);
libzfs_handle_t *g_zfshdl;
list_t g_pool_list; /* list of unavailable pools at initialization */
list_t g_device_list; /* list of disks with asynchronous label request */
taskq_t *g_taskq;
tpool_t *g_tpool;
boolean_t g_enumeration_done;
pthread_t g_zfs_tid; /* zfs_enum_pools() thread */
@ -749,8 +749,8 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
continue;
if (zfs_toplevel_state(zhp) >= VDEV_STATE_DEGRADED) {
list_remove(&g_pool_list, pool);
(void) taskq_dispatch(g_taskq, zfs_enable_ds,
pool, TQ_SLEEP);
(void) tpool_dispatch(g_tpool, zfs_enable_ds,
pool);
break;
}
}
@ -1347,9 +1347,9 @@ zfs_slm_fini(void)
/* wait for zfs_enum_pools thread to complete */
(void) pthread_join(g_zfs_tid, NULL);
/* destroy the thread pool */
if (g_taskq != NULL) {
taskq_wait(g_taskq);
taskq_destroy(g_taskq);
if (g_tpool != NULL) {
tpool_wait(g_tpool);
tpool_destroy(g_tpool);
}
while ((pool = list_remove_head(&g_pool_list)) != NULL) {

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
zedconfdir = $(sysconfdir)/zfs/zed.d
dist_zedconf_DATA = \
%D%/zed-functions.sh \

View File

@ -21,7 +21,6 @@ zed_check_cmd "${ZFS}" sort diff
# We lock the output file to avoid simultaneous writes.
# If we run into trouble, log and drop the lock
# shellcheck disable=SC2329
abort_alter() {
zed_log_msg "Error updating zfs-list.cache for ${ZEVENT_POOL}!"
zed_unlock "${FSLIST}"

View File

@ -45,10 +45,21 @@ struct launched_process_node {
static int
_launched_process_node_compare(const void *x1, const void *x2)
{
const struct launched_process_node *node1 = x1;
const struct launched_process_node *node2 = x2;
pid_t p1;
pid_t p2;
return (TREE_CMP(node1->pid, node2->pid));
assert(x1 != NULL);
assert(x2 != NULL);
p1 = ((const struct launched_process_node *) x1)->pid;
p2 = ((const struct launched_process_node *) x2)->pid;
if (p1 < p2)
return (-1);
else if (p1 == p2)
return (0);
else
return (1);
}
static pthread_t _reap_children_tid = (pthread_t)-1;

View File

@ -42,10 +42,26 @@ typedef struct zed_strings_node zed_strings_node_t;
static int
_zed_strings_node_compare(const void *x1, const void *x2)
{
const zed_strings_node_t *n1 = x1;
const zed_strings_node_t *n2 = x2;
const char *s1;
const char *s2;
int rv;
return (TREE_ISIGN(strcmp(n1->key, n2->key)));
assert(x1 != NULL);
assert(x2 != NULL);
s1 = ((const zed_strings_node_t *) x1)->key;
assert(s1 != NULL);
s2 = ((const zed_strings_node_t *) x2)->key;
assert(s2 != NULL);
rv = strcmp(s1, s2);
if (rv < 0)
return (-1);
if (rv > 0)
return (1);
return (0);
}
/*

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
sbin_PROGRAMS += zfs
CPPCHECKTARGETS += zfs
@ -13,7 +12,8 @@ zfs_SOURCES = \
zfs_LDADD = \
libzfs.la \
libzfs_core.la \
libnvpair.la
libnvpair.la \
libuutil.la
zfs_LDADD += $(LTLIBINTL)

View File

@ -28,6 +28,7 @@
*/
#include <libintl.h>
#include <libuutil.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@ -49,16 +50,14 @@
* When finished, we have an AVL tree of ZFS handles. We go through and execute
* the provided callback for each one, passing whatever data the user supplied.
*/
typedef struct callback_data callback_data_t;
typedef struct zfs_node {
zfs_handle_t *zn_handle;
callback_data_t *zn_callback;
avl_node_t zn_avlnode;
uu_avl_node_t zn_avlnode;
} zfs_node_t;
struct callback_data {
avl_tree_t cb_avl;
typedef struct callback_data {
uu_avl_t *cb_avl;
int cb_flags;
zfs_type_t cb_types;
zfs_sort_column_t *cb_sortcol;
@ -66,7 +65,9 @@ struct callback_data {
int cb_depth_limit;
int cb_depth;
uint8_t cb_props_table[ZFS_NUM_PROPS];
};
} callback_data_t;
uu_avl_pool_t *avl_pool;
/*
* Include snaps if they were requested or if this a zfs list where types
@ -98,12 +99,13 @@ zfs_callback(zfs_handle_t *zhp, void *data)
if ((zfs_get_type(zhp) & cb->cb_types) ||
((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
avl_index_t idx;
uu_avl_index_t idx;
zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
node->zn_handle = zhp;
node->zn_callback = cb;
if (avl_find(&cb->cb_avl, node, &idx) == NULL) {
uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
&idx) == NULL) {
if (cb->cb_proplist) {
if ((*cb->cb_proplist) &&
!(*cb->cb_proplist)->pl_all)
@ -118,7 +120,7 @@ zfs_callback(zfs_handle_t *zhp, void *data)
return (-1);
}
}
avl_insert(&cb->cb_avl, node, idx);
uu_avl_insert(cb->cb_avl, node, idx);
should_close = B_FALSE;
} else {
free(node);
@ -284,7 +286,7 @@ zfs_compare(const void *larg, const void *rarg)
if (rat != NULL)
*rat = '\0';
ret = TREE_ISIGN(strcmp(lname, rname));
ret = strcmp(lname, rname);
if (ret == 0 && (lat != NULL || rat != NULL)) {
/*
* If we're comparing a dataset to one of its snapshots, we
@ -338,11 +340,11 @@ zfs_compare(const void *larg, const void *rarg)
* with snapshots grouped under their parents.
*/
static int
zfs_sort(const void *larg, const void *rarg)
zfs_sort(const void *larg, const void *rarg, void *data)
{
zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
zfs_sort_column_t *sc = ((zfs_node_t *)larg)->zn_callback->cb_sortcol;
zfs_sort_column_t *sc = (zfs_sort_column_t *)data;
zfs_sort_column_t *psc;
for (psc = sc; psc != NULL; psc = psc->sc_next) {
@ -412,13 +414,15 @@ zfs_sort(const void *larg, const void *rarg)
return (-1);
if (lstr)
ret = TREE_ISIGN(strcmp(lstr, rstr));
else
ret = TREE_CMP(lnum, rnum);
ret = strcmp(lstr, rstr);
else if (lnum < rnum)
ret = -1;
else if (lnum > rnum)
ret = 1;
if (ret != 0) {
if (psc->sc_reverse == B_TRUE)
ret = -ret;
ret = (ret < 0) ? 1 : -1;
return (ret);
}
}
@ -434,6 +438,13 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
callback_data_t cb = {0};
int ret = 0;
zfs_node_t *node;
uu_avl_walk_t *walk;
avl_pool = uu_avl_pool_create("zfs_pool", sizeof (zfs_node_t),
offsetof(zfs_node_t, zn_avlnode), zfs_sort, UU_DEFAULT);
if (avl_pool == NULL)
nomem();
cb.cb_sortcol = sortcol;
cb.cb_flags = flags;
@ -478,8 +489,8 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
sizeof (cb.cb_props_table));
}
avl_create(&cb.cb_avl, zfs_sort,
sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL)
nomem();
if (argc == 0) {
/*
@ -520,20 +531,25 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
* At this point we've got our AVL tree full of zfs handles, so iterate
* over each one and execute the real user callback.
*/
for (node = avl_first(&cb.cb_avl); node != NULL;
node = AVL_NEXT(&cb.cb_avl, node))
for (node = uu_avl_first(cb.cb_avl); node != NULL;
node = uu_avl_next(cb.cb_avl, node))
ret |= callback(node->zn_handle, data);
/*
* Finally, clean up the AVL tree.
*/
void *cookie = NULL;
while ((node = avl_destroy_nodes(&cb.cb_avl, &cookie)) != NULL) {
if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL)
nomem();
while ((node = uu_avl_walk_next(walk)) != NULL) {
uu_avl_remove(cb.cb_avl, node);
zfs_close(node->zn_handle);
free(node);
}
avl_destroy(&cb.cb_avl);
uu_avl_walk_end(walk);
uu_avl_destroy(cb.cb_avl);
uu_avl_pool_destroy(avl_pool);
return (ret);
}

File diff suppressed because it is too large Load Diff

View File

@ -52,16 +52,13 @@
#include <sys/zio_compress.h>
#include <sys/zfeature.h>
#include <sys/dmu_tx.h>
#include <sys/backtrace.h>
#include <zfeature_common.h>
#include <libzutil.h>
#include <sys/metaslab_impl.h>
#include <libzpool.h>
static importargs_t g_importargs;
static char *g_pool;
static boolean_t g_readonly;
static boolean_t g_dump_dbgmsg;
typedef enum {
ZHACK_REPAIR_OP_UNKNOWN = 0,
@ -73,23 +70,12 @@ static __attribute__((noreturn)) void
usage(void)
{
(void) fprintf(stderr,
"Usage: zhack [-o tunable] [-c cachefile] [-d dir] [-G] "
"<subcommand> <args> ...\n"
" where <subcommand> <args> is one of the following:\n"
"Usage: zhack [-o tunable] [-c cachefile] [-d dir] <subcommand> "
"<args> ...\n"
"where <subcommand> <args> is one of the following:\n"
"\n");
(void) fprintf(stderr,
" global options:\n"
" -c <cachefile> reads config from the given cachefile\n"
" -d <dir> directory with vdevs for import\n"
" -o var=value... set global variable to an unsigned "
"32-bit integer\n"
" -G dump zfs_dbgmsg buffer before exiting\n"
"\n"
" action idle <pool> [-f] [-t seconds]\n"
" import the pool for a set time then export it\n"
" -t <seconds> sets the time the pool is imported\n"
"\n"
" feature stat <pool>\n"
" print information about enabled features\n"
" feature enable [-r] [-d desc] <pool> <feature>\n"
@ -116,39 +102,6 @@ usage(void)
exit(1);
}
static void
dump_debug_buffer(void)
{
ssize_t ret __attribute__((unused));
if (!g_dump_dbgmsg)
return;
/*
* We use write() instead of printf() so that this function
* is safe to call from a signal handler.
*/
ret = write(STDERR_FILENO, "\n", 1);
zfs_dbgmsg_print(STDERR_FILENO, "zhack");
}
static void sig_handler(int signo)
{
struct sigaction action;
libspl_backtrace(STDERR_FILENO);
dump_debug_buffer();
/*
* Restore default action and re-raise signal so SIGSEGV and
* SIGABRT can trigger a core dump.
*/
action.sa_handler = SIG_DFL;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
(void) sigaction(signo, &action, NULL);
raise(signo);
}
static __attribute__((format(printf, 3, 4))) __attribute__((noreturn)) void
fatal(spa_t *spa, const void *tag, const char *fmt, ...)
@ -166,8 +119,6 @@ fatal(spa_t *spa, const void *tag, const char *fmt, ...)
va_end(ap);
(void) fputc('\n', stderr);
dump_debug_buffer();
exit(1);
}
@ -554,79 +505,6 @@ zhack_do_feature(int argc, char **argv)
return (0);
}
static void
zhack_do_action_idle(int argc, char **argv)
{
spa_t *spa;
char *target, *tmp;
int idle_time = 0;
int c;
optind = 1;
while ((c = getopt(argc, argv, "+t:")) != -1) {
switch (c) {
case 't':
idle_time = strtol(optarg, &tmp, 0);
if (*tmp) {
(void) fprintf(stderr, "error: time must "
"be an integer in seconds: %s\n", tmp);
usage();
}
if (idle_time < 0) {
(void) fprintf(stderr, "error: time must "
"not be negative: %d\n", idle_time);
usage();
}
break;
default:
usage();
break;
}
}
argc -= optind;
argv += optind;
if (argc < 1) {
(void) fprintf(stderr, "error: missing pool name\n");
usage();
}
target = argv[0];
zhack_spa_open(target, B_FALSE, FTAG, &spa);
fprintf(stdout, "Imported pool %s, idle for %d seconds\n",
target, idle_time);
sleep(idle_time);
spa_close(spa, FTAG);
}
static int
zhack_do_action(int argc, char **argv)
{
char *subcommand;
argc--;
argv++;
if (argc == 0) {
(void) fprintf(stderr,
"error: no import operation specified\n");
usage();
}
subcommand = argv[0];
if (strcmp(subcommand, "idle") == 0) {
zhack_do_action_idle(argc, argv);
} else {
(void) fprintf(stderr, "error: unknown subcommand: %s\n",
subcommand);
usage();
}
return (0);
}
static boolean_t
strstarts(const char *a, const char *b)
{
@ -745,11 +623,8 @@ zhack_do_metaslab_leak(int argc, char **argv)
&start, &size), ==, 2);
ASSERT(vd);
size_t idx;
idx = start >> vd->vdev_ms_shift;
if (idx >= vd->vdev_ms_count)
continue;
metaslab_t *cur = vd->vdev_ms[idx];
metaslab_t *cur =
vd->vdev_ms[start >> vd->vdev_ms_shift];
if (prev != cur) {
if (prev) {
dmu_tx_commit(tx);
@ -1307,35 +1182,17 @@ zhack_do_label(int argc, char **argv)
int
main(int argc, char **argv)
{
struct sigaction action;
char *path[MAX_NUM_PATHS];
const char *subcommand;
int rv = 0;
int c;
/*
* Set up signal handlers, so if we crash due to bad on-disk data we
* can get more info. Unlike ztest, we don't bail out if we can't set
* up signal handlers, because zhack is very useful without them.
*/
action.sa_handler = sig_handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGSEGV, &action, NULL) < 0) {
(void) fprintf(stderr, "zhack: cannot catch SIGSEGV: %s\n",
strerror(errno));
}
if (sigaction(SIGABRT, &action, NULL) < 0) {
(void) fprintf(stderr, "zhack: cannot catch SIGABRT: %s\n",
strerror(errno));
}
g_importargs.path = path;
dprintf_setup(&argc, argv);
zfs_prop_init();
while ((c = getopt(argc, argv, "+c:d:Go:")) != -1) {
while ((c = getopt(argc, argv, "+c:d:o:")) != -1) {
switch (c) {
case 'c':
g_importargs.cachefile = optarg;
@ -1344,9 +1201,6 @@ main(int argc, char **argv)
assert(g_importargs.paths < MAX_NUM_PATHS);
g_importargs.path[g_importargs.paths++] = optarg;
break;
case 'G':
g_dump_dbgmsg = B_TRUE;
break;
case 'o':
if (handle_tunable_option(optarg, B_FALSE) != 0)
exit(1);
@ -1368,9 +1222,7 @@ main(int argc, char **argv)
subcommand = argv[0];
if (strcmp(subcommand, "action") == 0) {
rv = zhack_do_action(argc, argv);
} else if (strcmp(subcommand, "feature") == 0) {
if (strcmp(subcommand, "feature") == 0) {
rv = zhack_do_feature(argc, argv);
} else if (strcmp(subcommand, "label") == 0) {
return (zhack_do_label(argc, argv));
@ -1387,9 +1239,6 @@ main(int argc, char **argv)
"changes may not be committed to disk\n");
}
if (g_dump_dbgmsg)
dump_debug_buffer();
kernel_fini();
return (rv);

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
sbin_PROGRAMS += zinject
CPPCHECKTARGETS += zinject

View File

@ -85,7 +85,7 @@ static int
parse_pathname(const char *inpath, char *dataset, char *relpath,
struct stat64 *statbuf)
{
struct mnttab mp;
struct extmnttab mp;
const char *rel;
char fullpath[MAXPATHLEN];

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
zpool_CFLAGS = $(AM_CFLAGS)
zpool_CFLAGS += $(LIBBLKID_CFLAGS) $(LIBUUID_CFLAGS)
@ -29,6 +28,7 @@ zpool_LDADD = \
libzfs.la \
libzfs_core.la \
libnvpair.la \
libuutil.la \
libzutil.la
zpool_LDADD += $(LTLIBINTL)

View File

@ -30,10 +30,12 @@
*/
#include <libintl.h>
#include <libuutil.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread_pool.h>
#include <libzfs.h>
#include <libzutil.h>
@ -50,28 +52,30 @@
typedef struct zpool_node {
zpool_handle_t *zn_handle;
avl_node_t zn_avlnode;
uu_avl_node_t zn_avlnode;
hrtime_t zn_last_refresh;
} zpool_node_t;
struct zpool_list {
boolean_t zl_findall;
boolean_t zl_literal;
avl_tree_t zl_avl;
uu_avl_t *zl_avl;
uu_avl_pool_t *zl_pool;
zprop_list_t **zl_proplist;
zfs_type_t zl_type;
hrtime_t zl_last_refresh;
};
static int
zpool_compare(const void *larg, const void *rarg)
zpool_compare(const void *larg, const void *rarg, void *unused)
{
(void) unused;
zpool_handle_t *l = ((zpool_node_t *)larg)->zn_handle;
zpool_handle_t *r = ((zpool_node_t *)rarg)->zn_handle;
const char *lname = zpool_get_name(l);
const char *rname = zpool_get_name(r);
return (TREE_ISIGN(strcmp(lname, rname)));
return (strcmp(lname, rname));
}
/*
@ -82,11 +86,12 @@ static int
add_pool(zpool_handle_t *zhp, zpool_list_t *zlp)
{
zpool_node_t *node, *new = safe_malloc(sizeof (zpool_node_t));
avl_index_t idx;
uu_avl_index_t idx;
new->zn_handle = zhp;
uu_avl_node_init(new, &new->zn_avlnode, zlp->zl_pool);
node = avl_find(&zlp->zl_avl, new, &idx);
node = uu_avl_find(zlp->zl_avl, new, NULL, &idx);
if (node == NULL) {
if (zlp->zl_proplist &&
zpool_expand_proplist(zhp, zlp->zl_proplist,
@ -96,7 +101,7 @@ add_pool(zpool_handle_t *zhp, zpool_list_t *zlp)
return (-1);
}
new->zn_last_refresh = zlp->zl_last_refresh;
avl_insert(&zlp->zl_avl, new, idx);
uu_avl_insert(zlp->zl_avl, new, idx);
} else {
zpool_refresh_stats_from_handle(node->zn_handle, zhp);
node->zn_last_refresh = zlp->zl_last_refresh;
@ -134,8 +139,15 @@ pool_list_get(int argc, char **argv, zprop_list_t **proplist, zfs_type_t type,
zlp = safe_malloc(sizeof (zpool_list_t));
avl_create(&zlp->zl_avl, zpool_compare,
sizeof (zpool_node_t), offsetof(zpool_node_t, zn_avlnode));
zlp->zl_pool = uu_avl_pool_create("zfs_pool", sizeof (zpool_node_t),
offsetof(zpool_node_t, zn_avlnode), zpool_compare, UU_DEFAULT);
if (zlp->zl_pool == NULL)
zpool_no_memory();
if ((zlp->zl_avl = uu_avl_create(zlp->zl_pool, NULL,
UU_DEFAULT)) == NULL)
zpool_no_memory();
zlp->zl_proplist = proplist;
zlp->zl_type = type;
@ -182,8 +194,8 @@ pool_list_refresh(zpool_list_t *zlp)
* state.
*/
int navail = 0;
for (zpool_node_t *node = avl_first(&zlp->zl_avl);
node != NULL; node = AVL_NEXT(&zlp->zl_avl, node)) {
for (zpool_node_t *node = uu_avl_first(zlp->zl_avl);
node != NULL; node = uu_avl_next(zlp->zl_avl, node)) {
boolean_t missing;
zpool_refresh_stats(node->zn_handle, &missing);
navail += !missing;
@ -197,8 +209,8 @@ pool_list_refresh(zpool_list_t *zlp)
/* Walk the list of existing pools, and update or remove them. */
zpool_node_t *node, *next;
for (node = avl_first(&zlp->zl_avl); node != NULL; node = next) {
next = AVL_NEXT(&zlp->zl_avl, node);
for (node = uu_avl_first(zlp->zl_avl); node != NULL; node = next) {
next = uu_avl_next(zlp->zl_avl, node);
/*
* Skip any that were refreshed and are online; they were added
@ -212,7 +224,7 @@ pool_list_refresh(zpool_list_t *zlp)
boolean_t missing;
zpool_refresh_stats(node->zn_handle, &missing);
if (missing) {
avl_remove(&zlp->zl_avl, node);
uu_avl_remove(zlp->zl_avl, node);
zpool_close(node->zn_handle);
free(node);
} else {
@ -220,7 +232,7 @@ pool_list_refresh(zpool_list_t *zlp)
}
}
return (avl_numnodes(&zlp->zl_avl));
return (uu_avl_numnodes(zlp->zl_avl));
}
/*
@ -233,8 +245,8 @@ pool_list_iter(zpool_list_t *zlp, int unavail, zpool_iter_f func,
zpool_node_t *node, *next_node;
int ret = 0;
for (node = avl_first(&zlp->zl_avl); node != NULL; node = next_node) {
next_node = AVL_NEXT(&zlp->zl_avl, node);
for (node = uu_avl_first(zlp->zl_avl); node != NULL; node = next_node) {
next_node = uu_avl_next(zlp->zl_avl, node);
if (zpool_get_state(node->zn_handle) != POOL_STATE_UNAVAIL ||
unavail)
ret |= func(node->zn_handle, data);
@ -249,15 +261,25 @@ pool_list_iter(zpool_list_t *zlp, int unavail, zpool_iter_f func,
void
pool_list_free(zpool_list_t *zlp)
{
uu_avl_walk_t *walk;
zpool_node_t *node;
void *cookie = NULL;
while ((node = avl_destroy_nodes(&zlp->zl_avl, &cookie)) != NULL) {
if ((walk = uu_avl_walk_start(zlp->zl_avl, UU_WALK_ROBUST)) == NULL) {
(void) fprintf(stderr,
gettext("internal error: out of memory"));
exit(1);
}
while ((node = uu_avl_walk_next(walk)) != NULL) {
uu_avl_remove(zlp->zl_avl, node);
zpool_close(node->zn_handle);
free(node);
}
avl_destroy(&zlp->zl_avl);
uu_avl_walk_end(walk);
uu_avl_destroy(zlp->zl_avl);
uu_avl_pool_destroy(zlp->zl_pool);
free(zlp);
}
@ -267,7 +289,7 @@ pool_list_free(zpool_list_t *zlp)
int
pool_list_count(zpool_list_t *zlp)
{
return (avl_numnodes(&zlp->zl_avl));
return (uu_avl_numnodes(zlp->zl_avl));
}
/*
@ -652,21 +674,21 @@ all_pools_for_each_vdev_gather_cb(zpool_handle_t *zhp, void *cb_vcdl)
static void
all_pools_for_each_vdev_run_vcdl(vdev_cmd_data_list_t *vcdl)
{
taskq_t *tq = taskq_create("vdev_run_cmd",
5 * sysconf(_SC_NPROCESSORS_ONLN), minclsyspri, 1, INT_MAX,
TASKQ_DYNAMIC);
if (tq == NULL)
tpool_t *t;
t = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN), 0, NULL);
if (t == NULL)
return;
/* Spawn off the command for each vdev */
for (int i = 0; i < vcdl->count; i++) {
(void) taskq_dispatch(tq, vdev_run_cmd_thread,
(void *) &vcdl->data[i], TQ_SLEEP);
(void) tpool_dispatch(t, vdev_run_cmd_thread,
(void *) &vcdl->data[i]);
}
/* Wait for threads to finish */
taskq_wait(tq);
taskq_destroy(tq);
tpool_wait(t);
tpool_destroy(t);
}
/*

View File

@ -46,12 +46,14 @@
#include <inttypes.h>
#include <libgen.h>
#include <libintl.h>
#include <libuutil.h>
#include <locale.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <thread_pool.h>
#include <time.h>
#include <unistd.h>
#include <pwd.h>
@ -458,7 +460,7 @@ get_usage(zpool_help_t idx)
return (gettext("\tattach [-fsw] [-o property=value] "
"<pool> <vdev> <new-device>\n"));
case HELP_CLEAR:
return (gettext("\tclear [--power] <pool> [device]\n"));
return (gettext("\tclear [[--power]|[-nF]] <pool> [device]\n"));
case HELP_CREATE:
return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
"\t [-O file-system-property=value] ... \n"
@ -2388,7 +2390,7 @@ zpool_do_destroy(int argc, char **argv)
}
typedef struct export_cbdata {
taskq_t *taskq;
tpool_t *tpool;
pthread_mutex_t mnttab_lock;
boolean_t force;
boolean_t hardforce;
@ -2413,12 +2415,12 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
* zpool_disable_datasets() is not thread-safe for mnttab access.
* So we serialize access here for 'zpool export -a' parallel case.
*/
if (cb->taskq != NULL)
if (cb->tpool != NULL)
(void) pthread_mutex_lock(&cb->mnttab_lock);
int retval = zpool_disable_datasets(zhp, cb->force);
if (cb->taskq != NULL)
if (cb->tpool != NULL)
(void) pthread_mutex_unlock(&cb->mnttab_lock);
if (retval)
@ -2462,7 +2464,7 @@ zpool_export_task(void *arg)
static int
zpool_export_one_async(zpool_handle_t *zhp, void *data)
{
taskq_t *tq = ((export_cbdata_t *)data)->taskq;
tpool_t *tpool = ((export_cbdata_t *)data)->tpool;
async_export_args_t *aea = safe_malloc(sizeof (async_export_args_t));
/* save pool name since zhp will go out of scope */
@ -2470,8 +2472,7 @@ zpool_export_one_async(zpool_handle_t *zhp, void *data)
aea->aea_cbdata = data;
/* ship off actual export to another thread */
if (taskq_dispatch(tq, zpool_export_task, (void *)aea,
TQ_SLEEP) == TASKQID_INVALID)
if (tpool_dispatch(tpool, zpool_export_task, (void *)aea) != 0)
return (errno); /* unlikely */
else
return (0);
@ -2517,7 +2518,7 @@ zpool_do_export(int argc, char **argv)
cb.force = force;
cb.hardforce = hardforce;
cb.taskq = NULL;
cb.tpool = NULL;
cb.retval = 0;
argc -= optind;
argv += optind;
@ -2531,17 +2532,16 @@ zpool_do_export(int argc, char **argv)
usage(B_FALSE);
}
cb.taskq = taskq_create("zpool_export",
5 * sysconf(_SC_NPROCESSORS_ONLN), minclsyspri, 1, INT_MAX,
TASKQ_DYNAMIC);
cb.tpool = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN),
0, NULL);
(void) pthread_mutex_init(&cb.mnttab_lock, NULL);
/* Asynchronously call zpool_export_one using thread pool */
ret = for_each_pool(argc, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
B_FALSE, zpool_export_one_async, &cb);
taskq_wait(cb.taskq);
taskq_destroy(cb.taskq);
tpool_wait(cb.tpool);
tpool_destroy(cb.tpool);
(void) pthread_mutex_destroy(&cb.mnttab_lock);
return (ret | cb.retval);
@ -3456,7 +3456,7 @@ show_import(nvlist_t *config, boolean_t report_error)
case ZPOOL_STATUS_CORRUPT_POOL:
(void) printf_color(ANSI_YELLOW, gettext("The pool metadata is "
"incomplete or corrupted.\n"));
"corrupted.\n"));
break;
case ZPOOL_STATUS_VERSION_OLDER:
@ -3704,12 +3704,6 @@ show_import(nvlist_t *config, boolean_t report_error)
(void) printf(gettext("Set a unique system hostid with "
"the zgenhostid(8) command.\n"));
break;
case ZPOOL_STATUS_CORRUPT_POOL:
(void) printf(gettext("The pool cannot be imported due "
"to missing or damaged devices. Ensure\n"
"\t%sall devices are present and not in use by "
"another subsystem.\n"), indent);
break;
default:
(void) printf(gettext("The pool cannot be imported due "
"to damaged devices or data.\n"));
@ -3885,9 +3879,6 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
hostid, ctime(&timestamp));
}
if (getenv("ZFS_LOAD_INFO_DEBUG"))
dump_nvlist(nvinfo, 4);
return (1);
}
@ -3955,11 +3946,10 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
uint_t npools = 0;
taskq_t *tq = NULL;
tpool_t *tp = NULL;
if (import->do_all) {
tq = taskq_create("zpool_import_all",
5 * sysconf(_SC_NPROCESSORS_ONLN), minclsyspri, 1, INT_MAX,
TASKQ_DYNAMIC);
tp = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN),
0, NULL);
}
/*
@ -4008,8 +3998,8 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
ip->ip_mntthreads = mount_tp_nthr / npools;
ip->ip_err = &err;
(void) taskq_dispatch(tq, do_import_task,
(void *)ip, TQ_SLEEP);
(void) tpool_dispatch(tp, do_import_task,
(void *)ip);
} else {
/*
* If we're importing from cachefile, then
@ -4058,8 +4048,8 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
}
}
if (import->do_all) {
taskq_wait(tq);
taskq_destroy(tq);
tpool_wait(tp);
tpool_destroy(tp);
}
/*
@ -6960,19 +6950,7 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
switch (prop) {
case ZPOOL_PROP_SIZE:
case ZPOOL_PROP_NORMAL_SIZE:
case ZPOOL_PROP_SPECIAL_SIZE:
case ZPOOL_PROP_DEDUP_SIZE:
case ZPOOL_PROP_LOG_SIZE:
case ZPOOL_PROP_ELOG_SIZE:
case ZPOOL_PROP_SELOG_SIZE:
case ZPOOL_PROP_EXPANDSZ:
case ZPOOL_PROP_NORMAL_EXPANDSZ:
case ZPOOL_PROP_SPECIAL_EXPANDSZ:
case ZPOOL_PROP_DEDUP_EXPANDSZ:
case ZPOOL_PROP_LOG_EXPANDSZ:
case ZPOOL_PROP_ELOG_EXPANDSZ:
case ZPOOL_PROP_SELOG_EXPANDSZ:
case ZPOOL_PROP_CHECKPOINT:
case ZPOOL_PROP_DEDUPRATIO:
case ZPOOL_PROP_DEDUPCACHED:
@ -6983,12 +6961,6 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
format);
break;
case ZPOOL_PROP_FRAGMENTATION:
case ZPOOL_PROP_NORMAL_FRAGMENTATION:
case ZPOOL_PROP_SPECIAL_FRAGMENTATION:
case ZPOOL_PROP_DEDUP_FRAGMENTATION:
case ZPOOL_PROP_LOG_FRAGMENTATION:
case ZPOOL_PROP_ELOG_FRAGMENTATION:
case ZPOOL_PROP_SELOG_FRAGMENTATION:
if (value == ZFS_FRAG_INVALID) {
(void) strlcpy(propval, "-", sizeof (propval));
} else if (format == ZFS_NICENUM_RAW) {
@ -7000,12 +6972,6 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
}
break;
case ZPOOL_PROP_CAPACITY:
case ZPOOL_PROP_NORMAL_CAPACITY:
case ZPOOL_PROP_SPECIAL_CAPACITY:
case ZPOOL_PROP_DEDUP_CAPACITY:
case ZPOOL_PROP_LOG_CAPACITY:
case ZPOOL_PROP_ELOG_CAPACITY:
case ZPOOL_PROP_SELOG_CAPACITY:
/* capacity value is in parts-per-10,000 (aka permyriad) */
if (format == ZFS_NICENUM_RAW)
(void) snprintf(propval, sizeof (propval), "%llu",
@ -7039,6 +7005,7 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
/*
* print static default line per vdev
* not compatible with '-o' <proplist> option
*/
static void
collect_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
@ -7092,98 +7059,48 @@ collect_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
* 'toplevel' boolean value is passed to the print_one_column()
* to indicate that the value is valid.
*/
for (zprop_list_t *pl = cb->cb_proplist; pl != NULL;
pl = pl->pl_next) {
switch (pl->pl_prop) {
case ZPOOL_PROP_SIZE:
if (VDEV_STAT_VALID(vs_pspace, c) &&
vs->vs_pspace) {
collect_vdev_prop(
ZPOOL_PROP_SIZE, vs->vs_pspace,
NULL, scripted, B_TRUE, format,
cb->cb_json, props,
if (VDEV_STAT_VALID(vs_pspace, c) && vs->vs_pspace) {
collect_vdev_prop(ZPOOL_PROP_SIZE, vs->vs_pspace, NULL,
scripted, B_TRUE, format, cb->cb_json, props,
cb->cb_json_as_int);
} else {
collect_vdev_prop(
ZPOOL_PROP_SIZE, vs->vs_space, NULL,
scripted, toplevel, format,
cb->cb_json, props,
collect_vdev_prop(ZPOOL_PROP_SIZE, vs->vs_space, NULL,
scripted, toplevel, format, cb->cb_json, props,
cb->cb_json_as_int);
}
break;
case ZPOOL_PROP_ALLOCATED:
collect_vdev_prop(ZPOOL_PROP_ALLOCATED,
vs->vs_alloc, NULL, scripted, toplevel,
format, cb->cb_json, props,
collect_vdev_prop(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, NULL,
scripted, toplevel, format, cb->cb_json, props,
cb->cb_json_as_int);
break;
case ZPOOL_PROP_FREE:
collect_vdev_prop(ZPOOL_PROP_FREE,
vs->vs_space - vs->vs_alloc, NULL, scripted,
toplevel, format, cb->cb_json, props,
collect_vdev_prop(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
NULL, scripted, toplevel, format, cb->cb_json, props,
cb->cb_json_as_int);
break;
case ZPOOL_PROP_CHECKPOINT:
collect_vdev_prop(ZPOOL_PROP_CHECKPOINT,
vs->vs_checkpoint_space, NULL, scripted,
toplevel, format, cb->cb_json, props,
cb->cb_json_as_int);
break;
case ZPOOL_PROP_EXPANDSZ:
collect_vdev_prop(ZPOOL_PROP_EXPANDSZ,
vs->vs_esize, NULL, scripted, B_TRUE,
format, cb->cb_json, props,
cb->cb_json_as_int);
break;
case ZPOOL_PROP_FRAGMENTATION:
collect_vdev_prop(
ZPOOL_PROP_FRAGMENTATION,
vs->vs_fragmentation, NULL, scripted,
(vs->vs_fragmentation != ZFS_FRAG_INVALID &&
toplevel),
format, cb->cb_json, props,
cb->cb_json_as_int);
break;
case ZPOOL_PROP_CAPACITY:
cap = (vs->vs_space == 0) ?
0 : (vs->vs_alloc * 10000 / vs->vs_space);
collect_vdev_prop(ZPOOL_PROP_CAPACITY, cap,
NULL, scripted, toplevel, format,
vs->vs_checkpoint_space, NULL, scripted, toplevel, format,
cb->cb_json, props, cb->cb_json_as_int);
break;
case ZPOOL_PROP_HEALTH:
state = zpool_state_to_name(vs->vs_state,
vs->vs_aux);
collect_vdev_prop(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, NULL,
scripted, B_TRUE, format, cb->cb_json, props,
cb->cb_json_as_int);
collect_vdev_prop(ZPOOL_PROP_FRAGMENTATION,
vs->vs_fragmentation, NULL, scripted,
(vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel),
format, cb->cb_json, props, cb->cb_json_as_int);
cap = (vs->vs_space == 0) ? 0 :
(vs->vs_alloc * 10000 / vs->vs_space);
collect_vdev_prop(ZPOOL_PROP_CAPACITY, cap, NULL,
scripted, toplevel, format, cb->cb_json, props,
cb->cb_json_as_int);
collect_vdev_prop(ZPOOL_PROP_DEDUPRATIO, 0, NULL,
scripted, toplevel, format, cb->cb_json, props,
cb->cb_json_as_int);
state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
if (isspare) {
if (vs->vs_aux == VDEV_AUX_SPARED)
state = "INUSE";
else if (vs->vs_state ==
VDEV_STATE_HEALTHY)
else if (vs->vs_state == VDEV_STATE_HEALTHY)
state = "AVAIL";
}
collect_vdev_prop(ZPOOL_PROP_HEALTH, 0, state,
scripted, B_TRUE, format, cb->cb_json,
props, cb->cb_json_as_int);
break;
case ZPOOL_PROP_NAME:
break;
default:
collect_vdev_prop(pl->pl_prop, 0,
NULL, scripted, B_FALSE, format,
cb->cb_json, props, cb->cb_json_as_int);
}
}
collect_vdev_prop(ZPOOL_PROP_HEALTH, 0, state, scripted,
B_TRUE, format, cb->cb_json, props, cb->cb_json_as_int);
if (cb->cb_json) {
fnvlist_add_nvlist(ent, "properties", props);
@ -8251,7 +8168,7 @@ zpool_do_offline(int argc, char **argv)
}
/*
* zpool clear [--power] <pool> [device]
* zpool clear [-nF]|[--power] <pool> [device]
*
* Clear all errors associated with a pool or a particular device.
*/
@ -8260,7 +8177,11 @@ zpool_do_clear(int argc, char **argv)
{
int c;
int ret = 0;
boolean_t dryrun = B_FALSE;
boolean_t do_rewind = B_FALSE;
boolean_t xtreme_rewind = B_FALSE;
boolean_t is_power_on = B_FALSE;
uint32_t rewind_policy = ZPOOL_NO_REWIND;
nvlist_t *policy = NULL;
zpool_handle_t *zhp;
char *pool, *device;
@ -8271,9 +8192,18 @@ zpool_do_clear(int argc, char **argv)
};
/* check options */
while ((c = getopt_long(argc, argv, "", long_options,
while ((c = getopt_long(argc, argv, "FnX", long_options,
NULL)) != -1) {
switch (c) {
case 'F':
do_rewind = B_TRUE;
break;
case 'n':
dryrun = B_TRUE;
break;
case 'X':
xtreme_rewind = B_TRUE;
break;
case ZPOOL_OPTION_POWER:
is_power_on = B_TRUE;
break;
@ -8300,8 +8230,24 @@ zpool_do_clear(int argc, char **argv)
usage(B_FALSE);
}
if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0)
if ((dryrun || xtreme_rewind) && !do_rewind) {
(void) fprintf(stderr,
gettext("-n or -X only meaningful with -F\n"));
usage(B_FALSE);
}
if (dryrun)
rewind_policy = ZPOOL_TRY_REWIND;
else if (do_rewind)
rewind_policy = ZPOOL_DO_REWIND;
if (xtreme_rewind)
rewind_policy |= ZPOOL_EXTREME_REWIND;
/* In future, further rewind policy choices can be passed along here */
if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY,
rewind_policy) != 0) {
return (1);
}
pool = argv[0];
device = argc == 2 ? argv[1] : NULL;
@ -10495,7 +10441,7 @@ print_dedup_stats(zpool_handle_t *zhp, nvlist_t *config, boolean_t literal)
(uint64_t **)&dds, &c) == 0);
verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
(uint64_t **)&ddh, &c) == 0);
zpool_dump_ddt(dds, ddh, literal);
zpool_dump_ddt(dds, ddh);
}
#define ST_SIZE 4096
@ -10617,8 +10563,7 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp,
case ZPOOL_STATUS_CORRUPT_POOL:
(void) snprintf(status, ST_SIZE, gettext("The pool metadata is "
"incomplete or corrupted and the pool cannot be "
"opened.\n"));
"corrupted and the pool cannot be opened.\n"));
zpool_explain_recover(zpool_get_handle(zhp),
zpool_get_name(zhp), reason, zpool_get_config(zhp, NULL),
action, AC_SIZE);
@ -13784,7 +13729,7 @@ zpool_do_help(int argc, char **argv)
(void) execlp("man", "man", page, NULL);
fprintf(stderr, "couldn't run man program: %s\n", strerror(errno));
fprintf(stderr, "couldn't run man program: %s", strerror(errno));
return (-1);
}

View File

@ -114,3 +114,29 @@ array64_max(uint64_t array[], unsigned int len)
return (max);
}
/*
* Find highest one bit set.
* Returns bit number + 1 of highest bit that is set, otherwise returns 0.
*/
int
highbit64(uint64_t i)
{
if (i == 0)
return (0);
return (NBBY * sizeof (uint64_t) - __builtin_clzll(i));
}
/*
* Find lowest one bit set.
* Returns bit number + 1 of lowest bit that is set, otherwise returns 0.
*/
int
lowbit64(uint64_t i)
{
if (i == 0)
return (0);
return (__builtin_ffsll(i));
}

View File

@ -45,6 +45,8 @@ void *safe_realloc(void *, size_t);
void zpool_no_memory(void);
uint_t num_logs(nvlist_t *nv);
uint64_t array64_max(uint64_t array[], unsigned int len);
int highbit64(uint64_t i);
int lowbit64(uint64_t i);
/*
* Misc utility functions

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
zfsexec_PROGRAMS += zpool_influxdb
CPPCHECKTARGETS += zpool_influxdb

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
zstream_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS)
sbin_PROGRAMS += zstream
@ -8,13 +7,10 @@ zstream_SOURCES = \
%D%/zstream.c \
%D%/zstream.h \
%D%/zstream_decompress.c \
%D%/zstream_drop_record.c \
%D%/zstream_dump.c \
%D%/zstream_recompress.c \
%D%/zstream_redup.c \
%D%/zstream_token.c \
%D%/zstream_util.c \
%D%/zstream_util.h
%D%/zstream_token.c
zstream_LDADD = \
libzfs.la \

View File

@ -43,8 +43,6 @@ zstream_usage(void)
"\n"
"\tzstream decompress [-v] [OBJECT,OFFSET[,TYPE]] ...\n"
"\n"
"\tzstream drop_record [-v] [OBJECT,OFFSET] ...\n"
"\n"
"\tzstream recompress [ -l level] TYPE\n"
"\n"
"\tzstream token resume_token\n"
@ -70,8 +68,6 @@ main(int argc, char *argv[])
return (zstream_do_dump(argc - 1, argv + 1));
} else if (strcmp(subcommand, "decompress") == 0) {
return (zstream_do_decompress(argc - 1, argv + 1));
} else if (strcmp(subcommand, "drop_record") == 0) {
return (zstream_do_drop_record(argc - 1, argv + 1));
} else if (strcmp(subcommand, "recompress") == 0) {
return (zstream_do_recompress(argc - 1, argv + 1));
} else if (strcmp(subcommand, "token") == 0) {

View File

@ -25,10 +25,12 @@
extern "C" {
#endif
extern void *safe_calloc(size_t n);
extern int sfread(void *buf, size_t size, FILE *fp);
extern void *safe_malloc(size_t size);
extern int zstream_do_redup(int, char *[]);
extern int zstream_do_dump(int, char *[]);
extern int zstream_do_decompress(int argc, char *argv[]);
extern int zstream_do_drop_record(int argc, char *argv[]);
extern int zstream_do_recompress(int argc, char *argv[]);
extern int zstream_do_token(int, char *[]);
extern void zstream_usage(void);

View File

@ -37,7 +37,31 @@
#include <sys/zstd/zstd.h>
#include "zfs_fletcher.h"
#include "zstream.h"
#include "zstream_util.h"
static int
dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
zio_cksum_t *zc, int outfd)
{
assert(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum)
== sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
fletcher_4_incremental_native(drr,
offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
if (drr->drr_type != DRR_BEGIN) {
assert(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
drr_checksum.drr_checksum));
drr->drr_u.drr_checksum.drr_checksum = *zc;
}
fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
sizeof (zio_cksum_t), zc);
if (write(outfd, drr, sizeof (*drr)) == -1)
return (errno);
if (payload_len != 0) {
fletcher_4_incremental_native(payload, payload_len, zc);
if (write(outfd, payload, payload_len) == -1)
return (errno);
}
return (0);
}
int
zstream_do_decompress(int argc, char *argv[])

View File

@ -1,324 +0,0 @@
// SPDX-License-Identifier: CDDL-1.0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2026 ConnectWise. All rights reserved.
* Use is subject to license terms.
*/
#include <err.h>
#include <search.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/zfs_ioctl.h>
#include <sys/zio_checksum.h>
#include <sys/zstd/zstd.h>
#include "zfs_fletcher.h"
#include "zstream.h"
#include "zstream_util.h"
int
zstream_do_drop_record(int argc, char *argv[])
{
const int KEYSIZE = 64;
int bufsz = SPA_MAXBLOCKSIZE;
char *buf = safe_malloc(bufsz);
dmu_replay_record_t thedrr;
dmu_replay_record_t *drr = &thedrr;
zio_cksum_t stream_cksum;
int c;
boolean_t verbose = B_FALSE;
while ((c = getopt(argc, argv, "v")) != -1) {
switch (c) {
case 'v':
verbose = B_TRUE;
break;
case '?':
(void) fprintf(stderr, "invalid option '%c'\n",
optopt);
zstream_usage();
break;
}
}
argc -= optind;
argv += optind;
if (argc < 0)
zstream_usage();
if (hcreate(argc) == 0)
errx(1, "hcreate");
for (int i = 0; i < argc; i++) {
uint64_t object, offset;
char *obj_str;
char *offset_str;
char *key;
char *end;
obj_str = strsep(&argv[i], ",");
if (argv[i] == NULL) {
zstream_usage();
exit(2);
}
errno = 0;
object = strtoull(obj_str, &end, 0);
if (errno || *end != '\0')
errx(1, "invalid value for object");
offset_str = strsep(&argv[i], ",");
offset = strtoull(offset_str, &end, 0);
if (errno || *end != '\0')
errx(1, "invalid value for offset");
if (asprintf(&key, "%llu,%llu", (u_longlong_t)object,
(u_longlong_t)offset) < 0) {
err(1, "asprintf");
}
ENTRY e = {.key = key};
ENTRY *p;
p = hsearch(e, ENTER);
if (p == NULL)
errx(1, "hsearch");
p->data = (void*)(intptr_t)B_TRUE;
}
if (isatty(STDIN_FILENO)) {
(void) fprintf(stderr,
"Error: The send stream is a binary format "
"and can not be read from a\n"
"terminal. Standard input must be redirected.\n");
exit(1);
}
fletcher_4_init();
int begin = 0;
boolean_t seen = B_FALSE;
while (sfread(drr, sizeof (*drr), stdin) != 0) {
struct drr_write *drrw;
uint64_t payload_size = 0;
/*
* We need to regenerate the checksum.
*/
if (drr->drr_type != DRR_BEGIN) {
memset(&drr->drr_u.drr_checksum.drr_checksum, 0,
sizeof (drr->drr_u.drr_checksum.drr_checksum));
}
switch (drr->drr_type) {
case DRR_BEGIN:
{
ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
VERIFY0(begin++);
seen = B_TRUE;
uint32_t sz = drr->drr_payloadlen;
VERIFY3U(sz, <=, 1U << 28);
if (sz != 0) {
if (sz > bufsz) {
buf = realloc(buf, sz);
if (buf == NULL)
err(1, "realloc");
bufsz = sz;
}
(void) sfread(buf, sz, stdin);
}
payload_size = sz;
break;
}
case DRR_END:
{
struct drr_end *drre = &drr->drr_u.drr_end;
/*
* We would prefer to just check --begin == 0, but
* replication streams have an end of stream END
* record, so we must avoid tripping it.
*/
VERIFY3B(seen, ==, B_TRUE);
begin--;
/*
* Use the recalculated checksum, unless this is
* the END record of a stream package, which has
* no checksum.
*/
if (!ZIO_CHECKSUM_IS_ZERO(&drre->drr_checksum))
drre->drr_checksum = stream_cksum;
break;
}
case DRR_OBJECT:
{
struct drr_object *drro = &drr->drr_u.drr_object;
VERIFY3S(begin, ==, 1);
if (drro->drr_bonuslen > 0) {
payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro);
(void) sfread(buf, payload_size, stdin);
}
break;
}
case DRR_SPILL:
{
struct drr_spill *drrs = &drr->drr_u.drr_spill;
VERIFY3S(begin, ==, 1);
payload_size = DRR_SPILL_PAYLOAD_SIZE(drrs);
(void) sfread(buf, payload_size, stdin);
break;
}
case DRR_WRITE_BYREF:
VERIFY3S(begin, ==, 1);
fprintf(stderr,
"Deduplicated streams are not supported\n");
exit(1);
break;
case DRR_WRITE:
{
VERIFY3S(begin, ==, 1);
drrw = &thedrr.drr_u.drr_write;
payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
ENTRY *p;
char key[KEYSIZE];
snprintf(key, KEYSIZE, "%llu,%llu",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
ENTRY e = {.key = key};
(void) sfread(buf, payload_size, stdin);
p = hsearch(e, FIND);
if (p == NULL) {
/*
* Dump the contents of the block unaltered
*/
} else {
/*
* Read and discard the block
*/
if (verbose)
fprintf(stderr,
"Dropping WRITE record for object "
"%llu offset %llu\n",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
continue;
}
break;
}
case DRR_WRITE_EMBEDDED:
{
ENTRY *p;
char key[KEYSIZE];
VERIFY3S(begin, ==, 1);
struct drr_write_embedded *drrwe =
&drr->drr_u.drr_write_embedded;
payload_size =
P2ROUNDUP((uint64_t)drrwe->drr_psize, 8);
snprintf(key, KEYSIZE, "%llu,%llu",
(u_longlong_t)drrwe->drr_object,
(u_longlong_t)drrwe->drr_offset);
ENTRY e = {.key = key};
(void) sfread(buf, payload_size, stdin);
p = hsearch(e, FIND);
if (p == NULL) {
/*
* Dump the contents of the block unaltered
*/
} else {
/*
* Read and discard the block
*/
if (verbose)
fprintf(stderr,
"Dropping WRITE_EMBEDDED record for"
" object %llu offset %llu\n",
(u_longlong_t)drrwe->drr_object,
(u_longlong_t)drrwe->drr_offset);
continue;
}
break;
}
case DRR_FREEOBJECTS:
case DRR_FREE:
case DRR_OBJECT_RANGE:
VERIFY3S(begin, ==, 1);
break;
default:
(void) fprintf(stderr, "INVALID record type 0x%x\n",
drr->drr_type);
/* should never happen, so assert */
assert(B_FALSE);
}
if (feof(stdout)) {
fprintf(stderr, "Error: unexpected end-of-file\n");
exit(1);
}
if (ferror(stdout)) {
fprintf(stderr, "Error while reading file: %s\n",
strerror(errno));
exit(1);
}
/*
* We need to recalculate the checksum, and it needs to be
* initially zero to do that. BEGIN records don't have
* a checksum.
*/
if (drr->drr_type != DRR_BEGIN) {
memset(&drr->drr_u.drr_checksum.drr_checksum, 0,
sizeof (drr->drr_u.drr_checksum.drr_checksum));
}
if (dump_record(drr, buf, payload_size,
&stream_cksum, STDOUT_FILENO) != 0)
break;
if (drr->drr_type == DRR_END) {
/*
* Typically the END record is either the last
* thing in the stream, or it is followed
* by a BEGIN record (which also zeros the checksum).
* However, a stream package ends with two END
* records. The last END record's checksum starts
* from zero.
*/
ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
}
}
free(buf);
fletcher_4_fini();
hdestroy();
return (0);
}

View File

@ -44,7 +44,6 @@
#include <sys/zio.h>
#include <zfs_fletcher.h>
#include "zstream.h"
#include "zstream_util.h"
/*
* If dump mode is enabled, the number of bytes to print per line
@ -61,6 +60,18 @@ static FILE *send_stream = 0;
static boolean_t do_byteswap = B_FALSE;
static boolean_t do_cksum = B_TRUE;
void *
safe_malloc(size_t size)
{
void *rv = malloc(size);
if (rv == NULL) {
(void) fprintf(stderr, "ERROR; failed to allocate %zu bytes\n",
size);
abort();
}
return (rv);
}
/*
* ssread - send stream read.
*

View File

@ -37,7 +37,31 @@
#include <sys/zstd/zstd.h>
#include "zfs_fletcher.h"
#include "zstream.h"
#include "zstream_util.h"
static int
dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
zio_cksum_t *zc, int outfd)
{
assert(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum)
== sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
fletcher_4_incremental_native(drr,
offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
if (drr->drr_type != DRR_BEGIN) {
assert(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
drr_checksum.drr_checksum));
drr->drr_u.drr_checksum.drr_checksum = *zc;
}
fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
sizeof (zio_cksum_t), zc);
if (write(outfd, drr, sizeof (*drr)) == -1)
return (errno);
if (payload_len != 0) {
fletcher_4_incremental_native(payload, payload_len, zc);
if (write(outfd, payload, payload_len) == -1)
return (errno);
}
return (0);
}
int
zstream_do_recompress(int argc, char *argv[])

View File

@ -37,7 +37,6 @@
#include <sys/zio_checksum.h>
#include "zfs_fletcher.h"
#include "zstream.h"
#include "zstream_util.h"
#define MAX_RDT_PHYSMEM_PERCENT 20
@ -58,6 +57,34 @@ typedef struct redup_table {
int numhashbits;
} redup_table_t;
void *
safe_calloc(size_t n)
{
void *rv = calloc(1, n);
if (rv == NULL) {
fprintf(stderr,
"Error: could not allocate %u bytes of memory\n",
(int)n);
exit(1);
}
return (rv);
}
/*
* Safe version of fread(), exits on error.
*/
int
sfread(void *buf, size_t size, FILE *fp)
{
int rv = fread(buf, size, 1, fp);
if (rv == 0 && ferror(fp)) {
(void) fprintf(stderr, "Error while reading file: %s\n",
strerror(errno));
exit(1);
}
return (rv);
}
/*
* Safe version of pread(), exits on error.
*/
@ -77,6 +104,31 @@ spread(int fd, void *buf, size_t count, off_t offset)
}
}
static int
dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
zio_cksum_t *zc, int outfd)
{
assert(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum)
== sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
fletcher_4_incremental_native(drr,
offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
if (drr->drr_type != DRR_BEGIN) {
assert(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
drr_checksum.drr_checksum));
drr->drr_u.drr_checksum.drr_checksum = *zc;
}
fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
sizeof (zio_cksum_t), zc);
if (write(outfd, drr, sizeof (*drr)) == -1)
return (errno);
if (payload_len != 0) {
fletcher_4_incremental_native(payload, payload_len, zc);
if (write(outfd, payload, payload_len) == -1)
return (errno);
}
return (0);
}
static void
rdt_insert(redup_table_t *rdt,
uint64_t guid, uint64_t object, uint64_t offset, uint64_t stream_offset)
@ -139,9 +191,9 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
#ifdef _ILP32
uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20;
#else
uint64_t physbytes = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
uint64_t max_rde_size =
MAX((physbytes * MAX_RDT_PHYSMEM_PERCENT) / 100,
MAX((physmem * MAX_RDT_PHYSMEM_PERCENT) / 100,
SMALLEST_POSSIBLE_MAX_RDT_MB << 20);
#endif

View File

@ -1,106 +0,0 @@
// SPDX-License-Identifier: CDDL-1.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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved
* Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
* Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
* Copyright (c) 2019 Datto Inc.
* Copyright (c) 2024, Klara, Inc.
*/
#include <sys/debug.h>
#include <stddef.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <zfs_fletcher.h>
#include "zstream_util.h"
/*
* From libzfs_sendrecv.c
*/
int
dump_record(dmu_replay_record_t *drr, void *payload, size_t payload_len,
zio_cksum_t *zc, int outfd)
{
ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
fletcher_4_incremental_native(drr,
offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
if (drr->drr_type != DRR_BEGIN) {
ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
drr_checksum.drr_checksum));
drr->drr_u.drr_checksum.drr_checksum = *zc;
}
fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
sizeof (zio_cksum_t), zc);
if (write(outfd, drr, sizeof (*drr)) == -1)
return (errno);
if (payload_len != 0) {
fletcher_4_incremental_native(payload, payload_len, zc);
if (write(outfd, payload, payload_len) == -1)
return (errno);
}
return (0);
}
void *
safe_malloc(size_t size)
{
void *rv = malloc(size);
if (rv == NULL) {
(void) fprintf(stderr, "Error: failed to allocate %zu bytes\n",
size);
exit(1);
}
return (rv);
}
void *
safe_calloc(size_t size)
{
void *rv = calloc(1, size);
if (rv == NULL) {
(void) fprintf(stderr,
"Error: failed to allocate %zu bytes\n", size);
exit(1);
}
return (rv);
}
/*
* Safe version of fread(), exits on error.
*/
int
sfread(void *buf, size_t size, FILE *fp)
{
int rv = fread(buf, size, 1, fp);
if (rv == 0 && ferror(fp)) {
(void) fprintf(stderr, "Error while reading file: %s\n",
strerror(errno));
exit(1);
}
return (rv);
}

View File

@ -1,60 +0,0 @@
// SPDX-License-Identifier: CDDL-1.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) 2026 by Garth Snyder. All rights reserved.
*/
#ifndef _ZSTREAM_UTIL_H
#define _ZSTREAM_UTIL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <sys/zfs_ioctl.h>
#include <sys/zio_checksum.h>
/*
* The safe_ versions of the functions below terminate the process if the
* operation doesn't succeed instead of returning an error.
*/
extern void *
safe_malloc(size_t size);
extern void *
safe_calloc(size_t n);
extern int
sfread(void *buf, size_t size, FILE *fp);
/*
* 1) Update checksum with the record header up to drr_checksum.
* 2) Update checksum field in the record header.
* 3) Update checksum with the checksum field in the record header.
* 4) Update checksum with the contents of the payload.
* 5) Write header and payload to fd.
*/
extern int
dump_record(dmu_replay_record_t *drr, void *payload, size_t payload_len,
zio_cksum_t *zc, int outfd);
#ifdef __cplusplus
}
#endif
#endif /* _ZSTREAM_UTIL_H */

View File

@ -139,10 +139,9 @@
#include <sys/crypto/icp.h>
#include <sys/zfs_impl.h>
#include <sys/backtrace.h>
#include <libzpool.h>
#include <libspl.h>
static int ztest_fd_data = -1;
static int ztest_fd_rand = -1;
typedef struct ztest_shared_hdr {
uint64_t zh_hdr_size;
@ -903,10 +902,13 @@ ztest_random(uint64_t range)
{
uint64_t r;
ASSERT3S(ztest_fd_rand, >=, 0);
if (range == 0)
return (0);
random_get_pseudo_bytes((uint8_t *)&r, sizeof (r));
if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r))
fatal(B_TRUE, "short read from /dev/urandom");
return (r % range);
}
@ -7144,7 +7146,6 @@ static void
ztest_get_zdb_bin(char *bin, int len)
{
char *zdb_path;
char *resolved;
/*
* Try to use $ZDB and in-tree zdb path. If not successful, just
* let popen to search through PATH.
@ -7158,11 +7159,7 @@ ztest_get_zdb_bin(char *bin, int len)
return;
}
resolved = realpath(getexecname(), NULL);
VERIFY3P(resolved, !=, NULL);
strlcpy(bin, resolved, len);
free(resolved);
VERIFY3P(realpath(getexecname(), bin), !=, NULL);
if (strstr(bin, ".libs/ztest")) {
strstr(bin, ".libs/ztest")[0] = '\0'; /* In-tree */
strcat(bin, "zdb");
@ -8148,8 +8145,10 @@ ztest_raidz_expand_run(ztest_shared_t *zs, spa_t *spa)
/* Setup a 1 MiB buffer of random data */
uint64_t bufsize = 1024 * 1024;
void *buffer = umem_alloc(bufsize, UMEM_NOFAIL);
random_get_pseudo_bytes((uint8_t *)buffer, bufsize);
if (read(ztest_fd_rand, buffer, bufsize) != bufsize) {
fatal(B_TRUE, "short read from /dev/urandom");
}
/*
* Put some data in the pool and then attach a vdev to initiate
* reflow.
@ -8955,13 +8954,13 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
libspl_init();
/*
* Force random_get_bytes() to use /dev/urandom in order to prevent
* ztest from needlessly depleting the system entropy pool.
*/
random_force_pseudo(B_TRUE);
random_path = "/dev/urandom";
ztest_fd_rand = open(random_path, O_RDONLY | O_CLOEXEC);
ASSERT3S(ztest_fd_rand, >=, 0);
if (!fd_data_str) {
process_options(argc, argv);

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
#
# cppcheck for userspace nodist_*_SOURCES are kernel code and cppcheck goes crazy on them.
#

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
#
# Default build rules for all user space components, every Makefile.am
# should include these rules and override or extend them as needed.
@ -7,12 +6,11 @@
PHONY =
AM_CPPFLAGS = \
-include $(top_builddir)/zfs_config.h \
-include $(top_srcdir)/include/sys/simd_config.h \
-I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/module/icp/include \
-I$(top_srcdir)/lib/libspl/include \
-I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@ \
-I$(top_srcdir)/lib/libzpool/include
-I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@
AM_LIBTOOLFLAGS = --silent

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
# Global ShellCheck exclusions:
#
# ShellCheck can't follow non-constant source. Use a directive to specify location. [SC1090]

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
subst_sed_cmd = \
-e 's|@abs_top_srcdir[@]|$(abs_top_srcdir)|g' \
-e 's|@bindir[@]|$(bindir)|g' \

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Set the target cpu architecture. This allows the
dnl # following syntax to be used in a Makefile.am.

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Enabled -fsanitize=address if supported by $CC.
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Check if cppcheck is available.
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Check if GNU parallel is available.
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # The majority of the python scripts are written to be compatible
dnl # with Python 3.6. This option is intended to

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # ZFS_AC_PYTHON_MODULE(module_name, [action-if-true], [action-if-false])
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Set the flags used for sed in-place edits.
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Check if shellcheck and/or checkbashisms are available.
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Set the target system
dnl #

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: FSFAP
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
# ===========================================================================

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: FSFAP
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_count_cpus.html
# ===========================================================================

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: GPL-3.0-or-later WITH Autoconf-exception-macro
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_python_devel.html
# ===========================================================================

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: FSFAP
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_restore_flags.html
# ===========================================================================

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: FSFAP
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_save_flags.html
# ===========================================================================

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: CDDL-1.0
PHONY += deb-kmod deb-dkms deb-utils deb deb-local native-deb-local \
native-deb-utils native-deb-kmod native-deb
@ -58,21 +57,22 @@ deb-utils: deb-local rpm-utils-initramfs
debarch=`$(DPKG) --print-architecture`; \
pkg1=$${name}-$${version}.$${arch}.rpm; \
pkg2=libnvpair3-$${version}.$${arch}.rpm; \
pkg3=libzfs7-$${version}.$${arch}.rpm; \
pkg4=libzpool7-$${version}.$${arch}.rpm; \
pkg5=libzfs7-devel-$${version}.$${arch}.rpm; \
pkg6=$${name}-test-$${version}.$${arch}.rpm; \
pkg7=$${name}-dracut-$${version}.noarch.rpm; \
pkg8=$${name}-initramfs-$${version}.$${arch}.rpm; \
pkg9=`ls python3-pyzfs-$${version}.noarch.rpm 2>/dev/null`; \
pkg10=`ls pam_zfs_key-$${version}.$${arch}.rpm 2>/dev/null`; \
pkg3=libuutil3-$${version}.$${arch}.rpm; \
pkg4=libzfs7-$${version}.$${arch}.rpm; \
pkg5=libzpool7-$${version}.$${arch}.rpm; \
pkg6=libzfs7-devel-$${version}.$${arch}.rpm; \
pkg7=$${name}-test-$${version}.$${arch}.rpm; \
pkg8=$${name}-dracut-$${version}.noarch.rpm; \
pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
pkg10=`ls python3-pyzfs-$${version}.noarch.rpm 2>/dev/null`; \
pkg11=`ls pam_zfs_key-$${version}.$${arch}.rpm 2>/dev/null`; \
## Arguments need to be passed to dh_shlibdeps. Alien provides no mechanism
## to do this, so we install a shim onto the path which calls the real
## dh_shlibdeps with the required arguments.
path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \
echo "#!$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
echo "`which dh_shlibdeps` -- \
-xlibnvpair3linux -xlibzfs7linux -xlibzpool7linux" \
-xlibuutil3linux -xlibnvpair3linux -xlibzfs7linux -xlibzpool7linux" \
>> $${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,

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
# find_system_lib.m4 - Macros to search for a system library. -*- Autoconf -*-
dnl requires pkg.m4 from pkg-config

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: FSFULLR
# gettext.m4 serial 70 (gettext-0.20)
dnl Copyright (C) 1995-2014, 2016, 2018 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: FSFULLR
# host-cpu-c-abi.m4 serial 11
dnl Copyright (C) 2002-2019 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation

View File

@ -1,4 +1,3 @@
# SPDX-License-Identifier: FSFULLR
# iconv.m4 serial 21
dnl Copyright (C) 2000-2002, 2007-2014, 2016-2019 Free Software Foundation,
dnl Inc.

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Linux 5.0: access_ok() drops 'type' parameter:
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 3.1 API change,
dnl # posix_acl_equiv_mode now wants an umode_t instead of a mode_t
@ -22,35 +21,6 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
])
])
dnl #
dnl # 7.0 API change
dnl # posix_acl_to_xattr() now allocates and returns the value.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_TO_XATTR_ALLOC], [
ZFS_LINUX_TEST_SRC([posix_acl_to_xattr_alloc], [
#include <linux/fs.h>
#include <linux/posix_acl_xattr.h>
], [
struct user_namespace *ns = NULL;
struct posix_acl *acl = NULL;
size_t size = 0;
gfp_t gfp = 0;
void *xattr = NULL;
xattr = posix_acl_to_xattr(ns, acl, &size, gfp);
])
])
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_TO_XATTR_ALLOC], [
AC_MSG_CHECKING([whether posix_acl_to_xattr() allocates its result]);
ZFS_LINUX_TEST_RESULT([posix_acl_to_xattr_alloc], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_POSIX_ACL_TO_XATTR_ALLOC, 1,
[posix_acl_to_xattr() allocates its result])
], [
AC_MSG_RESULT(no)
])
])
dnl #
dnl # 3.1 API change,
dnl # Check if inode_operations contains the function get_acl
@ -203,14 +173,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL], [
ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
ZFS_AC_KERNEL_SRC_POSIX_ACL_TO_XATTR_ALLOC
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL
])
AC_DEFUN([ZFS_AC_KERNEL_ACL], [
ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
ZFS_AC_KERNEL_POSIX_ACL_TO_XATTR_ALLOC
ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
])

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 5.16 API change
dnl # add_disk grew a must-check return code

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 6.10 kernel, check number of args of __assign_str() for trace:
dnl

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 2.6.37 API change
dnl # The dops->d_automount() dentry operation was added as a clean

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Linux 4.8 API,
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 5.12 API change removes BIO_MAX_PAGES in favor of bio_max_segs()
dnl # which will handle the logic of setting the upper-bound to a

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 2.6.39 API change,
dnl # blk_start_plug() and blk_finish_plug()
@ -226,30 +225,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS], [
])
])
dnl #
dnl # 7.0 API change
dnl # blk_queue_rot() replaces blk_queue_nonrot() (inverted meaning)
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_ROT], [
ZFS_LINUX_TEST_SRC([blk_queue_rot], [
#include <linux/blkdev.h>
], [
struct request_queue *q __attribute__ ((unused)) = NULL;
(void) blk_queue_rot(q);
], [])
])
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_ROT], [
AC_MSG_CHECKING([whether blk_queue_rot() is available])
ZFS_LINUX_TEST_RESULT([blk_queue_rot], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLK_QUEUE_ROT, 1,
[blk_queue_rot() is available])
],[
AC_MSG_RESULT(no)
])
])
dnl #
dnl # 2.6.34 API change
dnl # blk_queue_max_segments() consolidates blk_queue_max_hw_segments()
@ -303,7 +278,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_HW_SECTORS
ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_SEGMENTS
ZFS_AC_KERNEL_SRC_BLK_QUEUE_ROT
ZFS_AC_KERNEL_SRC_BLK_MQ_RQ_HCTX
])
@ -316,6 +290,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE], [
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS
ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS
ZFS_AC_KERNEL_BLK_QUEUE_ROT
ZFS_AC_KERNEL_BLK_MQ_RQ_HCTX
])

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 2.6.38 API change,
dnl # Added blkdev_get_by_path()

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 2.6.38 API change
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 2.6.33 API change
dnl # Added eops->commit_metadata() callback to allow the underlying

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Certain kernel build options are not supported. These must be
dnl # detected at configure time and cause a build failure. Otherwise

View File

@ -0,0 +1,29 @@
dnl #
dnl # On certain architectures `__copy_from_user_inatomic`
dnl # is a GPL exported variable and cannot be used by OpenZFS.
dnl #
dnl #
dnl # Checking if `__copy_from_user_inatomic` is available.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC___COPY_FROM_USER_INATOMIC], [
ZFS_LINUX_TEST_SRC([__copy_from_user_inatomic], [
#include <linux/uaccess.h>
], [
int result __attribute__ ((unused)) = __copy_from_user_inatomic(NULL, NULL, 0);
], [], [ZFS_META_LICENSE])
])
AC_DEFUN([ZFS_AC_KERNEL___COPY_FROM_USER_INATOMIC], [
AC_MSG_CHECKING([whether __copy_from_user_inatomic is available])
ZFS_LINUX_TEST_RESULT([__copy_from_user_inatomic_license], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_MSG_ERROR([
*** The `__copy_from_user_inatomic()` Linux kernel function is
*** incompatible with the CDDL license and will prevent the module
*** linking stage from succeeding. OpenZFS cannot be compiled.
])
])
])

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # cpu_has_feature() may referencing GPL-only cpu_feature_keys on powerpc
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Ensure the DECLARE_EVENT_CLASS macro is available to non-GPL modules.
dnl #

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 2.6.28 API change
dnl # Added d_obtain_alias() helper function.

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 2.6.33 API change
dnl # Discard granularity and alignment restrictions may now be set.

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 6.18 API change
dnl # - generic_drop_inode() renamed to inode_generic_drop()

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 6.12 removed f_version from struct file
dnl #

View File

@ -1,23 +0,0 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 6.3 API change
dnl # locking support functions (eg generic_setlease) were moved out of
dnl # linux/fs.h to linux/filelock.h
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_FILELOCK_HEADER], [
ZFS_LINUX_TEST_SRC([filelock_header], [
#include <linux/fs.h>
#include <linux/filelock.h>
], [])
])
AC_DEFUN([ZFS_AC_KERNEL_FILELOCK_HEADER], [
AC_MSG_CHECKING([for standalone filelock header])
ZFS_LINUX_TEST_RESULT([filelock_header], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_FILELOCK_HEADER, 1, [linux/filelock.h exists])
], [
AC_MSG_RESULT(no)
])
])

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
AC_DEFUN([ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ], [
dnl #
dnl # Kernel 6.5 - generic_file_splice_read was removed in favor

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Starting from Linux 5.13, flush_dcache_page() becomes an inline
dnl # function and may indirectly referencing GPL-only symbols:

View File

@ -1,4 +1,3 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # 2.6.28 API change,
dnl # check if fmode_t typedef is defined

Some files were not shown because too many files have changed in this diff Show More