Skip to content

flake.lock: Update - #3

Open
github-actions[bot] wants to merge 170 commits into
masterfrom
update_flake_lock_action
Open

flake.lock: Update#3
github-actions[bot] wants to merge 170 commits into
masterfrom
update_flake_lock_action

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Automated changes by the update-flake-lock GitHub Action.

Flake lock file updates:

• Updated input 'crane':
    'github:ipetkov/crane/0532eb17955225173906d671fb36306bdeb1e2dc?narHash=sha256-EVZd2RsbpreRUDSi9rBwPY%2BZxoyMaiEBbZxxhljbaS4%3D' (2026-05-30)
  → 'github:ipetkov/crane/2c71e194474d13de031d729b729c968ddbe3507f?narHash=sha256-MPaRdVkf6zZP5fCPxYCi8Dr4pZzgmXzg8T9nVEbp3Mw%3D' (2026-08-03)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb?narHash=sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4%3D' (2026-05-13)
  → 'github:hercules-ci/flake-parts/427bf4bd9435fdf21321c8cc628c24efc14c0f7a?narHash=sha256-4dtXQk/NMePegK/nWp5NSeuZKLATItOq61lpEvmXqGw%3D' (2026-08-01)
• Updated input 'flake-parts/nixpkgs-lib':
    'github:nix-community/nixpkgs.lib/f5901329dade4a6ea039af1433fb087bd9c1fe14?narHash=sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ%3D' (2026-04-26)
  → 'github:nix-community/nixpkgs.lib/0e79af5e3d4dcfcd676ab5ba3f95d2e3352e078c?narHash=sha256-OmshNvn2vupOFpYinLUu%2B1Dnpu4n7Q5N3ggGVNHpkUI%3D' (2026-07-26)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/e73de5be04e0eff4190a1432b946d469c794e7b4?narHash=sha256-pGvFkM8N0xEkIIXDe5YYfbEAvHrk4IxBrjB/x8OomhE%3D' (2026-06-26)
  → 'github:nixos/nixpkgs/b7c2ada94fe99c15b0dbcf4d11fd7850b957a436?narHash=sha256-IItrdb7Puk05RqOBWZYFC5X6Wl1sJmCfh5MWVHw5iMM%3D' (2026-08-05)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/85570ef134d92a8702de6afd1f6f0209c863fa91?narHash=sha256-6QBThUi7SuK%2BdgA%2BDCaEkQGZN4kYx6DpXmK45%2BMG9zI%3D' (2026-05-30)
  → 'github:oxalica/rust-overlay/57a23bfaf4f7017267294b161175db1e32eb1c85?narHash=sha256-jfR6OhwurCKn1tREyfOcK/Omxf1Q/DzDDFbnEr1mBLs%3D' (2026-08-07)
• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/790751ff7fd3801feeaf96d7dc416a8d581265ba?narHash=sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0%3D' (2026-04-08)
  → 'github:numtide/treefmt-nix/ae7910970dddc408fe6ab1c8e4b277bb21d72dc0?narHash=sha256-NLSyTCW4K4ofhNBllt3omPasm6QpralXH1DBZOc91Dw%3D' (2026-08-05)

Running GitHub Actions on this PR

GitHub Actions will not run workflows on pull requests which are opened by a GitHub Action.

To run GitHub Actions workflows on this PR, run:

git branch -D update_flake_lock_action
git fetch origin
git checkout update_flake_lock_action
git commit --amend --no-edit
git push origin update_flake_lock_action --force

Komzpa and others added 30 commits July 13, 2026 20:50
Allocator waiters filter fs-wide wakeups through the per-device
alloc_wake_counters recorded in their failed-allocation trace (see
alloc_wait_advanced()). If a device becomes newly eligible after that
trace was built — e.g. an empty member is added and relabelled — it is
absent from the trace, so the waiter sees none of its traced devices
advance and re-parks without rebuilding its eligible device set. It can
stay blocked indefinitely even after an explicit bch2_alloc_wake_all().

Add an fs-wide wake_all_counter. bch2_alloc_wake_all() now advances it
(instead of bumping every device's counter), requests snapshot it before
device selection, and alloc_wait_advanced() forces a full retry when it
changes. Per-device wakes keep their existing selective filtering.

Also check allocator progress before the first closure_sync in
__bch2_wait_on_allocator(): a wake can race closure_wait() before our
closure is on the waitlist, and unpark is then required to drop it off
the llist.

Update the wake-counter documentation (bcachefs.h, alloc/types.h,
alloc/foreground.{c,h}) to describe the two counters.

Reported in: koverstreet#628

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
…t extents

bch2_inode_delete_keys() committed with a NULL disk reservation. Deleting a
compressed extent that straddles a snapshot boundary splits it (middle_split,
old.k->p.snapshot != new.k->p.snapshot), and __bch2_trans_commit() charges the
split's extra_disk_res to trans->disk_res via bch2_disk_reservation_add() —
whose fast path does `res->sectors += sectors` with no NULL check. So rm of a
compressed file in a snapshotted subvolume NULL-derefs in
bch2_trans_commit_extra_disk_res(), crashing on unlink:

  bch2_trans_commit_extra_disk_res
  __bch2_trans_commit.cold
  bch2_inode_delete_keys
  bch2_inode_rm
  bch2_evict_inode

Give bch2_inode_delete_keys() a real (NOFAIL) disk reservation.

Reported-by: pio2398 <koverstreet/bcachefs#1185>
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
__wp_update_state() read current->se.{sum_exec_runtime,exec_start} for
write-point runtime accounting, but BMQ/PDS (CONFIG_SCHED_ALT) replace CFS
and drop task_struct.se, so the OOT module failed to build on CachyOS's
bmq kernel (data/write.c: 'struct task_struct' has no member named 'se').

It's only debug/perf timing, so guard it like the wake_cpu hint in
btree/locking.c: use the runtime under !CONFIG_SCHED_ALT, 0 otherwise.
Proxmox's kernel ships CONFIG_FRAME_WARN=1024 (stricter than the usual 2048)
with CONFIG_WERROR, so the OOT module failed to build there — three bcachefs
functions have >1KB frames (util.c, fs/check.c, data/update.c). Chasing frame
sizes here is whack-a-mole for no safety benefit: the functions that trip it,
mainly the data-update path, run from kthread/workqueue context with a full
stack, and we're careful not to blow it. Keep -Wframe-larger-than as a warning
but not an error, for the module build (and user DKMS builds on Proxmox).
…d before

A recovery pass that fails gets its bit set in passes_failing and is
masked out of subsequent runs until another pass succeeds, so automatic
recovery doesn't loop on a pass whose dependency repair hasn't happened
yet.

That mask also swallowed passes the user explicitly asked for: running

    bcachefs fsck -o recovery_passes=check_reconcile_work

after that pass had failed once returned success having done nothing,
with no indication why (only the sysfs recovery_status "Failing:" line).
Silent success from an explicit request is baffling in the field.

Gate the mask on !BCH_FS_in_fsck: an explicit fsck - online, or mount -o
fsck - runs the requested passes regardless and lets any failure surface,
while automatic required-passes recovery and the async retry loop keep the
loop-avoidance behavior.

Noted while debugging github #1186.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
bcachefs checks and repairs at mount time, so the boot-time preen
invocation (fsck.bcachefs -p, run by systemd/mount before mounting) has
nothing to do and returns success immediately.

But exiting 0 in silence reads as "fsck ran and the filesystem is clean"
when in fact no checking happened - especially confusing when a user runs
it by hand expecting a check. Print a line saying what's going on.

Noted while debugging github #1186.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
The previous commit stopped an explicit fsck from skipping passes that
failed on an earlier run. For automatic recovery, a failing pass was
still masked out entirely until some other pass succeeded (which clears
passes_failing wholesale) - so if nothing else made progress, a failing
pass was effectively stuck for the session.

Ratelimit retries instead, reusing the cost model the superblock already
uses for expensive passes (last_runtime * fraction > now - last_run), but
keyed on an in-memory recovery_pass_entry per pass, since a failing pass
must not write the superblock. Retry cadence scales with how long the
pass ran, so we don't hammer a pass that keeps failing, but recovery
isn't wedged waiting on an unrelated success either.

RECOVERY_PASS_FAILING_RATELIMIT is the tuning knob if a class of failing
passes retries too aggressively.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Add a per-btree "clean" bitmask to bch_sb_field_ext, sibling to
btrees_lost_data. A set bit means: that btree was validated consistent
by its check pass, and nothing has mutated it since. This is the
mechanism only - nothing sets, clears or reads the bits yet.

Modeled on the recovery-passes superblock tracking: the value is cached
in c->sb (loaded in bch2_sb_to_cpu, size-guarded like
btrees_lost_data_ever) and mutated straight through to the superblock
with a synchronous write - bch2_set_btree_clean() / bch2_clear_btree_clean()
take sb_lock and bch2_write_super(), with a double-checked lock so the
common case (bit already in the wanted state) stays off sb_lock. Because
every change is persisted immediately, the on-disk value is always
current and doesn't depend on a clean shutdown.

This will let consistency checks that would otherwise destroy data based
on an in-memory table they can't fully trust - check_key_has_snapshot -
instead reschedule the check pass and defer.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Clear a btree's btrees_clean bit from its transactional trigger whenever
it's mutated. subvolumes already runs a transactional trigger; give
snapshots one too (BTREE_NODE_TYPE_HAS_TRANS_TRIGGERS) - it can't clear
from its atomic trigger, which runs in the commit's post-journal-reservation
section where the synchronous superblock write isn't allowed.

bch2_clear_btree_clean()'s double-checked lock means a mutation to a
btree that's already not-clean is a cheap read with no lock or sb write;
only the first mutation after a clean mark pays for the superblock write.

Nothing sets the bits yet, so this is inert - it becomes live in the
next patch.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Set the btrees_clean bit for a btree at the tail of its check pass:
snapshots in bch2_check_snapshots, subvolumes in bch2_check_subvols.

The gate - !ret && !BCH_FS_error - is the same one the pass runner uses
to mark a pass complete (bch2_run_recovery_pass()): the pass ran to
completion and left no unfixed error or inconsistency. It's cumulative
across passes, so an earlier pass's unfixed error suppresses this bit
too - consistent with passes_complete, and it fails toward "reschedule
the check pass," never toward "wrongly destroy."

With the clear from the previous patch, the bitmask is now live: set
when a check pass validates its btree, cleared when the btree is mutated.
Still no consumer - that's the next patch.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
For a key in a missing snapshot (SNAPSHOT_ID_empty), don't delete it
unless the snapshots and subvolumes btrees have both been validated
consistent and not mutated since - the btrees_clean bits. Otherwise the
in-memory snapshot table may just be stale, and deleting the key would
destroy live data; schedule check_snapshots / check_subvols and defer.

This replaces the old gate, which trusted require_recovery_pass() on its
own: that's satisfied as soon as the pass has run this mount, or even
when it's merely been ratelimited - it says nothing about whether the
btrees have been mutated since. btrees_clean is the "run since the last
mutation" signal we actually want. The require_recovery_pass() calls
stay, but only as the scheduling mechanism when we're not already clean.

The FIX gate stays "snapshots_clean && !ret" so a scheduled
reconstruct_snapshots (via btrees_lost_data) still blocks the delete.
Gating btrees are snapshots + subvolumes, matching the two passes the
code already requires.

The SNAPSHOT_ID_deleted branch is left alone for now - gating it on
btrees_clean and fixing bch2_snapshot_live_descendent()'s ambiguity are
separate follow-ups.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
… no-descendant

bch2_snapshot_live_descendent() walked the single-child chain from a
deleted snapshot node returning the live descendant, or 0. But it
returned 0 in two very different cases: a genuine dead leaf (subtree
fully deleted - the key is orphaned and should be dropped), and a
missing node mid-walk (a deleted interior node's child pointer is
dangling - the tree is damaged, and we simply couldn't determine whether
a live descendant exists).

check_key_has_snapshot() treats 0 as "no live descendant, delete the
key" - so the second case silently destroyed a key that a live
descendant should still have seen. Return the two outcomes distinctly:
0 with *live set (found, or *live == 0 for a genuine dead leaf) vs an
error (invalid_snapshot_node) for the dangling pointer.

check_key_has_snapshot() now, on that error, doesn't destroy the key: on
a validated-clean table it's an inconsistency check_snapshots missed
(surface it); otherwise we're already deferring via the scheduled passes.
create_lostfound() already folded both zero cases into an error return,
so it just gains the damage case there too.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
check_key_has_snapshot() and fsck are responsible for detecting and
repairing keys that reference a snapshot the in-memory table calls
missing or deleted. A runtime data-move that touches such a key
(reconcile, copygc, ...) has to be able to reach them, back off and
reschedule the check passes - but several debug asserts BUG on exactly
those states instead, crashing a debug build (or fsck) on damage that's
meant to be repaired:

 - btree_trans_update_by_path() / btree_insert_entry_checks():
   EBUG_ON(!bch2_snapshot_exists()) on a live update to a snapshot btree
 - bch2_snapshot_live_descendent(): EBUG_ON(children[1]) when a node the
   table calls deleted still has two children

Drop the two snapshot_exists asserts. Return the two-children case as a
new snapshot_multiple_descendents error so the caller backs off cleanly,
and give it (and invalid_snapshot_node) a BCH_ERR_snapshot parent class.
reconcile's move_extent error handling expects BCH_ERR_snapshot now
rather than warning about an unhandled error.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
A snapshot node in a deletion state (deleted / will_delete / no_keys)
that still has a live child is inconsistent: the child needs it as an
ancestor, so it can't actually be gone - the state is a corrupt or
interrupted transition. Revive it (state -> live), which is the simplest
repair back to a consistent tree; a tombstone child is left to be
deleted on its own.

Done in check_snapshot() before the deleted early-out, so a revived node
falls through into the normal edge/depth/tree checks and gets fully
re-validated rather than just un-deleted.

Previously the runtime paths BUG'd (bch2_snapshot_live_descendent) or
check_key_has_snapshot deferred forever on this shape because the repair
didn't exist; it's the DELETED variant of the coherence check
test_no_keys_two_children has been driving.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
DKMS passes the package version as $ref (1.38.8, no leading v), so
fetch-module.sh looked for bcachefs-$ref.ko - but the farm publishes
modules named after the git tag, bcachefs-v1.38.8.ko. The extra v meant
the prebuilt module was never found and every install silently fell back
to a local compile.

Normalize to the published form: strip any leading v from $ref and
prepend one, so both 1.38.8 and v1.38.8 resolve to bcachefs-v1.38.8.ko.

Reported-by: Christopher James Halse Rogers (RAOF)
Closes: koverstreet#784

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
…d commit

When bch2_check_key_has_snapshot() deletes a key (returns > 0),
bch2_data_update_init() committed that delete with a NULL disk
reservation. If trans->extra_disk_res is nonzero at that point, the
commit's bch2_trans_commit_extra_disk_res() ->
bch2_disk_reservation_add(c, trans->disk_res, ...) dereferences the NULL
disk_res and oopses (res->sectors += sectors, res == NULL).

The oops fires mid-commit with irqs disabled while holding btree locks,
so the btree_cache cannibalize lock its holder took is never released,
and every subsequent allocation then wedges forever on
btree_cache_cannibalize_lock_blocked ("Allocator stuck? Waited 30s").

Pass &m->op.res - live since bch2_write_op_init() and released on the
out: path by bch2_disk_reservation_put() - so extra_disk_res has a valid
reservation to be accounted against instead of NULL. (The upstream leak
source, the inverted condition in bch2_trans_commit_lazy(), was fixed in
83f72cd; this closes the NULL-deref itself.)

Reported-by: ZorbaTHut
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
… live window

bch2_fs_journal_start() spin_lock_init()s every slot of the pin fifo but only
journal_pin_list_init()s the [front, back) window (the fifo_for_each loop). The
out-of-window slots are left with kvmalloc garbage in their unflushed[]/flushed
list_heads.

fifo_entry() masks its index without a range check - unlike journal_seq_pin(),
which has EBUG_ON(seq < front || seq >= back) - so bch2_journal_pin_set() for a
seq outside the live window lands on one of those uninitialized slots and
list_add()s into garbage, faulting on next->prev. This wedged a userspace fsck
in journal_replay right as it went read-write; the release build compiles out
the EBUG_ON that would have caught the out-of-range access, and when the old
buffer is large enough to be an mmap'd allocation the stale pointer is genuinely
unmapped, so it SIGSEGVs instead of silently corrupting.

Initialize the whole buffer up front, matching bch2_journal_pin_fifo_resize()
which already does. An out-of-window access now hits a valid empty list; the
offending caller is caught separately by the WARN in bch2_journal_pin_set().

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
…ange

fifo_entry() masks without a range check, so bch2_journal_pin_set() for a seq
outside [j->pin.front, j->pin.back) silently lands on an out-of-window slot.
Such a pin is never reclaimed - reclaim only walks the live window - and is left
dangling in the old buffer when the fifo is resized and freed.

WARN_ONCE with the seq and the live range so the offending caller shows up in
the backtrace, rather than debugging the eventual use-after-free.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
A snapshot node with an unreadable state field - garbage, or a zero left on a
key written before bch_snapshot.state existed - but which is still reciprocally
referenced (a live subvolume points at it, or a child names it as parent) must
be live: the reference is stronger evidence than a corrupt state field.
check_snapshot already repairs this by marking it live, but snapshot_state_bad
was flags 0, so the repair only applied under fsck -y. Automatic recovery
(fix_errors=no) hit fsck_errors_not_fixed and went emergency read-only, wedging
the filesystem on every mount.

The common trigger is the root snapshot node on a master-tracking fs: it
predates the state field, and version_upgrade_complete is already at/past the
(as yet unreleased) version the field was added at, so there's no upgrade
transition and the flag-derive that would otherwise rewrite it never fires.

Mark snapshot_state_bad FSCK_AUTOFIX; the referenced->live repair and the 3-6
bit nearest-codeword correction that share it are both corroborated and
uniquely-decodable, safe to self-heal.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
…ount

bch2_journal_pins_to_text() capped the recent-pins dump at N seqs. But a seq
can hold many pins or none, so an N-seq cap either floods on a fat seq or spends
the budget on empty ones - and when the pins worth seeing are a few seqs in, you
never reach them. Count the pins printed and stop at N of those instead.

bch2_journal_seq_pins_to_text() gains a NULL-able pin counter; the debugfs
journal_pins file passes NULL, since it streams every seq unbounded.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
…mplete

bch2_journal_flush_seq() waited a bare 10s before printing "stuck?", and
hardcoded "10s" in the message. On storage where writes legitimately take
longer than that - a Proxmox passthrough with a 15s write tail turned up in the
wild - a single slow flush trips the warning even though nothing is actually
stuck, and the message misreports how long it waited.

Wait max(2 * max_dev_latency, 10s) instead, matching
bch2_journal_res_get_slowpath(), and print the real duration.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
The userspace list.h shim mapped list_replace() and list_replace_init()
straight to liburcu's cds_list_replace{,_init}(), which are broken for an empty
source list: they use old->next (== old when the list is empty) as the
insertion point and leave the new head pointing at the old head instead of at
itself. The kernel's versions self-point on empty.

This bit the journal pin-fifo resize (bch2_journal_pin_fifo_resize), which
list_replace_init()s every [front, back) slot - most of them empty - into a
freshly allocated buffer and then frees the old one. Each empty slot left the
new buffer's list head pointing into the freed old buffer; the next
bch2_journal_pin_set() list_add() wrote through that dangling pointer, a
use-after-free that SIGSEGV'd userspace fsck during journal replay (reported by
debaba and iav). It faulted rather than silently corrupting because the old
buffer was large enough to be an mmap allocation that munmap actually unmaps,
and it was userspace-only because the in-kernel list_replace_init() handles
empty lists correctly.

Shim list_replace{,_init}() to match the kernel - self-point on an empty source,
splice otherwise, avoiding the broken cds_list_replace_init() entirely. This
fixes the whole class; the resize was the only current caller, but any future
one would hit the same trap.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
A filesystem carried onto a version that already believes the state-field
migration has run - e.g. one that tracked an untagged master before the
version was released - never has its snapshot/subvolume state fields derived
from the legacy flag bits: the derive was gated on version_upgrade_complete
being mid-upgrade. Every state field is then 0, and check_subvols hits
fsck_repair_unimplemented on the root subvolume, so the fs won't mount.

Gate the flag-derive on the state field being unset rather than on upgrade
status, so it heals at any version. Mid-upgrade it stays silent (the
expected migration); post-upgrade an unset state is unexpected and is
surfaced + autofixed - subvol_state_bad becomes FSCK_AUTOFIX to match
snapshot_state_bad so the subvolume side self-heals at mount too.

The subvolume flags can only encode unlinked/live - one legacy bit, two
non-live states - so a wiped 'deleted' tombstone would derive to 'live' and
revert a pending deletion. Mirror any non-live state into UNLINKED in
bch2_subvolume_state_set: recovery then derives 'unlinked' and the deletion
pipeline reruns to completion (also what an old kernel needs to see to keep
deleting a tombstone).

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
The archive rule used `ar -rc`, which inserts and replaces members but
never removes ones that have dropped out of $(OBJS). When a source file
is deleted (e.g. fs/alloc/placement.c folded away on a branch), its
object lingered inside libbcachefs.a and dragged a dangling reference to
the now-removed bch2_dev_stripe_order into every link — an
undefined-symbol link failure that survived `cargo clean` and was only
cleared by a full `make clean`.

Remove the archive before recreating it so it only ever contains the
current object set.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
BkeyS<'a> is the mutable counterpart of BkeySC: a borrowed unpacked key
and value, with the lifetime tracked so edits made through it land on the
underlying buffer. It provides key_type() and val_bytes_mut() accessors,
a to_raw() for handing the key to C helpers, and converts From<&mut
bkey_i>. Being a mutable handle it is intentionally not Copy; callers
borrow it (&mut BkeyS) so it can be iterated more than once without ever
aliasing &mut.

BkeySC, which holds only shared references, gains a Copy derive.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
bkey_extent_entries_mut() and bkey_ptrs_mut() now borrow a &mut BkeyS
rather than a &mut bkey_i. A BkeyS can be produced from an unpacked
bkey_i (via From) or from a disassembled on-disk key, so the same
iterators serve both the journal and the metadata-dump btree walk;
borrowing rather than consuming the handle also lets a single key be
iterated more than once (a read scan followed by a rewrite pass).

bkey_ptrs_mut() is now pub so the dump command can use it out of crate.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Allowlist bset_encrypt, journal_nonce and btree_nonce for bindgen and
add btree/read.h to the header set, so the metadata-dump sanitize path
can drive the tested crypto inlines from Rust instead of a C shim.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Add `bcachefs dump --single-replica`, which writes only the
lowest-device-index replica of each btree node and rewrites the other
replica pointers to BCH_SB_MEMBER_INVALID. The read path already skips
INVALID pointers as a degraded slot, so the result is an honest,
single-replica image that reads clean off the surviving replica instead
of the checksum / missing-device errors a lying dump would produce.

De-replication runs through the sanitize path, which now operates on a
BkeyS: the journal's btree_root keys reach it via bkey_i_to_s, and packed
btree-node keys via __bch2_bkey_unpack_key with a format-only unpack (no
struct btree, so none of btree_node_read_done's repair runs on a dump).

Modified bsets and journal entries are re-encrypted and re-checksummed in
Rust over the wrapped bch2_encrypt / bch2_checksum / bset_encrypt,
retiring the crypto helpers from rust_shims.c.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
KEY_TYPE_reservation reserves nr_replicas copies of its size in physical
space but carries no pointers, so __trigger_reservation fed only the
persistent_reserved counter, never the per-snapshot disk-usage counter
(BCH_DISK_ACCOUNTING_snapshot) - which is otherwise summed from extent
pointers.

A snapshot holding only reservations therefore accounted zero sectors to
itself: it misreported its usage in the snapshot listing and the accounting
ioctl, and read as empty to the snapshot-deletion no-data check.

Emit the reserved physical sectors (size * nr_replicas, matching the
replicas-sectors convention) to the snapshot counter alongside the existing
persistent_reserved emission.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
@github-actions
github-actions Bot force-pushed the update_flake_lock_action branch from d1a42e4 to ea1dcfe Compare August 7, 2026 12:32
Flake lock file updates:

• Updated input 'crane':
    'github:ipetkov/crane/0532eb17955225173906d671fb36306bdeb1e2dc?narHash=sha256-EVZd2RsbpreRUDSi9rBwPY%2BZxoyMaiEBbZxxhljbaS4%3D' (2026-05-30)
  → 'github:ipetkov/crane/2c71e194474d13de031d729b729c968ddbe3507f?narHash=sha256-MPaRdVkf6zZP5fCPxYCi8Dr4pZzgmXzg8T9nVEbp3Mw%3D' (2026-08-03)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb?narHash=sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4%3D' (2026-05-13)
  → 'github:hercules-ci/flake-parts/427bf4bd9435fdf21321c8cc628c24efc14c0f7a?narHash=sha256-4dtXQk/NMePegK/nWp5NSeuZKLATItOq61lpEvmXqGw%3D' (2026-08-01)
• Updated input 'flake-parts/nixpkgs-lib':
    'github:nix-community/nixpkgs.lib/f5901329dade4a6ea039af1433fb087bd9c1fe14?narHash=sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ%3D' (2026-04-26)
  → 'github:nix-community/nixpkgs.lib/0e79af5e3d4dcfcd676ab5ba3f95d2e3352e078c?narHash=sha256-OmshNvn2vupOFpYinLUu%2B1Dnpu4n7Q5N3ggGVNHpkUI%3D' (2026-07-26)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/e73de5be04e0eff4190a1432b946d469c794e7b4?narHash=sha256-pGvFkM8N0xEkIIXDe5YYfbEAvHrk4IxBrjB/x8OomhE%3D' (2026-06-26)
  → 'github:nixos/nixpkgs/b7c2ada94fe99c15b0dbcf4d11fd7850b957a436?narHash=sha256-IItrdb7Puk05RqOBWZYFC5X6Wl1sJmCfh5MWVHw5iMM%3D' (2026-08-05)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/85570ef134d92a8702de6afd1f6f0209c863fa91?narHash=sha256-6QBThUi7SuK%2BdgA%2BDCaEkQGZN4kYx6DpXmK45%2BMG9zI%3D' (2026-05-30)
  → 'github:oxalica/rust-overlay/57a23bfaf4f7017267294b161175db1e32eb1c85?narHash=sha256-jfR6OhwurCKn1tREyfOcK/Omxf1Q/DzDDFbnEr1mBLs%3D' (2026-08-07)
• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/790751ff7fd3801feeaf96d7dc416a8d581265ba?narHash=sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0%3D' (2026-04-08)
  → 'github:numtide/treefmt-nix/ae7910970dddc408fe6ab1c8e4b277bb21d72dc0?narHash=sha256-NLSyTCW4K4ofhNBllt3omPasm6QpralXH1DBZOc91Dw%3D' (2026-08-05)
@github-actions
github-actions Bot force-pushed the update_flake_lock_action branch from ea1dcfe to 5ba9f57 Compare August 7, 2026 12:32
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.

2 participants