]> git.hungrycats.org Git - bees/commitdiff
btrfs-free: fix rlower_bound failing to find items at offset zero
authorZygo Blaxell <bees@furryterror.org>
Mon, 23 Mar 2026 07:43:26 +0000 (03:43 -0400)
committerZygo Blaxell <bees@furryterror.org>
Sat, 2 May 2026 03:48:57 +0000 (23:48 -0400)
rlower_bound initialized closest_logical to 0, so a matching item at
offset 0 never passed the `this_logical > closest_logical` check.
Add a `have_closest` flag so the first match is always accepted.

This caused ref_backward to return null when the previous extent was
at offset 0 in the file, which is the common case for the first
extent of any inode.

This has been subtly breaking subvol scans since the extent scan rework
exposed the bug; however, fixing this still doesn't help subvol scans
work at scale, so they're still deprecated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Zygo Blaxell <bees@furryterror.org>
lib/btrfs-tree.cc

index f3e65803215e73d4340fe9777140f2599e09588a..2e19a0d66826bba8376cbe6930cd6827196b462f 100644 (file)
@@ -417,6 +417,7 @@ namespace crucible {
        #define BTFRLB_DEBUG(x) CRUCIBLE_BTRFS_TREE_DEBUG(x)
        #endif
                BtrfsTreeItem closest_item;
+               bool have_closest = false;
                uint64_t closest_logical = 0;
                BtrfsIoctlSearchKey &sk = m_sk;
                size_t loops = 0;
@@ -452,7 +453,8 @@ namespace crucible {
                                                BTFRLB_DEBUG("(" << to_hex(scaled_hdr_logical) << " >= " << to_hex(upper_bound) << ")");
                                                break;
                                        }
-                                       if (this_logical <= logical && this_logical > closest_logical) {
+                                       if (this_logical <= logical && (!have_closest || this_logical > closest_logical)) {
+                                               have_closest = true;
                                                closest_logical = this_logical;
                                                closest_item = i;
                                                BTFRLB_DEBUG("(closest)");