]> git.hungrycats.org Git - bees/commitdiff
docs: document the extent-scan dedup/plan log lines
authorZygo Blaxell <bees@furryterror.org>
Thu, 9 Jul 2026 14:38:17 +0000 (10:38 -0400)
committerZygo Blaxell <bees@furryterror.org>
Sat, 5 Sep 2026 04:04:13 +0000 (00:04 -0400)
Describe the dedup: source/destination lines, the {bytenr+offset[:compression]
[/generation]} physical-extent token (including why the allocation generation is
logged and not file_extent_generation), and the plan: line fields, notably the
refs / rc / debt diagnostics that expose which references a plan rewrites and the
signed space-debt that admitted it.

Assisted-by: Claude-Code:claude-opus-4-8
docs/running.md

index d4bb6ded4e9c77523e24b9193d0e92a664707ccc..3541cc5924fbe7781cffc9220a3122dace1a8e5a 100644 (file)
@@ -100,3 +100,57 @@ periodically.  You may also want to set umask to 077 to prevent disclosure
 of information about the contents of the filesystem through the log file.
 
 There are also some shell wrappers in the `scripts/` directory.
+
+Reading the extent-scan log
+---------------------------
+
+At higher log levels the extent scanner prints one group of lines per
+deduplication.  A `dedup:` group names the surviving source extent and each
+destination whose references are redirected onto it:
+
+        dedup: src 128K [0x8613000..0x8633000] {0x2d3f88000+0x1000:zstd/1184} /path/to/src
+               dst 128K [0x0..0x20000]         {0x2fce257000+0x0:zstd/1207}   /path/to/dst
+
+The `{...}` token identifies a physical extent:
+
+        {<bytenr>+<offset>[:<compression>][/<generation>]}
+
+  * `<bytenr>+<offset>` — the extent's physical address and the offset into it.
+  * `:<compression>` — `zlib`, `lzo`, or `zstd` for a compressed extent, or
+    `:prealloc` for a preallocated (unwritten) extent; absent when the extent is
+    uncompressed.
+  * `/<generation>` — the extent's *allocation* generation, from the extent
+    tree.  It is fixed for one extent's lifetime and changes when a bytenr is
+    freed and reused, so it distinguishes a long-lived extent from a later one
+    that recycled its address — useful when correlating an address across log
+    lines.  (`file_extent_generation` is *not* used here: it is per-reference
+    and differs between reflinks of the same physical extent.)
+
+Special forms `{HOLE}`, `{INLINE}`, and `{}` mark a hole, an inline extent, and
+an extent that could not be read (freed or all references stale).
+
+Each destination that is rewritten also prints a `plan:` line describing the
+chosen plan and why it was chosen:
+
+        plan: 128K 1d0c0p0u 7.787s/8.600s {0x2fce257000} [Dddddd] refs 9912 rc 10041 debt -7197.0
+
+  * `128K` — the destination's logical size.
+  * `1d0c0p0u` — operation counts for this destination: `d` dedupe, `c` copy
+    (data relocated through a temporary file), `p` hole-punch (zero or
+    preallocated regions), `u` unreachable blocks freed with no operation.
+  * `7.787s/8.600s` — wall time to execute this destination / total time of the
+    planner pass so far (the second spots plans that are slow to *compute*).
+  * `{0x2fce257000}` — the destination extent's bytenr.
+  * `[Dddddd]` — a one-character-per-block disposition diagram: `D`/`d` deduped,
+    `C`/`c` copied, `0` hole, `U`/`u` unreachable (uppercase marks the first
+    block of each run).
+  * `refs <N>` — the destination's reference count as the planner saw it, read
+    before execution moves any references.
+  * `rc <N>` — references the winning plan is charged with rewriting
+    (`dst_ref_count` times the fragment count, summed over the plan's
+    destinations); this is what `rewrite.ref-op-cost` prices.
+  * `debt <D>` — the winning plan's signed space-debt: the modelled bytes it
+    adds to the filesystem, lower is better, negative is a net win, and
+    do-nothing is exactly `0`.  A destination with a large `refs` and a negative
+    `debt` was worth rewriting because the space it frees outweighs the cost of
+    moving its references.