Support page sizes larger than 4K#430
Open
dzianisbely wants to merge 2 commits into
Open
Conversation
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.
Summary
dattobd's COW manager operates in fixed 4096-byte blocks, but several spots in the snapshot path assumed
PAGE_SIZE == COW_BLOCK_SIZE. That assumption holds on 4K-page kernels but breaks onPAGE_SIZE > 4K, where a single page spans multiple COW blocks (16 on 64K), leading to silent snapshot data corruption. This change makes the COW path size-correct. It is architecture-independent: the logic keys only onPAGE_SIZE/SECTORS_PER_PAGE/COW_BLOCK_SIZE, with no arch#ifdefs, and is a no-op on 4K.What changed and why
< 1 pageand integer division yieldedpages == 0→ empty read clone → corrupt snapshot. Fixed by rounding the page count up and tracking atailso the read clone reads only real data. The refill loop now compares real data bytes (a page-count compare would loop forever given the short tail page).COW_SECTION_SIZE→PAGE_SIZE.COW_SECTION_SIZEis the number of index entries per COW section, and a section's mapping array is a page-granularity allocationget_order(sect_size * 8)incow_init(). It was hard-coded to 4096, which only lines up with a 4K page. The COW data block granularity is unaffected (COW_BLOCK_SIZE= 4096, separate).snap_handle_write_bio()looped over COW blocks within a bvec passing the same un-advanceddatapointer tocow_write_current(). On 64K a page holds 16 COW blocks, so all 16 got the page's first 4096 bytes → COW store garbage → snapshot reads garbage.Fix: advance
block_databyCOW_BLOCK_SIZEper iteration. On 4K the loop runs once, so the bug was invisible there.Evidence
Environments:
64K-page kernel (arm64, 6.8.0-124-generic-64k, PAGE_SIZE 65536): clean
build (0 warnings)
build-arm64-6-8-64k.txt.txt
Full
tests/suite: 24 OKfull-tests-arm64-6-8-64k.txt
ftrace hooks —
insmodsucceeds, thepath_mount/path_umounthooks register, and a real mount fireshandle_bdev_mount_event(the IPMODIFY redirect works on 64K).runtime-hooks-arm64-6-8-64k.txt
snapshot demo:
snapshot-demo-arm64-6-8-64k.txt
Direct test COW-store fix. 16 MB random pattern was written raw to the origin at offset 300 MB (outside the filesystem). Snapshot was taken that region was then overwritten data. This pushes full 16 MB of originals through
snap_handle_write_bio. The read-only snapshot still returns source data while the origin returns overwritten data (sha256 match). Verified both on the VM (seekable block devices) and after pulling both device images to a separate host and comparing. With the bug, the snapshot will return corrupted data.snap-cow-write-arm64-6-8-64k.txt
state-log-arm64-6-8-64k.txt
No regression on 4K (x86 7.0.0-22, real hardware). Same source builds clean and the full
tests/suite passes (24 OK) with snapshot and COW correct, confirming the change is a true no-op on 4K-page kernels. I took my changes from Add arm64(AArch64) support #429 to make test on Ubuntu 26.04build.txt
noregression-4k-x86-7.0.txt
snapshot-demo.txt
tests.txt