From 80f9c147f780063735da6fc20fc373dd5e72a1c0 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Tue, 11 Feb 2025 00:04:35 -0500 Subject: [PATCH] btrfs-tree: clean up the fetch function's return set Commit d32f31f411eeb1a8624b99dab223af69f0c8453e ("btrfs-tree: harden `rlower_bound` against exceptional objects") passes the first btrfs item in the result set that is above upper_bound up to `seek_backward`. This is somewhat wasteful as `seek_backward` cannot use such a result. Reverse that change in behavior, while keeping the rest of the other commit. This introduces a new case, where the search ioctl is producing items that are above upper bound, but there are no items in the result set, which continues looping until the end of the filesystem is reached. Handle that by setting an explicit exit variable. Signed-off-by: Zygo Blaxell --- lib/btrfs-tree.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/btrfs-tree.cc b/lib/btrfs-tree.cc index aa8958f..05c132e 100644 --- a/lib/btrfs-tree.cc +++ b/lib/btrfs-tree.cc @@ -418,6 +418,7 @@ namespace crucible { ++loops; fill_sk(sk, unscale_logical(min(scaled_max_logical(), lower_bound))); set rv; + bool too_far = false; do { sk.nr_items = 4; sk.do_ioctl(fd()); @@ -426,6 +427,7 @@ namespace crucible { next_sk(sk, i); // If hdr_stop or !hdr_match, don't inspect the item if (hdr_stop(i)) { + too_far = true; rv.insert(numeric_limits::max()); BTFRLB_DEBUG("(stop)"); break; @@ -438,22 +440,23 @@ namespace crucible { BTFRLB_DEBUG(" " << to_hex(this_logical) << " " << i); const auto scaled_hdr_logical = scale_logical(this_logical); BTFRLB_DEBUG(" " << "(match)"); + if (scaled_hdr_logical > upper_bound) { + too_far = true; + BTFRLB_DEBUG("(" << to_hex(scaled_hdr_logical) << " >= " << to_hex(upper_bound) << ")"); + break; + } if (this_logical <= logical && this_logical > closest_logical) { closest_logical = this_logical; closest_item = i; BTFRLB_DEBUG("(closest)"); } rv.insert(scaled_hdr_logical); - if (scaled_hdr_logical > upper_bound) { - BTFRLB_DEBUG("(" << to_hex(scaled_hdr_logical) << " >= " << to_hex(upper_bound) << ")"); - break; - } BTFRLB_DEBUG("(cont'd)"); } BTFRLB_DEBUG(endl); // We might get a search result that contains only non-matching items. // Keep looping until we find any matching item or we run out of tree. - } while (rv.empty() && !sk.m_result.empty()); + } while (!too_far && rv.empty() && !sk.m_result.empty()); return rv; }, scale_logical(lookbehind_size())); return closest_item;