}
}
+Cache::backref_buf_entry_query_set_t
+BtreeBackrefManager::get_cached_backrefs_in_range(
+ paddr_t start,
+ paddr_t end)
+{
+ 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&
+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,
+ paddr_t end)
+{
+ return cache.get_backref_extents_in_range(start, end);
+}
+
+void BtreeBackrefManager::cache_new_backref_extent(
+ paddr_t paddr,
+ extent_types_t type)
+{
+ return cache.add_backref_extent(paddr, type);
+}
+
+BtreeBackrefManager::retrieve_backref_extents_ret
+BtreeBackrefManager::retrieve_backref_extents(
+ Transaction &t,
+ Cache::backref_extent_buf_entry_query_set_t &&backref_extents,
+ std::vector<CachedExtentRef> &extents)
+{
+ return trans_intr::parallel_for_each(
+ backref_extents,
+ [this, &extents, &t](auto &ent) {
+ // only the gc fiber which is single can rewrite backref extents,
+ // so it must be alive
+ assert(is_backref_node(ent.type));
+ LOG_PREFIX(BtreeBackrefManager::retrieve_backref_extents);
+ DEBUGT("getting backref extent of type {} at {}",
+ t,
+ ent.type,
+ ent.paddr);
+ return cache.get_extent_by_type(
+ t, ent.type, ent.paddr, L_ADDR_NULL, BACKREF_NODE_SIZE
+ ).si_then([&extents](auto ext) {
+ extents.emplace_back(std::move(ext));
+ });
+ });
+}
+
} // namespace crimson::os::seastore::backref
auto *bpin = reinterpret_cast<BtreeBackrefPin*>(&pin);
pin_set.retire(bpin->get_range_pin());
}
+
+ Cache::backref_buf_entry_query_set_t
+ 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;
+
+ Cache::backref_extent_buf_entry_query_set_t
+ get_cached_backref_extents_in_range(
+ paddr_t start,
+ paddr_t end) final;
+
+ retrieve_backref_extents_ret retrieve_backref_extents(
+ Transaction &t,
+ Cache::backref_extent_buf_entry_query_set_t &&backref_extents,
+ std::vector<CachedExtentRef> &extents) final;
+
+ void cache_new_backref_extent(paddr_t paddr, extent_types_t type) final;
+
private:
SegmentManagerGroup &sm_group;
Cache &cache;
// created by this insertion
) = 0;
+ virtual Cache::backref_buf_entry_query_set_t
+ 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 Cache::backref_extent_buf_entry_query_set_t
+ get_cached_backref_extents_in_range(
+ paddr_t start,
+ paddr_t end) = 0;
+
+ using retrieve_backref_extents_iertr = trans_iertr<
+ crimson::errorator<
+ crimson::ct_error::input_output_error>
+ >;
+ using retrieve_backref_extents_ret =
+ retrieve_backref_extents_iertr::future<>;
+ virtual retrieve_backref_extents_ret retrieve_backref_extents(
+ Transaction &t,
+ Cache::backref_extent_buf_entry_query_set_t &&backref_extents,
+ std::vector<CachedExtentRef> &extents) = 0;
+
+ virtual void cache_new_backref_extent(paddr_t paddr, extent_types_t type) = 0;
+
/**
* insert new mappings directly from Cache
*/
#include "crimson/os/seastore/segment_manager.h"
#include "crimson/os/seastore/transaction.h"
+namespace crimson::os::seastore::backref {
+class BtreeBackrefManager;
+}
+
namespace crimson::os::seastore {
+class BackrefManager;
class SegmentCleaner;
struct backref_buf_entry_t {
// 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
-public:
- /**
- * get_extent_by_type
- *
- * Based on type, instantiate the correct concrete type
- * and read in the extent at location offset~length.
- */
- template <typename Func>
- get_extent_by_type_ret get_extent_by_type(
- Transaction &t, ///< [in] transaction
- extent_types_t type, ///< [in] type tag
- paddr_t offset, ///< [in] starting addr
- laddr_t laddr, ///< [in] logical address if logical
- seastore_off_t length, ///< [in] length
- Func &&extent_init_func ///< [in] extent init func
- ) {
- return _get_extent_by_type(
- t,
- type,
- offset,
- laddr,
- length,
- extent_init_func_t(std::forward<Func>(extent_init_func)));
- }
- get_extent_by_type_ret get_extent_by_type(
- Transaction &t,
- extent_types_t type,
- paddr_t offset,
- laddr_t laddr,
- seastore_off_t length
- ) {
- return get_extent_by_type(
- t, type, offset, laddr, length, [](CachedExtent &) {});
- }
+ // from the backref tree
- std::set<
- backref_buf_entry_t,
- backref_buf_entry_t::cmp_t> get_backrefs_in_range(
+ using backref_buf_entry_query_set_t =
+ std::set<
+ 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(
return res;
}
- std::set<
- backref_buf_entry_t,
- backref_buf_entry_t::cmp_t> get_del_backrefs_in_range(
+ 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);
return backref_buffer;
}
+public:
+ /**
+ * get_extent_by_type
+ *
+ * Based on type, instantiate the correct concrete type
+ * and read in the extent at location offset~length.
+ */
+ template <typename Func>
+ get_extent_by_type_ret get_extent_by_type(
+ Transaction &t, ///< [in] transaction
+ extent_types_t type, ///< [in] type tag
+ paddr_t offset, ///< [in] starting addr
+ laddr_t laddr, ///< [in] logical address if logical
+ seastore_off_t length, ///< [in] length
+ Func &&extent_init_func ///< [in] extent init func
+ ) {
+ return _get_extent_by_type(
+ t,
+ type,
+ offset,
+ laddr,
+ length,
+ extent_init_func_t(std::forward<Func>(extent_init_func)));
+ }
+ get_extent_by_type_ret get_extent_by_type(
+ Transaction &t,
+ extent_types_t type,
+ paddr_t offset,
+ laddr_t laddr,
+ seastore_off_t length
+ ) {
+ return get_extent_by_type(
+ t, type, offset, laddr, length, [](CachedExtent &) {});
+ }
+
void trim_backref_bufs(const journal_seq_t &trim_to) {
LOG_PREFIX(Cache::trim_backref_bufs);
SUBDEBUG(seastore_cache, "trimming to {}", trim_to);
};
};
+private:
+ ExtentPlacementManager& epm;
+ RootBlockRef root; ///< ref to current root
+ ExtentIndex extents; ///< set of live extents
+
+ journal_seq_t last_commit = JOURNAL_SEQ_MIN;
+
+ /**
+ * dirty
+ *
+ * holds refs to dirty extents. Ordered by CachedExtent::get_dirty_from().
+ */
+ CachedExtent::list dirty;
+
+ using backref_extent_buf_entry_query_set_t =
+ std::set<
+ backref_extent_buf_entry_t,
+ backref_extent_buf_entry_t::cmp_t>;
+ backref_extent_buf_entry_query_set_t backref_extents;
+
void add_backref_extent(paddr_t paddr, extent_types_t type) {
assert(!paddr.is_relative());
auto [iter, inserted] = backref_extents.emplace(paddr, type);
backref_extents.erase(iter);
}
- std::set<
- backref_extent_buf_entry_t,
- backref_extent_buf_entry_t::cmp_t> get_backref_extents_in_range(
+ backref_extent_buf_entry_query_set_t get_backref_extents_in_range(
paddr_t start,
paddr_t end) {
auto start_iter = backref_extents.lower_bound(start);
auto end_iter = backref_extents.upper_bound(end);
- std::set<
- backref_extent_buf_entry_t,
- backref_extent_buf_entry_t::cmp_t> res;
+ backref_extent_buf_entry_query_set_t res;
res.insert(start_iter, end_iter);
return res;
}
-private:
- ExtentPlacementManager& epm;
- RootBlockRef root; ///< ref to current root
- ExtentIndex extents; ///< set of live extents
-
- journal_seq_t last_commit = JOURNAL_SEQ_MIN;
-
- /**
- * dirty
- *
- * holds refs to dirty extents. Ordered by CachedExtent::get_dirty_from().
- */
- CachedExtent::list dirty;
-
- std::set<
- backref_extent_buf_entry_t,
- backref_extent_buf_entry_t::cmp_t> backref_extents;
-
+ friend class crimson::os::seastore::backref::BtreeBackrefManager;
+ friend class crimson::os::seastore::BackrefManager;
/**
* lru
*
* TODO: make the above capacity calculation part of FixedKVNodeLayout
* TODO: the above alignment probably isn't portable without further work
*/
-constexpr size_t INTERNAL_NODE_CAPACITY = 254;
+constexpr size_t INTERNAL_NODE_CAPACITY = 32;
struct LBAInternalNode
: FixedKVInternalNode<
INTERNAL_NODE_CAPACITY,
* TODO: update FixedKVNodeLayout to handle the above calculation
* TODO: the above alignment probably isn't portable without further work
*/
-constexpr size_t LEAF_NODE_CAPACITY = 145;
+constexpr size_t LEAF_NODE_CAPACITY = 32;
/**
* lba_map_val_le_t
config_t config,
SegmentManagerGroupRef&& sm_group,
BackrefManager &backref_manager,
- Cache &cache,
bool detailed)
: detailed(detailed),
config(config),
sm_group(std::move(sm_group)),
backref_manager(backref_manager),
- cache(cache),
ool_segment_seq_allocator(
new SegmentSeqAllocator(segment_type_t::OOL)),
gc_process(*this)
});
}
-SegmentCleaner::retrieve_backref_extents_ret
-SegmentCleaner::_retrieve_backref_extents(
- Transaction &t,
- std::set<
- Cache::backref_extent_buf_entry_t,
- Cache::backref_extent_buf_entry_t::cmp_t> &&backref_extents,
- std::vector<CachedExtentRef> &extents)
-{
- return trans_intr::parallel_for_each(
- backref_extents,
- [this, &extents, &t](auto &ent) {
- // only the gc fiber which is single can rewrite backref extents,
- // so it must be alive
- assert(is_backref_node(ent.type));
- LOG_PREFIX(SegmentCleaner::_retrieve_backref_extents);
- DEBUGT("getting backref extent of type {} at {}",
- t,
- ent.type,
- ent.paddr);
- return cache.get_extent_by_type(
- t, ent.type, ent.paddr, L_ADDR_NULL, BACKREF_NODE_SIZE
- ).si_then([&extents](auto ext) {
- extents.emplace_back(std::move(ext));
- });
- });
-}
-
SegmentCleaner::retrieve_live_extents_ret
SegmentCleaner::_retrieve_live_extents(
Transaction &t,
).si_then([this, FNAME, &extents, &ent, &seq, &t](auto ext) {
if (!ext) {
DEBUGT("addr {} dead, skipping", t, ent.paddr);
- auto backref = cache.get_del_backref(ent.paddr);
+ auto backref = backref_manager.get_cached_backref_removal(ent.paddr);
if (seq == JOURNAL_SEQ_NULL || seq < backref.seq) {
seq = backref.seq;
}
reclaimed = 0;
runs++;
return seastar::do_with(
- cache.get_backref_extents_in_range(
+ backref_manager.get_cached_backref_extents_in_range(
+ *next_reclaim_pos, end_paddr),
+ backref_manager.get_cached_backrefs_in_range(
*next_reclaim_pos, end_paddr),
- cache.get_backrefs_in_range(*next_reclaim_pos, end_paddr),
- cache.get_del_backrefs_in_range(
+ backref_manager.get_cached_backref_removals_in_range(
*next_reclaim_pos, end_paddr),
JOURNAL_SEQ_NULL,
[this, segment_id, &reclaimed, end_paddr]
std::vector<CachedExtentRef>(),
[this, &backref_extents, &backrefs, &reclaimed, &t, &seq]
(auto &extents) {
- return _retrieve_backref_extents(
+ return backref_manager.retrieve_backref_extents(
t, std::move(backref_extents), extents
).si_then([this, &extents, &t, &backrefs] {
return _retrieve_live_extents(
[&reclaimed, this, pavail_ratio, start, &runs, end_paddr] {
LOG_PREFIX(SegmentCleaner::gc_reclaim_space);
#ifndef NDEBUG
- auto ndel_backrefs = cache.get_del_backrefs_in_range(
- *next_reclaim_pos, end_paddr);
+ auto ndel_backrefs =
+ backref_manager.get_cached_backref_removals_in_range(
+ *next_reclaim_pos, end_paddr);
if (!ndel_backrefs.empty()) {
for (auto &del_br : ndel_backrefs) {
ERROR("unexpected del_backref {}~{} {} {}",
SegmentManagerGroupRef sm_group;
BackrefManager &backref_manager;
- Cache &cache;
SpaceTrackerIRef space_tracker;
segments_info_t segments;
config_t config,
SegmentManagerGroupRef&& sm_group,
BackrefManager &backref_manager,
- Cache &cache,
bool detailed = false);
SegmentSeqAllocator& get_ool_segment_seq_allocator() {
using gc_reclaim_space_ret = gc_reclaim_space_ertr::future<>;
gc_reclaim_space_ret gc_reclaim_space();
- using retrieve_backref_extents_iertr = work_iertr;
- using retrieve_backref_extents_ret =
- retrieve_backref_extents_iertr::future<>;
- retrieve_backref_extents_ret _retrieve_backref_extents(
- Transaction &t,
- std::set<
- Cache::backref_extent_buf_entry_t,
- Cache::backref_extent_buf_entry_t::cmp_t> &&backref_extents,
- std::vector<CachedExtentRef> &extents);
using retrieve_live_extents_iertr = work_iertr;
using retrieve_live_extents_ret =
}
if (depth) {
if (depth > 1) {
- cache->add_backref_extent(
+ backref_manager->cache_new_backref_extent(
addr, extent_types_t::BACKREF_INTERNAL);
} else {
- cache->add_backref_extent(
+ backref_manager->cache_new_backref_extent(
addr, extent_types_t::BACKREF_LEAF);
}
}
}).si_then([this] {
LOG_PREFIX(TransactionManager::mount);
- auto &backrefs = cache->get_backrefs();
+ auto &backrefs = backref_manager->get_cached_backrefs();
DEBUG("marking {} backrefs used", backrefs.size());
for (auto &backref : backrefs) {
segment_cleaner->mark_space_used(
seastar::lowres_system_clock::time_point(),
true);
}
- auto &del_backrefs = cache->get_del_backrefs();
+ auto &del_backrefs = backref_manager->get_cached_backref_removals();
DEBUG("marking {} backrefs free", del_backrefs.size());
for (auto &del_backref : del_backrefs) {
segment_cleaner->mark_space_free(
cleaner_config,
std::move(sms),
*backref_manager,
- *cache,
cleaner_is_detailed);
JournalRef journal;
len);
}
}).si_then([&tracker, this] {
- auto &backrefs = cache->get_backrefs();
+ 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.len);
}
}
- auto &del_backrefs = cache->get_del_backrefs();
+ auto &del_backrefs = backref_manager->get_cached_backref_removals();
for (auto &del_backref : del_backrefs) {
if (del_backref.paddr.get_addr_type() == addr_types_t::SEGMENT) {
logger().debug("check_usage: by backref, tracker release {}~{}",