btrfs: resumed snapshot deletion resets drop_progress to zero ============================================================== https://pelam.fi/btrfs-drop-progress/ (index.html is the same in readable form) When btrfs_drop_snapshot() resumes a partially dropped subvolume it copies the saved key only into wc->update_progress; wc->drop_progress and wc->drop_level stay zero. A commit or unmount before the resumed run drops its first reference writes drop key (0 0 0) level 0. The next mount restarts the drop from the first slot and tries to free blocks still shared with a surviving snapshot again: transaction abort ("unable to find ref byte nr ... errno=-117"). In the test runs btrfs check then reported errors and reads under the snapshot returned EIO. Regression from aea6f028d01d (v5.1-rc1). Files ----- 0001-btrfs-keep-drop_progress-when-resuming-snapshot-deletion.patch Kernel fix (git format-patch against v7.3.1; applies to v7.0.14 .. v7.4-rc1). 0001-btrfs-test-that-a-resumed-snapshot-deletion-keeps-it.patch fstests regression test btrfs/355 (format-patch against fstests master 22348afe). fstests/355, fstests/355.out The same test as plain files: copy to tests/btrfs/ of an fstests tree. repro-simple2.sh Minimal reproducer (root, ~70 s): 2G loop + dm-delay, 100k files, snapshot, delete, two interrupted mounts, then an uninterrupted one. Prints "BUG: ..." and exits 1 on the abort. Needs mkfiles.py next to it. repro-simple.sh Same sequence with checks: drop key via dump-tree after each step, dmesg, btrfs check --readonly, snapshot content manifest. Exit 0 = bug, 1 = correct, 2 = inconclusive. Needs mkfiles.py and manifest.py next to it. mkfiles.py, manifest.py Helpers: build the tall tree (one ~4K leaf per file); hash a tree's data and xattrs. SUMMARY.md Write-up: results, environment, reproducers, limits. logs/ab/ Per-run logs of both reproducers, 3 runs each on the stock, self-built unpatched and self-built patched btrfs.ko; dmesg and btrfs check output; module hashes. logs/btrfs-355/ fstests btrfs/355 runs: 355-30k (final test, SATA SSD), 355-ram (loop files on tmpfs; 356 there is a temporary copy with 30k files), 355-trim and 355-comment (re-runs after comment-only changes). logs/fstests-quick/ fstests -g quick summaries (unpatched vs patched module). logs/dmesg-abort-lines.txt All abort/critical lines from the logs, counted. sha256sums sha256sum -c sha256sums (run inside this directory). Running ------- Use a throwaway VM; the reproducers corrupt the btrfs they create (in an image file, nothing else is touched) and can abort a transaction in the running kernel. sudo ./repro-simple2.sh /var/tmp/work # needs btrfs-progs, dmsetup, python3 sudo ./repro-simple.sh /var/tmp/work fstests: copy fstests/355* to tests/btrfs/ (or apply the patch), then ./check btrfs/355 Tested ------ Ubuntu 26.10 VM (4 vCPU, 5 GB RAM, SATA SSD), kernel 7.3.0-9-generic (v7.3-rc6 based), btrfs-progs 7.1. btrfs.ko built from the matching Ubuntu source with and without the fix, same toolchain as stock. Results in SUMMARY.md. Status ------ The kernel patch was posted to linux-btrfs@vger.kernel.org: https://lore.kernel.org/linux-btrfs/20261103-drop-progress-v1-1-16e345565109@pelam.fi/ The fstests test (btrfs/355) was posted separately to fstests@vger.kernel.org: https://lore.kernel.org/fstests/20261103-btrfs-355-v1-1-fb0a30b4983b@pelam.fi/ Neither is merged. Contact: Peter Lamberg