diff --git a/src/crimson/os/seastore/lba_manager/btree/lba_btree_node_impl.cc b/src/crimson/os/seastore/lba_manager/btree/lba_btree_node_impl.cc index 93f52adf635..c75152103e4 100644 --- a/src/crimson/os/seastore/lba_manager/btree/lba_btree_node_impl.cc +++ b/src/crimson/os/seastore/lba_manager/btree/lba_btree_node_impl.cc @@ -180,56 +180,42 @@ LBAInternalNode::mutate_internal_address_ret LBAInternalNode::mutate_internal_ad LBAInternalNode::find_hole_ret LBAInternalNode::find_hole( op_context_t c, - laddr_t min, - laddr_t max, + laddr_t min_addr, + laddr_t max_addr, extent_len_t len) { logger().debug( "LBAInternalNode::find_hole min={}, max={}, len={}, *this={}", - min, max, len, *this); - auto bounds = bound(min, max); - return seastar::do_with( - bounds.first, - bounds.second, - L_ADDR_NULL, - [=](auto &i, auto &e, auto &ret) { - return crimson::do_until( - [=, &i, &e, &ret] { - if (i == e) { - return find_hole_ertr::make_ready_future>( - std::make_optional(L_ADDR_NULL)); - } - return get_lba_btree_extent( - c, - get_meta().depth - 1, - i->get_val(), - get_paddr() - ).safe_then([=, &i](auto extent) mutable { - auto lb = std::max(min, i->get_key()); - auto ub = i->get_next_key_or_max(); - logger().debug( - "LBAInternalNode::find_hole extent {} lb {} ub {}", - *extent, - lb, - ub); - return extent->find_hole( - c, - lb, - ub, - len); - }).safe_then([&i, &ret](auto addr) mutable { - i++; - if (addr != L_ADDR_NULL) { - ret = addr; - } - return find_hole_ertr::make_ready_future>( - addr == L_ADDR_NULL ? std::nullopt : - std::make_optional(addr)); - }); - }).safe_then([&ret]() { - return ret; - }); - }); + min_addr, max_addr, len, *this); + auto [begin, end] = bound(min_addr, max_addr); + return seastar::repeat_until_value( + [i=begin, e=end, c, min_addr, len, this]() mutable { + if (i == e) { + return seastar::make_ready_future>( + std::make_optional(L_ADDR_NULL)); + } + return get_lba_btree_extent(c, + get_meta().depth - 1, + i->get_val(), + get_paddr()).safe_then( + [c, min_addr, len, i](auto extent) mutable { + auto lb = std::max(min_addr, i->get_key()); + auto ub = i->get_next_key_or_max(); + logger().debug("LBAInternalNode::find_hole extent {} lb {} ub {}", + *extent, lb, ub); + return extent->find_hole(c, lb, ub, len); + }).safe_then([&i](auto addr) mutable -> std::optional { + if (addr == L_ADDR_NULL) { + ++i; + return {}; + } else { + return addr; + } + }, + // TODO: GCC enters a dead loop if crimson::do_until() is used + // or erroratorized future is returned + crimson::ct_error::assert_all{ "fix me - APIv6" }); + }); } LBAInternalNode::scan_mappings_ret LBAInternalNode::scan_mappings(