Skip to content

Clone zeros in pieces as large as the largest chunk - #440

Merged
folbricht merged 1 commit into
masterfrom
null-seed-clone-size
Sep 26, 2026
Merged

folbricht merged 1 commit into
masterfrom
null-seed-clone-size

Conversation

@folbricht

Copy link
Copy Markdown
Owner

When zeros are written over existing data on a filesystem that supports reflinks, the null seed clones them from a temporary file of zeros. That file was one block long, so each 4 KiB block of zeros was a separate FICLONERANGE call and ended up as a separate extent. Blank targets aren't affected since #439, which leaves zeros out of them, but updates over existing data are.

The file of zeros is now as large as the largest chunk, rounded up to full blocks: 256 KiB with the default chunk sizes. Runs of zeros are cloned in pieces of that size, and only the last piece is shorter. The unaligned head and tail are still written as zeros, and a failed clone still falls back to writing zeros.

Measurement

These are Debian 13 cloud images (3 GiB raw, about 2 GiB of it zero chunks) on btrfs, each updated in place to 20260909 with #323 applied (extract -k --seed old.caibx:target). There were two runs per case. Every result matched the image's md5.

Update from Extents Wall time
20260907 (2 days) before 43k – 56k 24.8 – 32.3 s
after 7.8k – 7.9k 11.2 – 16.5 s
20250909 (1 year) before 32k – 40k 29.5 – 39.9 s
after 8.2k 11.5 – 19.8 s

A plain extract over an existing image on master writes only about 65 MiB of zeros, because the rest is already in place. There, the extent count varies between 3k and 10k from run to run with either binary, so that case shows no measurable difference.

The temporary file now takes up ChunkSizeMax bytes instead of one block while an extract runs.

The null seed cloned runs of zeros from a file one block long, so every
block of zeros written over existing data was its own clone and its own
extent. Size the file of zeros to the largest chunk instead, rounded up to
full blocks, and clone each run in pieces of that size.
@folbricht
folbricht merged commit 5b74881 into master Sep 26, 2026
9 checks passed
@folbricht
folbricht deleted the null-seed-clone-size branch September 26, 2026 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant