Retry an ENOSPC ntfsresize dry run at a larger size instead of failing the capture - #172
Merged
Merged
Conversation
…g the capture ntfsresize relocates every cluster past the new end into the space before it. On a Windows 11 volume the file holding those relocations can run out of runlist room before the data runs out of clusters, and ntfsresize reports that as "No space left on device" even though the target has hundreds of MB free (ntfs-3g issue #142). The 500 MB floor from 916cd69 was meant to cover it and does not: the fogproject #789 reporter's volume has 10832 MB in use, needs 5323 MB of relocations, and the dry run still fails at 11318 MB on every kernel including the one carrying that floor. More room means fewer relocations, so on an ENOSPC dry run shrinkPartition now doubles the slack and tries again, stopping at the first size that passes. The real resize and the partition resize use that size. The retry is capped at the volume's present size: if nothing below it fits, the partition is recorded as fixed size and left alone, the same outcome as ntfsresize's own "bigger than the device size". Any other dry-run failure still aborts on the first try, so a genuine error is not hidden behind a run of consistency checks. tests/checks/ntfs-shrink-retry.sh pins all four behaviors against a stub ntfsresize that answers with the reporter's exact ENOSPC lines below a chosen size. Two of its cases fail on the pre-fix code. Fixes FOGProject/fogproject#789 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0131h4axUaE3VJZphvKRdDby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
fogproject #789: capturing a Windows 11 volume fails in
shrinkPartition()withThe reporter tested the 2026-03-06 and 2026-03-23 kernels, which carry the 500 MB minimum slack from 916cd69, and still hit it. Their screenshot shows why: 10832 MB in use, target 11318 MB, and ntfsresize needs 5323 MB of relocations. The file recording those relocations runs out of runlist room (ntfs-3g issue #142); a fixed floor can't cover that.
Fix
On an ENOSPC dry run, double the slack and retry, stopping at the first size that passes. The real resize and partition resize use that size. Capped at the volume's present size: if nothing below it fits, the partition goes to
d1.fixed_size_partitionsand is left alone, the same path as ntfsresize's "bigger than the device size". Any other dry-run failure still aborts on the first try.Each retry costs one more read-only consistency pass. Doubling from ~500 MB reaches any volume size in a handful of steps, which is the tradeoff over stepping linearly.
Verification
tests/checks/ntfs-shrink-retry.sh(new) stubsntfsresizewith the reporter's exact ENOSPC lines below a chosen size and asserts: retries grow and stop at the first passing size, the resize uses it; a non-ENOSPC failure aborts after one try; a never-fits volume is recorded fixed size with no ask at or past the volume size; a first-time pass is unchanged.funcs.shin place, the retry and never-fits cases fail. Restored, all four pass.sh tests/run-all.sh: 19 passed, 0 failed.Not verified on hardware. The reporter's volume is the only known reproducer, so I'd like them to test the experimental build.
🤖 Generated with Claude Code
https://claude.ai/code/session_0131h4axUaE3VJZphvKRdDby