advanced26 min studyLesson 175 in Engineering

Copy-on-write roots and the storage that snapshots retain

Follow new data and tree paths to a committed root, then account for shared blocks, snapshot retention, and application consistency boundaries.

On this page

What you’ll understand

  • Explain why a new root must not reference unavailable child blocks.
  • Calculate retained storage when versions share unchanged extents.
  • Distinguish a filesystem snapshot from a separate backup or an application-coordinated checkpoint.

Copy-on-write changes how a filesystem publishes updates: write replacement blocks elsewhere, construct changed metadata paths, and make a new root reachable under a recovery protocol. Older roots can continue referencing older contents. This enables inexpensive initial snapshots, but cheap creation is not the same as free retention. To reason correctly, track unique blocks and references rather than multiplying the number of visible versions by their logical sizes.

Build the next reachable tree without destroying the old one

Picture a root that reaches metadata nodes and data extents. Changing one leaf can require a new leaf and copies of ancestors along its path; unchanged branches can remain shared. Before publishing the replacement root, the required new children must be safely available under the filesystem's commit protocol. Otherwise a durable root could point to missing updates. Recovery must identify a valid committed view, not merely follow whichever root write happened to begin last. Real implementations include transaction machinery and recovery details beyond this small tree model.

Copy-on-write is a family of techniques rather than a universal guarantee about every byte. Filesystem features, per-file flags, direct I/O behavior, compression, and implementation choices affect actual paths. Btrfs normally uses copy-on-write and supports snapshots and reflinks, but users should consult the specific feature contracts rather than infer that all operations create an independent full copy. A reflinked file can share data extents while having a distinct file identity. That is different from a hard link, which provides another name for the same inode.

Sunique=∑b∈⋃v∈VBvsize⁡(b)S_{\rm unique}=\sum_{b\in\bigcup_{v\in V}B_v}\operatorname{size}(b)
For retained versions V with referenced block sets B_v, unique retained storage counts each block in the union once. The byte total excludes additional metadata and replication unless those blocks are explicitly included; adding logical version sizes double-counts sharing.↔ Scroll wide equations horizontally.

Cheap snapshots can make later deletions surprising

A snapshot can initially preserve a view by retaining references instead of copying every payload block. As the active version changes, older extents remain allocated while any retained snapshot still references them. Deleting a large file from the active namespace may therefore release little unique storage. Likewise, deleting one snapshot releases only blocks no remaining reference requires. Build a retention estimate from changed, uniquely retained data and metadata, then check filesystem-specific accounting instead of assuming a directory listing tells you which bytes can actually be reclaimed.

Shared extents also create shared fate. Two snapshots on one device are not two independent backups: a lost device can remove both, and damage to a shared block can affect several versions. A snapshot taken while an application is updating several objects may capture an application-inconsistent moment even if the filesystem snapshot itself is structurally coherent. Coordinate the application or use a recovery-capable format when needed. Keep an independent backup strategy and test restoration; the ability to browse yesterday's snapshot proves much less than surviving loss of the storage that holds every snapshot.

ΔS≈R+M,Sretained≈S0+∑i=1kRi+∑i=1kMi\Delta S\approx R+M,\qquad S_{\rm retained}\approx S_0+\sum_{i=1}^{k}R_i+\sum_{i=1}^{k}M_i
In a simplified uncompressed, unreplicated model, R_i bytes are newly written blocks retained for generation i and M_i bytes are added metadata. No old retained blocks are freed and rewrites use fresh blocks; sharing, compression, deduplication, and deletion can change real accounting.↔ Scroll wide equations horizontally.

Retention policy is part of write performance

Rewriting a small range can create metadata and allocation work, and retained snapshots can reduce space available for future placement. Evaluate the workload's overwrite size, snapshot frequency, retention duration, and free-space behavior together. A benchmark that creates one empty snapshot and never mutates data misses the accumulating cost. Conversely, claiming that copy-on-write always makes large-file operations slow ignores sharing, caching, request aggregation, and workload dependence. Measure the actual application operation and synchronization boundary before choosing flags that trade away checksumming or copy-on-write behavior.

The probability lab deliberately exposes an independence assumption relevant to retained copies. Set a small success probability p to mean failure of one independently stored block, and use n trials to model n distinct blocks. Increasing n raises the expected affected-block count np. It does not mean n snapshots are independent replicas: shared extents violate that interpretation. Predict how changing n alters the distribution, then explain why counting snapshot names as trials is wrong. The model illustrates independent events only; it cannot create snapshots, follow references, or evaluate a filesystem's recovery protocol.

Count unique data across retained generations

A 100 GiB dataset has a snapshot. The active dataset then replaces 8 GiB of extents with fresh, equal-sized extents, takes another snapshot, and replaces 5 GiB more. Assume no compression, replication, metadata cost, or block reuse and retain all versions.

  1. Initially the active view and first snapshot share the same 100 GiB of data, so unique payload remains 100 GiB rather than 200 GiB.

  2. The first rewrite retains the original 8 GiB through the older snapshot and adds 8 GiB of new blocks, producing 108 GiB of unique payload.

  3. The later rewrite adds another 5 GiB while the previous versions retain the replaced blocks, producing 113 GiB. The active logical dataset can still be 100 GiB throughout.

The result

Three visible generations need 113 GiB of unique payload under these assumptions. Which blocks a snapshot deletion frees depends on the remaining reference graph, not just that snapshot's logical size.

Explore the model

Interactive lab

Interactive lab · probability

Shared versions are not independent copies

Explore an exact binomial model by changing failure probability p and number n of independent block trials. Predict that the mean affected-block count is np. Snapshots sharing extents are not independent trials; this model highlights that limitation and does not simulate copy-on-write allocation or recovery.

Shared versions are not independent copiesThese are exact binomial probabilities for independent trials with one fixed success probability. Playback tours the distribution; it does not resample outcomes. Current readings: Mean · np: 5; Variance · np(1−p): 2.5; Total probability: 1. All parameters are adjustable with the labeled controls below.03581000.070.150.220.3Successes kP(X = k)k = 0 · P = 9.77e-4
Exact probabilityHighlighted outcomeMean np
Mean · np
5
Variance · np(1−p)
2.5
Total probability
1
t = 0 s

These are exact binomial probabilities for independent trials with one fixed success probability. Playback tours the distribution; it does not resample outcomes. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forCount distinct blocks and failure domains before interpreting visible versions as storage cost or protection.

Check your understanding

A file is deleted from the active Btrfs subvolume, but an older snapshot still references all of its extents. What should you expect before considering metadata details?

Try it yourself

A 40 GiB initial view is retained. Three later retained generations each add 2 GiB of fresh replacement blocks with no reclamation. Estimate unique payload and explain why four times 40 GiB is misleading.

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Start with shared initial payload, then add only newly retained blocks.

Compare with the solution

Unique payload is 40 + 3 × 2 = 46 GiB under the simplified assumptions. Multiplying four logical 40 GiB views gives 160 GiB and double-counts unchanged shared blocks. Metadata, compression, replication, and the actual overlap of retained extents require separate accounting; none of these views alone protects against losing the device that stores them.

Take it with you

  • Copy-on-write publication relies on correct child-before-root persistence dependencies.
  • Snapshots retain references, so unique storage follows shared-block reachability.
  • A structurally coherent snapshot is neither an independent backup nor automatic application consistency.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.