bees: make the per-extent reference ceiling configurable
BEES_MAX_EXTENT_REF_COUNT was a compile-time constant (9999) enforced at
several scattered gates. Make the operating limit a configured value,
rewrite.refs-max, so it can be tuned per filesystem, and route every runtime
user through the configuration.
The compiled constant is repurposed to the true hardware ceiling: the
LOGICAL_INO ioctl returns references into a 16 MiB kernel buffer, which at 24
bytes per (root, ino, offset) tuple holds ~699050 references. It is now
computed from that geometry and used only to size the ioctl buffer and to
clamp the configured value. The practical default (9999) lives in the config
(rewrite.refs-max), per the defaults-in-config rule.
The value lands in BeesRewritePolicy::m_refs_max (sentinel 0 = not loaded,
clamped to the ceiling at load) and is reachable as BeesContext::refs_max().
"unlimited" for rewrite.refs-max resolves to the kernel ceiling.
${REFS_MAX} mirrors the effective rewrite.refs-max. Like THREAD_FACTOR it is
derived from merged config (in set_argv, after the policy loads), not a system
fact, so it is not seeded in the constructor. Filters use it: filter
ref-count-max defaults to ${REFS_MAX}, and "unlimited" in a filter means that
configured value, not the kernel ceiling.
Call-site conversion:
- policy gates (resolve overflow, roots overflow, scan_next src/dst ref
limits) use the configured value (m_policy / m_rewrite_policy for the
plans, refs_max() for context and roots);
- the two LOGICAL_INO result-buffer generators capture this and size to
min(refs_max(), BEES_MAX_EXTENT_REF_COUNT), so the buffer scales with the
configured value up to the hardware ceiling and "unlimited" cannot
overflow the allocation;
- the legacy scan_one_extent seen-set cap uses refs_max().
Substitution plumbing: the typed BeesConfig::get() reads raw Innie values, so
the rewrite loader applies subst() before parsing, and a substitutor is
threaded into the filter parser. It is applied only to the numeric ref-count
fields, never to free-text values such as name-pattern regexes, which may
legally contain a lone '$' that subst() rejects.
No behavior change at the defaults: refs-max resolves to 9999, and the buffer
is sized exactly as before.