Skip to content

vdev_initialize: bound and snapshot chunk size - #19096

Open
matthiasgoergens wants to merge 1 commit into
openzfs:masterfrom
matthiasgoergens:fix/initialize-chunk-size-current
Open

matthiasgoergens wants to merge 1 commit into
openzfs:masterfrom
matthiasgoergens:fix/initialize-chunk-size-current

Conversation

@matthiasgoergens

@matthiasgoergens matthiasgoergens commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

zfs_initialize_chunk_size is read separately when allocating the initialisation buffer and when splitting writes. Changing it during initialisation can therefore make the write size inconsistent with the buffer. The value also needs to satisfy the maximum block-size limit and the target vdev's physical I/O alignment.

Sample and normalise the value once while allocating and filling the per-device ABD. Clamp it to the range from the configured vdev sector size (2^ashift bytes) to 16 MiB, then derive every write split from abd_get_size(data). This makes the allocated ABD the single source of truth even if the tunable changes while the thread is running.

Changes take effect when a device initialisation thread next starts, including after initialisation is resumed. The regression test covers lower and upper bounds, sector-unaligned values, active tunable changes, and suspend/resume; controlled I/O delays ensure that the active state is observed before suspension.

Copilot AI lite review requested due to automatic review settings September 10, 2026 16:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The remaining findings are minor documentation/spelling issues and do not affect the correctness of the chunk-size snapshotting and clamping behavior.

Pull request overview

This PR makes zfs_initialize_chunk_size consistent and safe to use during vdev initialization by sampling and normalizing it once per device initialization thread, preventing mismatches between the ABD allocation size and subsequent write sizes if the tunable changes mid-run.

Changes:

  • Snapshot zfs_initialize_chunk_size once per vdev_initialize_thread() and reuse it for both ABD allocation and write splitting.
  • Clamp the effective chunk size to SPA_MINBLOCKSIZE..SPA_MAXBLOCKSIZE and round it down to a 512-byte multiple.
  • Document the “sample-on-thread-start” behavior (including resume) in zfs(4).
File summaries
File Description
module/zfs/vdev_initialize.c Snapshots, clamps, and reuses a per-thread chunk size for buffer allocation and write sizing.
man/man4/zfs.4 Documents clamping/rounding and when tunable changes take effect.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread man/man4/zfs.4 Outdated
Comment thread module/zfs/vdev_initialize.c Outdated
@behlendorf behlendorf added the Status: Code Review Needed Ready for review and testing label Sep 10, 2026
Copilot AI review requested due to automatic review settings September 11, 2026 02:31
@matthiasgoergens
matthiasgoergens force-pushed the fix/initialize-chunk-size-current branch from 19c8a91 to 312589b Compare September 11, 2026 02:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Add regression coverage for bounds, rounding, and sampling across suspend/resume.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread module/zfs/vdev_initialize.c Outdated
Comment on lines +540 to +542
chunk_size = MIN(MAX(chunk_size, SPA_MINBLOCKSIZE),
SPA_MAXBLOCKSIZE);
chunk_size = P2ALIGN_TYPED(chunk_size, SPA_MINBLOCKSIZE, uint64_t);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added zpool_initialize_chunk_size.ksh. It exercises 0, 1, 513, and 16 MiB + 1, checks the reported initialisation state and error count, changes the tunable while initialisation is active and suspended, and completes the resumed run. The unpatched zero-sized case reproduces the allocator panic.

@matthiasgoergens
matthiasgoergens force-pushed the fix/initialize-chunk-size-current branch from 312589b to a25b811 Compare September 11, 2026 04:00
Copilot AI review requested due to automatic review settings September 11, 2026 04:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The functional test has a moderate polling issue that can falsely fail when initialization completes before progress is observed.

Review details

Suppressed comments (1)

tests/zfs-tests/tests/functional/cli_root/zpool_initialize/zpool_initialize_chunk_size.ksh:52

  • wait_for_initialize treats a percentage line as the only indication that initialization started. The test deliberately includes the 16 MiB case, which can finish the 1 GiB file before a poll observes it; a completed vdev no longer has an initialize_progress percentage, so this reports “Initializing did not start” for a successful run. Poll init_state and accept both ACTIVE and COMPLETE instead.
		[[ -n "$(initialize_progress $TESTPOOL $VDEV)" ]] && return
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@amotin amotin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General motivation is good. But I think instead of explicitly passing the chunk size we could just use the allocated and filled ABD size, so that there could never be a discrepancy between allocation and access. Also I have feeling that somewhere there should be the vdev's ashift as a limit, not SPA_MINBLOCKSIZE.

@matthiasgoergens
matthiasgoergens force-pushed the fix/initialize-chunk-size-current branch from a25b811 to 243d498 Compare September 14, 2026 09:16
@matthiasgoergens

Copy link
Copy Markdown
Contributor Author

Thanks. Updated along both lines: the allocation is clamped and rounded against 1ULL << vd->vdev_ashift, and vdev_initialize_ranges() derives the split size from abd_get_size(data) rather than receiving a separate size. The ABD is therefore the source of truth for every write. The regression test now creates an ashift-12 vdev and exercises bounds, sector-unaligned values, active tunable changes, and suspend/resume.

@matthiasgoergens
matthiasgoergens force-pushed the fix/initialize-chunk-size-current branch from 243d498 to 0fd6b95 Compare September 14, 2026 10:13
The initialisation buffer allocation and write loop read
zfs_initialize_chunk_size independently. A concurrent tunable change can
make the write size inconsistent with the allocated buffer.

Snapshot and normalise the value once per device initialisation thread.
Clamp it to the configured vdev sector size and maximum block size.
Derive every write split from the allocated ABD size. This makes the
allocation the single source of truth.

Document the effective bounds and when tunable changes take effect. Add
regression coverage for bounds, unaligned values, tunable changes, and
suspend/resume.

Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
Copilot AI review requested due to automatic review settings September 16, 2026 03:30
@matthiasgoergens
matthiasgoergens force-pushed the fix/initialize-chunk-size-current branch from 0fd6b95 to e769833 Compare September 16, 2026 03:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The regression tests need stronger coverage for round-down alignment and tunable snapshot timing.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

tests/zfs-tests/tests/functional/cli_root/zpool_initialize/zpool_initialize_chunk_size.ksh:75

  • This helper only observes the state flag, but vdev_initialize() sets that flag before creating the worker thread (module/zfs/vdev_initialize.c:663-665). Either caller can therefore change the tunable before the new thread allocates its ABD or issues a delayed write, allowing the snapshot behavior to go untested; wait for an initialization I/O to complete (for example, for the reported initialized-byte count to increase) before changing the tunable.
	while (( retries-- > 0 )); do
		state=$(initialize_stat init_state 2>/dev/null) || state=
		[[ "$state" == "ACTIVE" ]] && return
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite


log_must truncate -s $((MINVDEVSIZE * 4)) "$VDEV"

for chunk_size in 0 1 $((sector_sz - 1)) $((max_chunk_sz + 1)); do
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status: Code Review Needed Ready for review and testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants