LLVM/project b3b1a5f — llvm/lib/Target/AMDGPU/AsmParser AMDGPUAsmParser.cpp, llvm/test/MC/AMDGPU reloc-operands-vopd.s

[AMDGPU][MC] Fixed an issue where VOPD instruction doesn't accept a relocatable symbol

Fixes LCOMPILER-2797.
DeltaFile
+21-0llvm/test/MC/AMDGPU/reloc-operands-vopd.s
+8-2llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+29-22 files

LLVM/project ff5453f — clang/lib/AST ExprConstant.cpp, clang/test/SemaCXX new-nothrow-by-value.cpp

[Clang][ExprConst] Accept prvalue for nothrow new

A user defined operator new can accept prvalue for nothrow. There is
no guarantee in spec that it should be lvalue. Relax the check with
side effect only.
DeltaFile
+18-0clang/test/SemaCXX/new-nothrow-by-value.cpp
+5-2clang/lib/AST/ExprConstant.cpp
+23-22 files

LLVM/project 0905c19 — clang/test/CodeGen/RISCV lto-module-asm-abi.c

[Clang][RISC-V] Fix lto-module-asm-abi.c on non-asserts/no-lld builds

Pass `-fno-discard-value-names` so the `entry:` label is preserved in
non-asserts builds, and drop `-fuse-ld=lld` so the driver check succeeds
on bots that do not have `ld.lld` installed.

Fixes: bf529329b5ce ("[RISC-V][LTO] Add baseline tests for LTO inline assembly and mapping symbols (#225129)")
DeltaFile
+3-3clang/test/CodeGen/RISCV/lto-module-asm-abi.c
+3-31 files

LLVM/project 32ee4f7 — llvm/include/llvm/CodeGen SDPatternMatch.h

[SDPatternMatch] Simplify EffectiveOperands and drop the template specialization. NFC (#226036)

The chain and glue operands are in fixed locations, we don't need a loop
to find them.

Use the template parameter to skip the constructor body instead of using
template specialization.
DeltaFile
+9-18llvm/include/llvm/CodeGen/SDPatternMatch.h
+9-181 files

OpenBSD/ports 3IJ87Nn — sysutils/fastfetch distinfo Makefile

   Update fastfetch to 2.69.0
VersionDeltaFile
1.19+2-2sysutils/fastfetch/distinfo
1.19+2-2sysutils/fastfetch/Makefile
+4-42 files

FreeNAS/freenas a911a44 — src/middlewared/middlewared/plugins/zfs set_rules.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_resource_set.py test_set_rules.py

Refuse volsize changes on read-only and locked volumes in zfs.resource.set

## Problem
ZFS applies each property in a request on its own, and it refuses a `volsize` change on a read-only or locked volume while still writing the rest of the request. When a thick volume was grown through `zfs.resource.set`, the `refreservation=auto` added to keep it thick was therefore written even though the resize failed, leaving a larger reservation on a volume that never grew. The same happened with a caller-supplied `refreservation`, and a `readonly: off` sent in the same request was applied even though ZFS still judged the resize against the stored read-only value. The resize tests brought in from master, and one S3 bucket test, also still called `zfs.resource.query`, and the resize tests expected the old `pool.dataset.update` error text.

## Solution
Added a set rule that rejects any `volsize` in the request while the volume is currently read-only or locked, so nothing is written and the caller is told to turn read-only off or unlock the volume first. `keystatus` is now read alongside the other properties so the rule can tell a locked volume apart. The resize and S3 bucket integration tests use `zfs.resource.list`, the resize tests expect the new messages, and there is a new case covering a grow that also turns `readonly` off.
DeltaFile
+62-1src/middlewared/middlewared/pytest/unit/plugins/zfs/test_set_rules.py
+22-1src/middlewared/middlewared/plugins/zfs/set_rules.py
+15-5tests/api2/test_zvol_resize.py
+1-1tests/api2/test_s3_bucket.py
+2-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_resource_set.py
+102-85 files

LLVM/project e54a8d1 — llvm/cmake/modules GetLibraryName.cmake

[cmake][Windows] Fix CMake variable (#226745)

As a follow-up fix to #226635, the variable is `WIN32` not `Win32`.
DeltaFile
+1-1llvm/cmake/modules/GetLibraryName.cmake
+1-11 files

FreeBSD/ports 7efdef5 — www/hs-postgrest Makefile Makefile.cabal

www/hs-postgrest: Update 16.2 => 16.4
DeltaFile
+9-5www/hs-postgrest/distinfo
+3-3www/hs-postgrest/Makefile.cabal
+1-1www/hs-postgrest/Makefile
+13-93 files

FreeNAS/freenas 7605918 — src/middlewared/middlewared/plugins/iscsi_ extents.py, src/middlewared/middlewared/plugins/nvmet namespace.py

Move locked-path check to zfs.resource and tell snapshots from directories

## Problem
Resolving any `@` in the locked-path check to its dataset stopped the snapshot crash, but it also made an ordinary directory like `/mnt/tank/data at old` report locked whenever a sibling dataset `tank/data` was locked. The `@` can't simply be stripped from authoritative forms only either, because iSCSI, NVMe-oF and VM hand snapshot-backed zvols over as `/mnt/<zvol>@<snap>`.

## Solution
The check now lives in the private `zfs.resource.path_is_locked` endpoint, and `pool.dataset.path_in_locked_datasets` is a thin shim to it. A snapshot is detected by the resource type libzfs returns and resolved to its dataset, which is also matched against the about-to-lock dataset. Under `/mnt` only a zvol snapshot counts, and parent components containing `@` are skipped during the walk, so directories resolve to the dataset they actually live in. Internal callers call the new endpoint directly.
DeltaFile
+2-75src/middlewared/middlewared/plugins/pool_/dataset_encryption_info.py
+73-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_path_is_locked.py
+68-0src/middlewared/middlewared/plugins/zfs/path_is_locked_impl.py
+0-60src/middlewared/middlewared/pytest/unit/plugins/pool/test_path_in_locked_datasets.py
+3-11src/middlewared/middlewared/plugins/nvmet/namespace.py
+3-11src/middlewared/middlewared/plugins/iscsi_/extents.py
+149-15712 files not shown
+176-17718 files

FreeNAS/freenas 6203968 — src/middlewared/middlewared/plugins/iscsi_ zfs_delegate.py, src/middlewared/middlewared/pytest/unit/plugins/iscsi test_zfs_delegate.py

Encode zvol names when matching snapshot devices to iSCSI extents

## Problem
The iSCSI extent delegate looked up extents on the snapshot devices about to be hidden by `zvol/<dataset>@<snap>` built from the raw dataset name, but an extent stores its path in the encoded form where a space becomes `+`. A zvol or snapshot with a space in its name therefore never matched, and `snapdev=hidden` removed the device node from under a live extent, which the attachment scan it replaced caught correctly.

## Solution
Build the lookup paths with `zvol_name_to_path`, the same encoder the extent disk choices come from, and pin it with unit tests over names containing spaces, including the exact path list passed to `iscsi.extent.query`.
DeltaFile
+42-4src/middlewared/middlewared/pytest/unit/plugins/iscsi/test_zfs_delegate.py
+2-1src/middlewared/middlewared/plugins/iscsi_/zfs_delegate.py
+44-52 files

FreeNAS/freenas 9ae822c — src/middlewared/middlewared/plugins/zfs set_rules.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_set_rules.py

Allow switching dedup between ON and VERIFY on tiered datasets

## Problem
The dedup tiering checks in `zfs.resource.set` fired whenever the dedup value changed, so `pool.dataset.update` rejected ON <-> VERIFY on a PERFORMANCE dataset or on a parent with PERFORMANCE descendants. The old pool.dataset validation deliberately skipped datasets that already had dedup in effect, since such a switch changes neither where data lives nor whether it is deduplicated.

## Solution
Both checks now only run when dedup goes from off to on (the `special_small_blocks` arm of the tiering check is unchanged). The rule matrix fixture was moved to an off -> on transition to match.
DeltaFile
+2-2src/middlewared/middlewared/plugins/zfs/set_rules.py
+3-1src/middlewared/middlewared/pytest/unit/plugins/zfs/test_set_rules.py
+5-32 files

FreeNAS/freenas 993bcc9 — tests/api2 test_pool_dataset_update_shim.py

Assert the raw copies value in the pool.dataset.update shim test

## Problem
The test compared `copies` from `zfs.resource.list` against the integer 2, but `copies` is an index property in ZFS, so its parsed value comes back as the string label "2" and the assertion failed on every run.

## Solution
Assert the raw value "2", matching how the neighbouring dedup and compression tests check what ZFS stored.
DeltaFile
+1-1tests/api2/test_pool_dataset_update_shim.py
+1-11 files

FreeNAS/freenas b558f0e — src/middlewared/middlewared/api/v27_0_0 pool_dataset.py, src/middlewared/middlewared/plugins/pool_ dataset.py

Point pool.dataset.update at zfs.resource.set

`pool.dataset.update` carried its own copy of every ZFS policy check (ACL coupling, headroom, blocksize alignment, recordsize choices, dedup licensing, SMB/snapdev guards, LUN resyncs) and wrote through the raw `update_impl`, so the two write paths could drift and the pool path skipped whatever `zfs.resource.set` and its delegates enforce.

Translate the pool payload into a `zfs.resource.set` request (lowercasing the index values the pool Literals uppercase, passing sizes and `copies` as ints, `quota: null` as 0, `INHERIT` and removed user properties as `inherit`) and let `zfs.resource.set` and its delegates validate and write. The update validation keeps only the field-shape rejections and the `user_properties_update` handling; everything else, the resyncs and the `ZFSException` mapping go.

When the shim itself already found errors, the request is run through `zfs.resource.set` as a `dry_run` so the caller still gets shim-side and zfs-side errors in one `ValidationErrors`. The request model is built inside the same `try`, so a value the zfs models reject comes back as a validation error rather than a raw pydantic one. Errors are re-keyed onto `pool_dataset_update.<field>`: the property's own field when the caller sent it, `acltype` for the derived `aclmode`/`aclinherit`, `volsize` for the re-reservation a volsize grow triggers, `user_properties_update`/`user_properties` for the caller's own user properties, and bare `pool_dataset_update` for anything structural.

Behaviour changes worth knowing: `copies` outside 1..3 and a negative `reservation` are now rejected; the recordsize and shrink messages come from the zfs rules; the ACL combination error lands on `acltype` rather than `aclmode`; a ZFS failure is keyed on `pool_dataset_update` instead of `pool.dataset.update`; the dRAID volblocksize check on update is gone, and `force_size` no longer bypasses the headroom check (its description says so). An empty payload still skips the write and emits CHANGED.
DeltaFile
+83-248src/middlewared/middlewared/plugins/pool_/dataset.py
+156-0tests/api2/test_pool_dataset_update_shim.py
+150-0src/middlewared/middlewared/pytest/unit/plugins/pool/test_dataset_update_shim.py
+8-0src/middlewared/middlewared/api/v27_0_0/pool_dataset.py
+1-1tests/sharing_protocols/nvmet/test_nvmet_tcp.py
+1-1tests/api2/test_draid_record_and_block_size.py
+399-2506 files

FreeNAS/freenas 2e7515f — src/middlewared/middlewared/plugins/pool_ dataset_encryption_info.py, src/middlewared/middlewared/pytest/unit/plugins/pool test_path_in_locked_datasets.py

Resolve snapshot names to their dataset in the locked-path check

## Problem
`pool.dataset.path_in_locked_datasets` opened the resource named by the path and read its `crypto()`; a snapshot-backed iSCSI extent, NVMe-oF namespace or VM disk (`zvol/<dataset>@<snap>`) therefore reached it with an `@` name, pylibzfs returned a snapshot object with no `crypto`, and the AttributeError escaped, so `iscsi.extent.create` on such an extent inserted its row and then crashed in `get_instance`, and every later extent query failed on the orphan.

## Solution
A snapshot holds no keys, so its lock state is its dataset's: strip the snapshot suffix before the parent walk, which also lets the ancestor-prefix check see the dataset. Pinned with a unit test over the three accepted path forms.
DeltaFile
+60-0src/middlewared/middlewared/pytest/unit/plugins/pool/test_path_in_locked_datasets.py
+3-0src/middlewared/middlewared/plugins/pool_/dataset_encryption_info.py
+63-02 files

FreeNAS/freenas a5d702a — src/middlewared/middlewared/plugins/zfs resource.py resource_set.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_delegates.py

Add a delegate registry to zfs.resource.set

## Problem
Other plugins' policy on a property change (share ACL constraints, LUN resyncs, snapshot-device visibility) lived inline in `pool.dataset.update`, so `zfs.resource.set` could not enforce it and every new consumer of the raw namespace would have had to re-implement it.

## Solution
Add a delegate registry to `zfs.resource`: a delegate declares the resource types and property names it cares about, validates into the same `ValidationErrors` as the intrinsic rules before anything is written, and runs its side effects after a successful write, where a failure is logged and never breaks the write's return. Both hooks are coroutines, bridged once per phase from the thread `set` runs on and skipped when no delegate participates. A volume's present snapshot devices are handed to delegates when the request touches `snapdev`. The mechanism is pinned with fake delegates; the real registrants follow separately.
DeltaFile
+335-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_delegates.py
+96-0src/middlewared/middlewared/plugins/zfs/delegates.py
+23-2src/middlewared/middlewared/plugins/zfs/resource_set.py
+14-1src/middlewared/middlewared/plugins/zfs/resource.py
+468-34 files

FreeNAS/freenas b31543a — src/middlewared/middlewared/plugins/zfs resource_set.py set_rules.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_resource_set.py test_set_rules.py

Validate type validity, headroom, blocksize alignment and ACL coupling in zfs.resource.set

## Problem
With the effective-state machinery in place, `zfs.resource.set` still accepted properties invalid for the target type, inherits of values that replication would immediately bring back, a reservation grow with no headroom, a volsize that is not a multiple of the volblocksize, dedup on a dataset whose descendants are tiered, an out-of-range recordsize and an out-of-range `special_small_blocks`. The ACL companions of `acltype` were also filled in before the resource was read, so an `acltype` on a volume fanned out into three errors, and a thick zvol grow left its reservation behind.

## Solution
Add the remaining intrinsic rules to the registry, couple the ACL companions after the read on filesystems only, and follow a thick zvol's reservation on grow with libzfs's own `auto` so its rollback stays live and an over-reservation is never lowered. Names middleware adds on the caller's behalf are recorded as derived, and errors about them are attributed to the field the caller actually sent.
DeltaFile
+458-18src/middlewared/middlewared/pytest/unit/plugins/zfs/test_set_rules.py
+181-2src/middlewared/middlewared/plugins/zfs/set_rules.py
+155-6tests/api2/test_zfs_resource_set.py
+49-2src/middlewared/middlewared/pytest/unit/plugins/zfs/test_resource_set.py
+11-20src/middlewared/middlewared/plugins/zfs/resource_set.py
+854-485 files

FreeNAS/freenas 31a271d — src/middlewared/middlewared/api/v27_0_0 zfs_resource_crud.py, src/middlewared/middlewared/plugins/zfs resource_set.py set_rules.py

Resolve effective state before writing in zfs.resource.set

## Problem
`zfs.resource.set` validated each rule against the target's current value, so an inherited property was judged by the dataset's own value instead of its parent's (`inherit=["dedup"]` could not be gated at all). Rules raised one at a time, a bug inside a rule surfaced as a 500 instead of a validation failure, the dataset was read with a property set that varied per request, and the tier config was read on every call.

## Solution
- **One fixed read**: the target, plus its parent only when a native is inherited on a non-root dataset, is read once with a fixed property set. A missing target is a `ValidationError` on `path` (ENOENT); the tier config and the DEDUP entitlement are read only when the request touches the properties they govern.
- **Effective state**: a frozen `SetContext` resolves every property through `effective()` (requested value, else the parent's value or the registered ZFS default on a pool root, else the current value). Values live in a `PropertyView` that raises `CallError` for a name that was not read.
- **Aggregated rules**: the request rules run before any I/O and report together. The volsize, ACL, tiering and dedup rules are listed once in `SET_RULES` and report into one `ValidationErrors`; `validate_set` never raises, and a rule that breaks is logged and makes the request fail closed with a `CallError` only when nothing else was reported.
- **Dry run**: a middleware-only `dry_run` flag validates the request and returns the current values of the touched properties without writing.
DeltaFile
+590-135src/middlewared/middlewared/pytest/unit/plugins/zfs/test_set_rules.py
+233-143src/middlewared/middlewared/plugins/zfs/set_rules.py
+296-41src/middlewared/middlewared/pytest/unit/plugins/zfs/test_resource_set.py
+173-14tests/api2/test_zfs_resource_set.py
+83-57src/middlewared/middlewared/plugins/zfs/resource_set.py
+4-0src/middlewared/middlewared/api/v27_0_0/zfs_resource_crud.py
+1,379-3906 files

FreeNAS/freenas babf41b — tests/api2 test_zfs_resource_promote.py test_zfs_resource_info.py

Fix integration test assertions for promote, destroy and blocksize errors

## Problem
Three groups of `zfs.resource` integration tests asserted the wrong exception shape: promote's empty-path test still expected the old non-empty-string message after `path` became a dataset name, the destroy failure tests caught `ClientException` although the integration client re-raises server `CallError`s as `CallError`, and the nonexistent-pool blocksize test expected `ValidationErrors` where the method raises a single `ValidationError`.

## Solution
Point each assertion at the exception class and message the server actually raises, keeping every attribute, errno and message expectation.
DeltaFile
+7-8tests/api2/test_zfs_resource_destroy.py
+5-4tests/api2/test_zfs_resource_info.py
+1-1tests/api2/test_zfs_resource_promote.py
+13-133 files

FreeNAS/freenas dcd14fa — src/middlewared/middlewared/plugins/iscsi_ global_linux.py extents.py, src/middlewared/middlewared/pytest/unit/plugins/iscsi __init__.py test_zfs_delegate.py

Register the iSCSI extent delegate and split iscsi.extent.update_internal

## Problem
LUN size and readonly resyncs after a zvol property change ran only from `pool.dataset.update`, so a `zfs.resource.set` on a zvol backing an extent left the target stale. On top of that, the readonly resync went through the public `iscsi.extent.update`, which writes `readonly` back to the zvol, so a readonly change on a shared zvol produced a second CHANGED event.

## Solution
Add an `iscsi.extent` delegate for volumes that rejects hiding snapshot devices an extent is using, resyncs the LUN size when `volsize` changes and resyncs the extent's `ro` flag whenever `readonly` is set or inherited. It is registered with `zfs.resource.set` from the iSCSI plugin setup.

The body of `iscsi.extent.update` moves to a private `update_internal` that only writes `readonly` to the zvol when asked to. The public update still does, while the ZFS-originated resync calls it without the write-back. As a side effect that resync no longer writes an "Update iSCSI extent" audit row, since it's an internal sync rather than a user action.
DeltaFile
+191-0src/middlewared/middlewared/pytest/unit/plugins/iscsi/test_zfs_delegate.py
+40-0src/middlewared/middlewared/plugins/iscsi_/zfs_delegate.py
+8-2src/middlewared/middlewared/plugins/iscsi_/extents.py
+1-3src/middlewared/middlewared/plugins/iscsi_/global_linux.py
+0-0src/middlewared/middlewared/pytest/unit/plugins/iscsi/__init__.py
+240-55 files

FreeNAS/freenas 386e81c — src/middlewared/middlewared/plugins/zfs resource_ops.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_rename_clone_guards.py

Guard rename, promote and snapshot rename against protected paths and mount clones

## Problem
`zfs.resource.rename` guarded neither name against protected paths and carried a ceremonial `force` flag, `promote` had no guard at all, and snapshot rename only guarded the source. A failed destroy surfaced as a validation error even though the input was fine, and a filesystem created by `zfs.resource.snapshot.clone` was never mounted.

## Solution
- **Protected paths**: rename rejects a protected source or destination, promote rejects a protected path and snapshot rename also checks the destination. Each model gets a `Private` `bypass` for middleware callers, and `force` is gone from the rename model.
- **Destroy failures**: an operational destroy failure is raised as a `CallError` carrying the errno, and the clones error is attributed to the method rather than `defer`. The snapshot destroy docstring now documents `EBUSY`, which is what is actually raised.
- **Clone mounts**: `clone_impl` reports whether it created a filesystem, and the public `clone` mounts only those unless the new `no_mount` option is set. A mount failure is logged as a warning and the clone is kept, matching zfs(8).
DeltaFile
+110-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_rename_clone_guards.py
+45-10tests/api2/test_zfs_resource_rename.py
+40-1tests/api2/test_zfs_resource_snapshot_clone.py
+18-0tests/api2/test_zfs_resource_promote.py
+9-8tests/api2/test_zfs_resource_destroy.py
+4-12src/middlewared/middlewared/plugins/zfs/resource_ops.py
+226-316 files not shown
+262-5312 files

FreeNAS/freenas 4706944 — src/middlewared/middlewared/plugins/pool_ dataset.py

Split pool dataset validation by mode

## Problem
`pool.dataset`'s `__common_validation` served both create and update through a `mode` argument plus a handful of branches that were mode-dependent by content rather than by an explicit gate, which made it hard to see which checks actually apply to an update and impossible to re-point the update path at `zfs.resource.set` without dragging create-only logic along.

## Solution
Split it into `__create_validation` and `__update_validation`. Every `mode` gate is inlined into the side it belongs to, the `create_ancestors` / missing-parent handling and the readonly-parent check stay create-only, the SMB acltype guard and the `user_properties_update` normalisation stay update-only, and the parent lookup, dRAID checks and field-shape rejections are kept on both sides. No behaviour change on either path.
DeltaFile
+198-80src/middlewared/middlewared/plugins/pool_/dataset.py
+198-801 files

FreeNAS/freenas 61ff377 — src/middlewared/middlewared/plugins/zfs resource.py snapshot.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_audit_extended.py

Audit zfs.resource mutating methods

## Problem
None of the `zfs.resource` or `zfs.resource.snapshot` mutating methods wrote an audit entry, so a destroy, rename, promote, property change or snapshot operation issued through the public API left no trace in the audit log.

## Solution
Add `audit=` and `audit_extended` to every mutating method, describing the target path and the flags that change the blast radius (recursive, defer, all_snapshots and the rollback options). The descriptions are built from the raw request dict with `.get` so a malformed request can never break the audit hook, and `zfs.resource.set` lists every property it changes, user property it sets and property it inherits.
DeltaFile
+71-0tests/api2/test_audit_zfs_resource.py
+61-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_audit_extended.py
+22-0src/middlewared/middlewared/plugins/zfs/snapshot.py
+20-1src/middlewared/middlewared/plugins/zfs/resource.py
+174-14 files

FreeNAS/freenas f2f8b57 — src/middlewared/middlewared/api/v27_0_0 zfs_resource_crud.py, src/middlewared/middlewared/plugins/zfs resource_set.py resource.py

Emit zfs.resource.list events

## Problem
`zfs.resource` mutations were invisible to subscribers: no ADDED/CHANGED event was sent from set, create, rename or promote, the kernel history hook fed only `pool.dataset.query` REMOVED, and no per-type event models existed to document the payload.

## Solution
Register `zfs.resource.list` with per-type event models and emit from the service `*_impl` methods once the write has returned: CHANGED from `set_impl` carrying only what was touched under `fields` (so tier, pool import and HA writes emit too, while a dry run emits nothing), ADDED from `create_impl`, REMOVED then ADDED from `rename_impl` and an `origin`-only CHANGED from `promote_impl`. Destroy is left to the kernel history hook, which now also sends `zfs.resource.list` REMOVED for destroyed datasets, skipping snapshots and hidden `%` clones such as the ones replication receives through. An import test catches event model naming mistakes in CI and unit tests pin every emission.

The set model's `user_properties` description also stops promising an 8192-byte value bound; the API caps strings at 1024 characters.
DeltaFile
+241-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_resource_events.py
+46-3src/middlewared/middlewared/plugins/zfs/resource.py
+43-1src/middlewared/middlewared/api/v27_0_0/zfs_resource_crud.py
+27-2src/middlewared/middlewared/plugins/zfs/resource_set.py
+5-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_service_imports.py
+2-0src/middlewared/middlewared/plugins/zfs_/zfs_events.py
+364-66 files

FreeNAS/freenas 0b502fa — src/middlewared/middlewared/plugins/pool_ snapshot_count.py dataset.py, src/middlewared/middlewared/pytest/unit/plugins/pool test_snapshot_create_shim.py

Point pool.snapshot and pool.dataset at public zfs.resource methods

## Problem
`pool.snapshot.rename` has been broken on master since the typesafe conversion of `zfs.resource.rename`: it called the dataset method, which rejects every `@` path with "Use `zfs.resource.snapshot.rename` to rename snapshots", so every call failed. `pool.snapshot.create`, `clone`, `hold` and `release` called the raw `*_impl`s, which translate nothing, so a nonexistent path or an existing destination surfaced as a raw traceback with EINVAL instead of a validation error, and the pool layer duplicated the translation it did get right (`rollback`).

## Solution
Call the public `zfs.resource.snapshot.*` and `zfs.resource.*` wrappers, which carry the ENOENT/EEXIST/not-a-snapshot translation and the `@` placement checks, and re-key their `ValidationError` attributes onto the `pool.snapshot.*` names so the pool error contract is preserved. `pool.dataset.rename`, `promote`, `delete` and `snapshot_count` go through the public methods too; `delete` keeps its own protected-path and children checks so a doomed delete fails before attachments are stopped.

`pool.snapshot.create` is the one seam whose callee returns a model to internal callers, so it dumps it before the dict-reading transform. A unit test drives the real method through the stub middleware so a dropped dump or a wrong re-key fails in CI rather than taking the VM suite down.
DeltaFile
+102-0src/middlewared/middlewared/pytest/unit/plugins/pool/test_snapshot_create_shim.py
+47-53src/middlewared/middlewared/plugins/pool_/snapshot.py
+23-7tests/api2/test_zfs_resource_snapshot_rename.py
+8-10src/middlewared/middlewared/plugins/pool_/dataset.py
+17-0tests/api2/test_snapshots.py
+2-2src/middlewared/middlewared/plugins/pool_/snapshot_count.py
+199-726 files

FreeNAS/freenas 537545c — src/middlewared/middlewared/api/v27_0_0 zfs_resource_crud.py, src/middlewared/middlewared/plugins/zfs create_impl.py resource.py

Return the written state from the same handle in zfs.resource.set_impl

## Problem
`set` re-read the dataset through a fresh `list` call after writing and indexed `[0]`, so what it returned was a second query rather than the state the write produced. libzfs failures from all three write phases were collapsed into one attribute with no hint of which phase failed or what had already been applied, `EZFS_BADVERSION` and `EZFS_NOTSUP` fell through to a generic error, and nothing pinned that `volsize` and `refreservation` travel in one nvlist, which is what keeps libzfs's volsize rollback alive.

## Solution
`set_impl` normalises its optional arguments once, writes, and returns the entry projected from the handle that did the write (touched natives only, `properties` null when none were touched). Each phase maps its own failure: invalid input becomes a `ValidationError` on the property, `user_properties` or `inherit.<name>` attribute, a vanished resource and operational failures become `CallError`s, and every message except the vanished case ends with the values now on disk, read from the same handle after refreshing it since libzfs only refreshes on success. `EZFS_BADVERSION`/`EZFS_NOTSUP` join the invalid-input table, the set model's `path` is typed as a dataset name, and the set model's `volsize`, `refreservation`, `user_properties` and `inherit` descriptions state the set-time contract. Unit tests pin the single nvlist, the same-handle projection and every row of the error mapping.
DeltaFile
+247-13src/middlewared/middlewared/pytest/unit/plugins/zfs/test_resource_set.py
+110-34src/middlewared/middlewared/plugins/zfs/resource_set.py
+24-7src/middlewared/middlewared/api/v27_0_0/zfs_resource_crud.py
+2-2src/middlewared/middlewared/plugins/zfs/resource.py
+2-0src/middlewared/middlewared/plugins/zfs/create_impl.py
+385-565 files

FreeNAS/freenas d00e3f7 — src/middlewared/middlewared/plugins/nvmet zfs_delegate.py, src/middlewared/middlewared/plugins/smb_ zfs_delegate.py

Register the share, namespace and VM device delegates

## Problem
The SMB acltype guard, the NVMe-oF namespace resync and the VM device snapshot-device guard still lived only in `pool.dataset.update`, so `zfs.resource.set` could change the ACL type under enabled SMB shares, leave a namespace at its old size after a volsize grow, or hide a zvol snapshot device a VM disk depends on.

## Solution
Register `smb.share`, `nvmet.namespace` and `vm.device` delegates with `zfs.resource.set` from each plugin's setup. The SMB delegate goes through `pool.dataset.attachments`, which resolves the mountpoint itself, and lists every share name joined with commas rather than printing the list repr. The namespace and VM legs of the snapdev guard decode their stored device paths before comparing them against the volume's snapshot devices.

A unit test runs `validate_delegate` over the four concrete delegates so a malformed one fails CI instead of boot, and new integration tests cover the delegates end to end and the `zfs.resource.list` event stream, including the kernel-sourced destroy events and the replication receive filter.
DeltaFile
+144-0tests/api2/test_zfs_resource_events.py
+139-0tests/api2/test_zfs_resource_delegates.py
+42-0src/middlewared/middlewared/plugins/nvmet/zfs_delegate.py
+30-0src/middlewared/middlewared/plugins/vm/attachments.py
+30-0src/middlewared/middlewared/plugins/smb_/zfs_delegate.py
+13-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_delegates.py
+398-02 files not shown
+402-08 files

FreeNAS/freenas 7abedd8 — src/middlewared/middlewared/plugins/zfs create_rules.py rules_common.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_set_rules.py

Skip the refreservation headroom leg when a refquota clamps available

## Problem
`zfs.resource.set`'s reservation headroom rule takes `available − usedbyrefreservation` as the space the kernel will check a refreservation against. That identity holds only when the dataset has no refquota of its own; a filesystem's `available` is clamped to `refquota − referenced`, so on a refquota'd filesystem the rule rejected any reservation above 80% of the refquota remainder, reported a second error next to the refquota check, and refused a refquota raise and refreservation grow sent in one request.

## Solution
Check the refreservation against the effective refquota (the kernel compares after the same-nvlist refquota is applied) and run the headroom leg only when the on-disk refquota is zero, which is exactly when the visible base equals the kernel's directory-level figure; the shared headroom helper loses its refquota leg. The dedup-inheritance integration test is restructured so its entitlement mocks are sequential rather than nested.
DeltaFile
+28-3src/middlewared/middlewared/pytest/unit/plugins/zfs/test_set_rules.py
+12-9tests/api2/test_zfs_resource_set.py
+12-3src/middlewared/middlewared/plugins/zfs/set_rules.py
+1-8src/middlewared/middlewared/plugins/zfs/rules_common.py
+0-1src/middlewared/middlewared/plugins/zfs/create_rules.py
+53-245 files

FreeNAS/freenas 271e0a1 — src/middlewared/middlewared/plugins/zfs set_rules.py resource_create.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_create_rules.py

Aggregate create-side validation and share the headroom rule

## Problem
`zfs.resource.create`'s rules raised on the first violation, so a caller had to fix a request one error at a time. The create-side headroom check measured a new volume's reservation against the ancestor's `available`, which counts the unused part of the ancestor's own refreservation that a new child can never use. And the post-write re-read indexed `[0]` on a list whose order nothing guaranteed.

## Solution
The shared `reject_*` helpers move into `rules_common.py`, where each one appends to a `ValidationErrors` under a caller-supplied attribute instead of raising. Every create rule now appends too, and `create_impl` checks the collection at two barriers: once after the name, entitlement and parent-type checks (the rules below read filesystem-only properties from the parent), and once right before the ioctl. `check_volume_capacity` goes through the new shared `reject_insufficient_headroom` rule with `available - usedbyrefreservation` of the nearest ancestor as its base and reports on `properties.refreservation`. User property names follow ZFS's own grammar and values are length-checked and single-line. The tier config is read only when a tier-managed property can be involved, and the read-back finds the new resource by name. The set rules call the shared helpers through a local collector and raise the first violation, so the set path's behaviour is unchanged.
DeltaFile
+287-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_create_rules.py
+69-182src/middlewared/middlewared/plugins/zfs/create_rules.py
+178-0src/middlewared/middlewared/plugins/zfs/rules_common.py
+48-38src/middlewared/middlewared/plugins/zfs/resource_create.py
+45-11tests/api2/test_zfs_resource_create.py
+26-8src/middlewared/middlewared/plugins/zfs/set_rules.py
+653-2396 files

FreeNAS/freenas b4f052a — src/middlewared/middlewared/plugins/zfs update_rules.py set_rules.py, src/middlewared/middlewared/pytest/unit/plugins/zfs test_update_rules.py test_set_rules.py

Rename zfs.resource.update to set

## Problem
The raw ZFS namespace models `zfs(8)`, whose property write verb is `set`, and the `update` name collides with the CRUD-style `pool.dataset.update` it is meant to replace. `zfs.resource.update` has never shipped on master, so there is nothing to alias.

## Solution
Rename the method, its impl, its API models, its module and rule module, and the tests to `set`, and regenerate the entitlement gate inventory. `.set` and `.destroy` are also added to the read-role resource blacklist so a read role can never be granted either write verb.
DeltaFile
+0-209src/middlewared/middlewared/plugins/zfs/update_rules.py
+209-0src/middlewared/middlewared/plugins/zfs/set_rules.py
+0-200tests/api2/test_zfs_resource_update.py
+200-0tests/api2/test_zfs_resource_set.py
+0-185src/middlewared/middlewared/pytest/unit/plugins/zfs/test_update_rules.py
+185-0src/middlewared/middlewared/pytest/unit/plugins/zfs/test_set_rules.py
+594-59410 files not shown
+766-76416 files

FreeNAS/freenas 3846a57 — src/middlewared/middlewared/api/v27_0_0 zfs_resource_crud.py, src/middlewared/middlewared/plugins/zfs update_rules.py resource_processes.py

Round out zfs.resource with list, update and the dataset parity methods

## Problem
`zfs.resource` is replacing `pool.dataset`, but it had no way to change a property, its listing method was called `query` while taking a single object rather than the `(filters, options)` that name implies everywhere else, and the choices methods, the zvol blocksize recommendation and the processes family still lived only under `pool.dataset`, so retiring that namespace would have taken those capabilities with it.

## Solution
**`query` becomes `list`.** The behaviour is unchanged - a single object describing what to walk, a flat result unless `nest_results` is set - but the name no longer promises a filterable query it never was. Its primitive is `list_impl`, so the private entry point reads as the method it serves. This is a hard rename with no compatibility shim, so 25.10.x and 26.0 clients lose `zfs.resource.query`; that needs a release note.

**`update` is new.** It takes `{path, properties, user_properties, inherit}` and returns the updated entry, rather than splitting into the `set` and `inherit` that `zfs(8)` uses. A dataset edit is one save, the underlying handle already performs the property set, the user-property set and the per-property inherit in a single pass, and splitting the API would only export sequencing and partial rollback to every caller. Its property vocabulary subclasses the create model so the public/private split is inherited rather than restated, minus what ZFS cannot change after creation. It is the one public method whose role the decorator does not force, so an integration test holds `ZFS_RESOURCE_WRITE` to granting it and `ZFS_RESOURCE_READ` to being refused.

**The write primitive lives on `zfs.resource`.** `update_impl` takes untyped keyword arguments, since internal callers legitimately write property names outside the public vocabulary, and like `create_impl` and `destroy_impl` it refuses snapshot paths and, unless the caller passes `bypass`, protected paths - a private method is still reachable over the wire, and every system dataset, apps and pool-import writer now funnels through this one call. `pool.dataset.update_impl` is a shim that unpacks its existing argument dict onto the primitive with `bypass` set, since those writers reach it that way; the dict stays intact as the HA wire format it is and its callers are untouched. `zfs.tier` calls the primitive directly through a typed call, also with `bypass`, because it is the only way to re-tier an internal dataset once tiering owns `special_small_blocks`, and moves onto the `ZFS_RESOURCE_*` roles that match its namespace - a custom privilege built on `DATASET_*` alone therefore loses `zfs.tier`, which also needs a release note. `pool.dataset.update` keeps its own policy layer and is not shimmed onto the new method; dedup licensing, the acltype-versus-SMB-share block and the LUN resync side effects belong above the raw ZFS layer, not on it.

**`rename` and `promote` become public**, typed and single-object, held by `ZFS_RESOURCE_WRITE`, with the private entry points renamed `rename_impl` and `promote_impl`. `rename` requires `force` as the same acknowledgement `pool.dataset.rename` requires and drops `recursive`, which a dataset rename can never be; the message for that moved to the `pool.dataset.rename` shim so the caller-visible error is unchanged. `pool.snapshot.rename` is re-pointed at the snapshot implementation, which is where snapshot renames actually live - it has been dead since the rename guard landed.

**The read-parity methods move** to `zfs.resource` behind one-line `pool.dataset` shims that keep their existing models and roles, with the pure parts split into modules that need no service or filesystem access.

**Fixes carried along.** Normalising sources no longer dereferences a null `properties`; the overlapping-path check now runs whenever the walk descends rather than only when `get_children` is set, and names the option that actually triggered it; `max_depth` is bounded below at zero; and nesting no longer raises when a parent's `children` is absent because the walk never descended into it.
DeltaFile
+331-92src/middlewared/middlewared/plugins/zfs/resource.py
+361-0tests/api2/test_zfs_resource_list.py
+0-353tests/api2/test_zfs_resource_query.py
+241-0src/middlewared/middlewared/plugins/zfs/resource_processes.py
+203-8src/middlewared/middlewared/api/v27_0_0/zfs_resource_crud.py
+209-0src/middlewared/middlewared/plugins/zfs/update_rules.py
+1,345-45398 files not shown
+2,844-1,261104 files