diff --git a/src/crimson/os/seastore/async_cleaner.cc b/src/crimson/os/seastore/async_cleaner.cc index 1a5b3df1479..e0d198be78f 100644 --- a/src/crimson/os/seastore/async_cleaner.cc +++ b/src/crimson/os/seastore/async_cleaner.cc @@ -907,12 +907,11 @@ AsyncCleaner::_retrieve_live_extents( std::vector &extents) { return seastar::do_with( - JOURNAL_SEQ_NULL, std::move(backrefs), - [this, &t, &extents](auto &seq, auto &backrefs) { + [this, &t, &extents](auto &backrefs) { return trans_intr::parallel_for_each( backrefs, - [this, &extents, &t, &seq](auto &ent) { + [this, &extents, &t](auto &ent) { LOG_PREFIX(AsyncCleaner::_retrieve_live_extents); DEBUGT("getting extent of type {} at {}~{}", t, @@ -921,13 +920,10 @@ AsyncCleaner::_retrieve_live_extents( ent.len); return ecb->get_extents_if_live( t, ent.type, ent.paddr, ent.laddr, ent.len - ).si_then([this, FNAME, &extents, &ent, &seq, &t](auto list) { + ).si_then([&extents, &ent, &t](auto list) { + LOG_PREFIX(AsyncCleaner::_retrieve_live_extents); if (list.empty()) { DEBUGT("addr {} dead, skipping", t, ent.paddr); - auto backref = backref_manager.get_cached_backref_removal(ent.paddr); - if (seq == JOURNAL_SEQ_NULL || seq < backref.seq) { - seq = backref.seq; - } } else { for (auto &e : list) { extents.emplace_back(std::move(e)); @@ -935,9 +931,6 @@ AsyncCleaner::_retrieve_live_extents( } return ExtentCallbackInterface::rewrite_extent_iertr::now(); }); - }).si_then([&seq] { - return retrieve_live_extents_iertr::make_ready_future< - journal_seq_t>(std::move(seq)); }); }); } @@ -1008,63 +1001,61 @@ AsyncCleaner::gc_reclaim_space_ret AsyncCleaner::gc_reclaim_space() reclaimed = 0; runs++; return seastar::do_with( - backref_manager.get_cached_backref_extents_in_range( - reclaim_state->start_pos, reclaim_state->end_pos), - backref_manager.get_cached_backrefs_in_range( - reclaim_state->start_pos, reclaim_state->end_pos), - backref_manager.get_cached_backref_removals_in_range( - reclaim_state->start_pos, reclaim_state->end_pos), JOURNAL_SEQ_NULL, [this, &reclaimed, &pin_list]( - auto &backref_extents, - auto &backrefs, - auto &del_backrefs, auto &seq) { return ecb->with_transaction_intr( Transaction::src_t::CLEANER_RECLAIM, "reclaim_space", - [this, &backref_extents, &backrefs, &seq, - &del_backrefs, &reclaimed, &pin_list](auto &t) { - LOG_PREFIX(AsyncCleaner::gc_reclaim_space); - DEBUGT("{} backrefs, {} del_backrefs, {} pins", t, - backrefs.size(), del_backrefs.size(), pin_list.size()); - for (auto &br : backrefs) { - if (seq == JOURNAL_SEQ_NULL - || (br.seq != JOURNAL_SEQ_NULL && br.seq > seq)) - seq = br.seq; - } - for (auto &pin : pin_list) { - backrefs.emplace( - pin->get_key(), - pin->get_val(), - pin->get_length(), - pin->get_type(), - journal_seq_t()); - } - for (auto &del_backref : del_backrefs) { - DEBUGT("del_backref {}~{} {} {}", t, - del_backref.paddr, del_backref.len, del_backref.type, del_backref.seq); - auto it = backrefs.find(del_backref.paddr); - if (it != backrefs.end() && - it->len == del_backref.len) - backrefs.erase(it); - if (seq == JOURNAL_SEQ_NULL - || (del_backref.seq != JOURNAL_SEQ_NULL && del_backref.seq > seq)) - seq = del_backref.seq; - } + [this, &seq, &reclaimed, &pin_list](auto &t) { return seastar::do_with( std::vector(), - [this, &backref_extents, &backrefs, &reclaimed, &t, &seq] + [this, &reclaimed, &t, &seq, &pin_list] (auto &extents) { return backref_manager.retrieve_backref_extents( - t, std::move(backref_extents), extents - ).si_then([this, &extents, &t, &backrefs] { + t, + backref_manager.get_cached_backref_extents_in_range( + reclaim_state->start_pos, reclaim_state->end_pos), + extents + ).si_then([this, &extents, &t, &pin_list] { + // calculate live extents + auto backref_set = + backref_manager.get_cached_backrefs_in_range( + reclaim_state->start_pos, reclaim_state->end_pos); + std::set< + backref_buf_entry_t, + backref_buf_entry_t::cmp_t> backrefs; + for (auto &pin : pin_list) { + backrefs.emplace(pin->get_key(), pin->get_val(), + pin->get_length(), pin->get_type(), journal_seq_t()); + } + for (auto &backref : backref_set) { + if (backref.laddr == L_ADDR_NULL) { + auto it = backrefs.find(backref.paddr); + assert(it->len == backref.len); + backrefs.erase(it); + } else { + backrefs.emplace(backref.paddr, backref.laddr, + backref.len, backref.type, backref.seq); + } + } + // retrieve live extents return _retrieve_live_extents( t, std::move(backrefs), extents); - }).si_then([this, &seq, &t](auto nseq) { - if (nseq != JOURNAL_SEQ_NULL && - (nseq > seq || seq == JOURNAL_SEQ_NULL)) - seq = nseq; + }).si_then([this, &t, &seq] { + // we need to get the backref_set in range again, because + // it can change during live extents retrieval + auto backref_set = + backref_manager.get_cached_backrefs_in_range( + reclaim_state->start_pos, reclaim_state->end_pos); + // calculate the journal seq up to which the backref merge + // should run + for (auto &backref : backref_set) { + if (backref.seq != JOURNAL_SEQ_NULL && + (backref.seq > seq || seq == JOURNAL_SEQ_NULL)) { + seq = backref.seq; + } + } auto fut = BackrefManager::merge_cached_backrefs_iertr::now(); if (seq != JOURNAL_SEQ_NULL) { fut = backref_manager.merge_cached_backrefs( @@ -1089,7 +1080,9 @@ AsyncCleaner::gc_reclaim_space_ret AsyncCleaner::gc_reclaim_space() t.mark_segment_to_release(reclaim_state->get_segment_id()); } return ecb->submit_transaction_direct( - t, std::make_optional(std::move(seq))); + t, std::make_optional(std::move(seq)), + std::make_optional>( + {reclaim_state->start_pos, reclaim_state->end_pos})); }); }); }); @@ -1098,18 +1091,6 @@ AsyncCleaner::gc_reclaim_space_ret AsyncCleaner::gc_reclaim_space() }).safe_then( [&reclaimed, this, pavail_ratio, start, &runs] { LOG_PREFIX(AsyncCleaner::gc_reclaim_space); -#ifndef NDEBUG - auto ndel_backrefs = - backref_manager.get_cached_backref_removals_in_range( - reclaim_state->start_pos, reclaim_state->end_pos); - if (!ndel_backrefs.empty()) { - for (auto &del_br : ndel_backrefs) { - ERROR("unexpected del_backref {}~{} {} {}", - del_br.paddr, del_br.len, del_br.type, del_br.seq); - } - ceph_abort("impossible"); - } -#endif stats.reclaiming_bytes += reclaimed; auto d = seastar::lowres_system_clock::now() - start; DEBUG("duration: {}, pavail_ratio before: {}, repeats: {}", d, pavail_ratio, runs); @@ -1311,7 +1292,8 @@ AsyncCleaner::maybe_release_segment(Transaction &t) return sm_group->release_segment(to_release ).safe_then([this, FNAME, &t, to_release] { auto old_usage = calc_utilization(to_release); - if(old_usage != 0) { + if(unlikely(old_usage != 0)) { + space_tracker->dump_usage(to_release); ERRORT("segment {} old_usage {} != 0", t, to_release, old_usage); ceph_abort(); } @@ -1386,10 +1368,11 @@ void AsyncCleaner::mark_space_used( void AsyncCleaner::mark_space_free( paddr_t addr, - extent_len_t len) + extent_len_t len, + bool init_scan) { LOG_PREFIX(AsyncCleaner::mark_space_free); - if (!init_complete) { + if (!init_complete && !init_scan) { return; } if (addr.get_addr_type() != addr_types_t::SEGMENT) { diff --git a/src/crimson/os/seastore/async_cleaner.h b/src/crimson/os/seastore/async_cleaner.h index 8aef05a09bc..94791486ff9 100644 --- a/src/crimson/os/seastore/async_cleaner.h +++ b/src/crimson/os/seastore/async_cleaner.h @@ -666,7 +666,8 @@ public: submit_transaction_direct_iertr::future<>; virtual submit_transaction_direct_ret submit_transaction_direct( Transaction &t, - std::optional seq_to_trim = std::nullopt) = 0; + std::optional seq_to_trim = std::nullopt, + std::optional> gc_range = std::nullopt) = 0; }; private: @@ -835,7 +836,8 @@ public: void mark_space_free( paddr_t addr, - extent_len_t len); + extent_len_t len, + bool init_scan = false); SpaceTrackerIRef get_empty_space_tracker() const { return space_tracker->make_empty(); @@ -1110,7 +1112,7 @@ private: using retrieve_live_extents_iertr = work_iertr; using retrieve_live_extents_ret = - retrieve_live_extents_iertr::future; + retrieve_live_extents_iertr::future<>; retrieve_live_extents_ret _retrieve_live_extents( Transaction &t, std::set< diff --git a/src/crimson/os/seastore/backref/btree_backref_manager.cc b/src/crimson/os/seastore/backref/btree_backref_manager.cc index 9823a218a0e..5d0d6bf7881 100644 --- a/src/crimson/os/seastore/backref/btree_backref_manager.cc +++ b/src/crimson/os/seastore/backref/btree_backref_manager.cc @@ -437,32 +437,12 @@ BtreeBackrefManager::get_cached_backrefs_in_range( return cache.get_backrefs_in_range(start, end); } -Cache::backref_buf_entry_query_set_t -BtreeBackrefManager::get_cached_backref_removals_in_range( - paddr_t start, - paddr_t end) -{ - return cache.get_del_backrefs_in_range(start, end); -} - -const backref_buf_entry_t::set_t& -BtreeBackrefManager::get_cached_backref_removals() -{ - return cache.get_del_backrefs(); -} - -const backref_buf_entry_t::set_t& +const backref_set_t& BtreeBackrefManager::get_cached_backrefs() { return cache.get_backrefs(); } -backref_buf_entry_t -BtreeBackrefManager::get_cached_backref_removal(paddr_t addr) -{ - return cache.get_del_backref(addr); -} - Cache::backref_extent_buf_entry_query_set_t BtreeBackrefManager::get_cached_backref_extents_in_range( paddr_t start, @@ -503,8 +483,4 @@ BtreeBackrefManager::retrieve_backref_extents( }); } -bool BtreeBackrefManager::backref_should_be_removed(paddr_t paddr) { - return cache.backref_should_be_removed(paddr); -} - } // namespace crimson::os::seastore::backref diff --git a/src/crimson/os/seastore/backref/btree_backref_manager.h b/src/crimson/os/seastore/backref/btree_backref_manager.h index ddfae7ec48c..5bc7476373e 100644 --- a/src/crimson/os/seastore/backref/btree_backref_manager.h +++ b/src/crimson/os/seastore/backref/btree_backref_manager.h @@ -104,15 +104,7 @@ public: get_cached_backrefs_in_range( paddr_t start, paddr_t end) final; - - Cache::backref_buf_entry_query_set_t - get_cached_backref_removals_in_range( - paddr_t start, - paddr_t end) final; - - const backref_buf_entry_t::set_t& get_cached_backref_removals() final; - const backref_buf_entry_t::set_t& get_cached_backrefs() final; - backref_buf_entry_t get_cached_backref_removal(paddr_t addr) final; + const backref_set_t& get_cached_backrefs() final; Cache::backref_extent_buf_entry_query_set_t get_cached_backref_extents_in_range( @@ -126,8 +118,6 @@ public: void cache_new_backref_extent(paddr_t paddr, extent_types_t type) final; - bool backref_should_be_removed(paddr_t paddr) final; - private: SegmentManagerGroup &sm_group; Cache &cache; diff --git a/src/crimson/os/seastore/backref_manager.h b/src/crimson/os/seastore/backref_manager.h index 8082356d395..76a08257c97 100644 --- a/src/crimson/os/seastore/backref_manager.h +++ b/src/crimson/os/seastore/backref_manager.h @@ -87,23 +87,13 @@ public: get_cached_backrefs_in_range( paddr_t start, paddr_t end) = 0; - - virtual Cache::backref_buf_entry_query_set_t - get_cached_backref_removals_in_range( - paddr_t start, - paddr_t end) = 0; - - virtual const backref_buf_entry_t::set_t& get_cached_backref_removals() = 0; - virtual const backref_buf_entry_t::set_t& get_cached_backrefs() = 0; - virtual backref_buf_entry_t get_cached_backref_removal(paddr_t addr) = 0; + virtual const backref_set_t& get_cached_backrefs() = 0; virtual Cache::backref_extent_buf_entry_query_set_t get_cached_backref_extents_in_range( paddr_t start, paddr_t end) = 0; - virtual bool backref_should_be_removed(paddr_t paddr) = 0; - using retrieve_backref_extents_iertr = trans_iertr< crimson::errorator< crimson::ct_error::input_output_error> diff --git a/src/crimson/os/seastore/cache.cc b/src/crimson/os/seastore/cache.cc index c2f88f2df82..54922cd02c7 100644 --- a/src/crimson/os/seastore/cache.cc +++ b/src/crimson/os/seastore/cache.cc @@ -28,6 +28,15 @@ SET_SUBSYS(seastore_cache); namespace crimson::os::seastore { +std::ostream &operator<<(std::ostream &out, const backref_buf_entry_t &ent) { + return out << "backref_buf_entry_t{" + << ent.paddr << "~" << ent.len << ", " + << "laddr: " << ent.laddr << ", " + << "type: " << ent.type << ", " + << "seq: " << ent.seq << ", " + << "}"; +} + Cache::Cache( ExtentPlacementManager &epm) : epm(epm), @@ -1351,39 +1360,9 @@ void Cache::backref_batch_update( if (!backref_buffer) { backref_buffer = std::make_unique(); } - // backref_buf_entry_t::laddr == L_ADDR_NULL means erase + for (auto &ent : list) { - if (ent->laddr == L_ADDR_NULL) { - auto insert_set_iter = backref_inserted_set.find( - ent->paddr, backref_buf_entry_t::cmp_t()); - if (insert_set_iter == backref_inserted_set.end()) { - // backref to be removed isn't in the backref buffer, - // it must be in the backref tree. - auto [it, insert] = backref_remove_set.insert(*ent); - boost::ignore_unused(insert); -#ifndef NDEBUG - if (!insert) { - ERROR("backref_remove_set already contains {}", ent->paddr); - } -#endif - assert(insert); - } else { - // the backref insertion hasn't been applied to the - // backref tree - auto seq = insert_set_iter->seq; - auto it = backref_buffer->backrefs_by_seq.find(seq); - ceph_assert(it != backref_buffer->backrefs_by_seq.end()); - auto &backref_buf = it->second; - assert(insert_set_iter->backref_buf_hook.is_linked()); - backref_buf.br_list.erase( - backref_buf_entry_t::list_t::s_iterator_to(*insert_set_iter)); - backref_inserted_set.erase(insert_set_iter); - } - } else { - auto [it, insert] = backref_inserted_set.insert(*ent); - boost::ignore_unused(insert); - assert(insert); - } + backref_set.insert(*ent); } auto iter = backref_buffer->backrefs_by_seq.find(seq); diff --git a/src/crimson/os/seastore/cache.h b/src/crimson/os/seastore/cache.h index a0cd4e178f9..54a96c12b59 100644 --- a/src/crimson/os/seastore/cache.h +++ b/src/crimson/os/seastore/cache.h @@ -68,6 +68,7 @@ struct backref_buf_entry_t { const backref_buf_entry_t &r) { return l.paddr == r.paddr; } + using set_hook_t = boost::intrusive::set_member_hook< boost::intrusive::link_mode< @@ -84,7 +85,7 @@ struct backref_buf_entry_t { backref_buf_entry_t, set_hook_t, &backref_buf_entry_t::backref_set_hook>; - using set_t = boost::intrusive::set< + using set_t = boost::intrusive::multiset< backref_buf_entry_t, backref_set_member_options, boost::intrusive::constant_time_size>; @@ -113,9 +114,13 @@ struct backref_buf_entry_t { }; }; +std::ostream &operator<<(std::ostream &out, const backref_buf_entry_t &ent); + using backref_buf_entry_ref = std::unique_ptr; +using backref_set_t = backref_buf_entry_t::set_t; + struct backref_buf_t { backref_buf_t(std::vector &&refs) : backrefs(std::move(refs)) { for (auto &ref : backrefs) { @@ -555,27 +560,23 @@ private: } backref_cache_ref backref_buffer; - // backrefs that needs to be inserted into the backref tree - backref_buf_entry_t::set_t backref_inserted_set; - backref_buf_entry_t::set_t backref_remove_set; // backrefs needs to be removed - // from the backref tree + backref_set_t backref_set; // in cache backrefs indexed by paddr_t using backref_buf_entry_query_set_t = - std::set< + std::multiset< backref_buf_entry_t, backref_buf_entry_t::cmp_t>; + backref_buf_entry_query_set_t get_backrefs_in_range( paddr_t start, paddr_t end) { - auto start_iter = backref_inserted_set.lower_bound( + auto start_iter = backref_set.lower_bound( start, backref_buf_entry_t::cmp_t()); - auto end_iter = backref_inserted_set.lower_bound( + auto end_iter = backref_set.lower_bound( end, backref_buf_entry_t::cmp_t()); - std::set< - backref_buf_entry_t, - backref_buf_entry_t::cmp_t> res; + backref_buf_entry_query_set_t res; for (auto it = start_iter; it != end_iter; it++) { @@ -584,47 +585,8 @@ private: return res; } - backref_buf_entry_query_set_t get_del_backrefs_in_range( - paddr_t start, - paddr_t end) { - LOG_PREFIX(Cache::get_del_backrefs_in_range); - SUBDEBUG(seastore_cache, "total {} del_backrefs", backref_remove_set.size()); - auto start_iter = backref_remove_set.lower_bound( - start, - backref_buf_entry_t::cmp_t()); - auto end_iter = backref_remove_set.lower_bound( - end, - backref_buf_entry_t::cmp_t()); - std::set< - backref_buf_entry_t, - backref_buf_entry_t::cmp_t> res; - for (auto it = start_iter; - it != end_iter; - it++) { - res.emplace(it->paddr, it->laddr, it->len, it->type, it->seq); - } - SUBDEBUG(seastore_cache, "{} del_backrefs in range", res.size()); - return res; - } - - backref_buf_entry_t get_del_backref( - paddr_t addr) { - auto it = backref_remove_set.find(addr, backref_buf_entry_t::cmp_t()); - assert(it != backref_remove_set.end()); - return *it; - } - - bool backref_should_be_removed(paddr_t addr) { - return backref_remove_set.find( - addr, backref_buf_entry_t::cmp_t()) != backref_remove_set.end(); - } - - const backref_buf_entry_t::set_t& get_backrefs() { - return backref_inserted_set; - } - - const backref_buf_entry_t::set_t& get_del_backrefs() { - return backref_remove_set; + const backref_set_t& get_backrefs() { + return backref_set; } backref_cache_ref& get_backref_buffer() { diff --git a/src/crimson/os/seastore/seastore.cc b/src/crimson/os/seastore/seastore.cc index ddbd44e3da6..125a374edde 100644 --- a/src/crimson/os/seastore/seastore.cc +++ b/src/crimson/os/seastore/seastore.cc @@ -1043,7 +1043,6 @@ SeaStore::tm_ret SeaStore::_do_transaction_step( std::vector &d_onodes, ceph::os::Transaction::iterator &i) { - LOG_PREFIX(SeaStore::_do_transaction_step); auto op = i.decode_op(); using ceph::os::Transaction; @@ -1088,6 +1087,7 @@ SeaStore::tm_ret SeaStore::_do_transaction_step( } } return fut.si_then([&, op, this](auto&& get_onode) -> tm_ret { + LOG_PREFIX(SeaStore::_do_transaction_step); OnodeRef &o = onodes[op->oid]; if (!o) { assert(get_onode); diff --git a/src/crimson/os/seastore/transaction_manager.cc b/src/crimson/os/seastore/transaction_manager.cc index 12ac86c7911..1224114b276 100644 --- a/src/crimson/os/seastore/transaction_manager.cc +++ b/src/crimson/os/seastore/transaction_manager.cc @@ -137,13 +137,10 @@ TransactionManager::mount_ertr::future<> TransactionManager::mount() t, addr, len); - if (addr.is_real() && - !backref_manager->backref_should_be_removed(addr)) { - async_cleaner->mark_space_used( - addr, - len , - /* init_scan = */ true); - } + async_cleaner->mark_space_used( + addr, + len , + /* init_scan = */ true); if (is_backref_node(type)) { ceph_assert(depth); backref_manager->cache_new_backref_extent(addr, type); @@ -154,16 +151,24 @@ TransactionManager::mount_ertr::future<> TransactionManager::mount() cache->update_tree_extents_num(type, 1); return seastar::now(); } - }).si_then([this] { + }).si_then([this, &t] { LOG_PREFIX(TransactionManager::mount); auto &backrefs = backref_manager->get_cached_backrefs(); - DEBUG("marking {} backrefs used", backrefs.size()); + DEBUGT("scan backref cache", t); for (auto &backref : backrefs) { - async_cleaner->mark_space_used( - backref.paddr, - backref.len, - true); - cache->update_tree_extents_num(backref.type, 1); + if (backref.laddr == L_ADDR_NULL) { + async_cleaner->mark_space_free( + backref.paddr, + backref.len, + true); + cache->update_tree_extents_num(backref.type, -1); + } else { + async_cleaner->mark_space_used( + backref.paddr, + backref.len, + true); + cache->update_tree_extents_num(backref.type, 1); + } } return seastar::now(); }); @@ -321,7 +326,8 @@ TransactionManager::submit_transaction( TransactionManager::submit_transaction_direct_ret TransactionManager::submit_transaction_direct( Transaction &tref, - std::optional seq_to_trim) + std::optional seq_to_trim, + std::optional> gc_range) { LOG_PREFIX(TransactionManager::submit_transaction_direct); SUBTRACET(seastore_t, "start", tref); @@ -354,11 +360,26 @@ TransactionManager::submit_transaction_direct( }).si_then([this, FNAME, &tref] { SUBTRACET(seastore_t, "about to prepare", tref); return tref.get_handle().enter(write_pipeline.prepare); - }).si_then([this, FNAME, &tref, seq_to_trim=std::move(seq_to_trim)]() mutable + }).si_then([this, FNAME, &tref, seq_to_trim=std::move(seq_to_trim), + gc_range=std::move(gc_range)]() mutable -> submit_transaction_iertr::future<> { if (seq_to_trim && *seq_to_trim != JOURNAL_SEQ_NULL) { cache->trim_backref_bufs(*seq_to_trim); } + +#ifndef NDEBUG + if (gc_range) { + auto backref_set = + backref_manager->get_cached_backrefs_in_range( + gc_range->first, gc_range->second); + for (auto &backref : backref_set) { + ERRORT("unexpected backref: {}~{}, {}, {}, {}", + tref, backref.paddr, backref.len, backref.laddr, + backref.type, backref.seq); + ceph_abort("impossible"); + } + } +#endif auto record = cache->prepare_record(tref, async_cleaner.get()); tref.get_handle().maybe_release_collection_lock(); diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index d5c153df43c..295ba8f35ca 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -484,7 +484,8 @@ public: using AsyncCleaner::ExtentCallbackInterface::submit_transaction_direct_ret; submit_transaction_direct_ret submit_transaction_direct( Transaction &t, - std::optional seq_to_trim = std::nullopt) final; + std::optional seq_to_trim = std::nullopt, + std::optional> gc_range = std::nullopt) final; /** * flush diff --git a/src/test/crimson/seastore/test_transaction_manager.cc b/src/test/crimson/seastore/test_transaction_manager.cc index 34f37951128..54ba912b5e3 100644 --- a/src/test/crimson/seastore/test_transaction_manager.cc +++ b/src/test/crimson/seastore/test_transaction_manager.cc @@ -402,9 +402,8 @@ struct transaction_manager_test_t : [this, &tracker](auto &t) { return backref_manager->scan_mapped_space( t, - [&tracker, this](auto offset, auto len, depth_t, extent_types_t) { - if (offset.get_addr_type() == addr_types_t::SEGMENT && - !backref_manager->backref_should_be_removed(offset)) { + [&tracker](auto offset, auto len, depth_t, extent_types_t) { + if (offset.get_addr_type() == addr_types_t::SEGMENT) { logger().debug("check_usage: tracker alloc {}~{}", offset, len); tracker->allocate( @@ -416,12 +415,17 @@ struct transaction_manager_test_t : auto &backrefs = backref_manager->get_cached_backrefs(); for (auto &backref : backrefs) { if (backref.paddr.get_addr_type() == addr_types_t::SEGMENT) { - logger().debug("check_usage: by backref, tracker alloc {}~{}", - backref.paddr, backref.len); - tracker->allocate( - backref.paddr.as_seg_paddr().get_segment_id(), - backref.paddr.as_seg_paddr().get_segment_off(), - backref.len); + if (backref.laddr == L_ADDR_NULL) { + tracker->release( + backref.paddr.as_seg_paddr().get_segment_id(), + backref.paddr.as_seg_paddr().get_segment_off(), + backref.len); + } else { + tracker->allocate( + backref.paddr.as_seg_paddr().get_segment_id(), + backref.paddr.as_seg_paddr().get_segment_off(), + backref.len); + } } } return seastar::now();