From 46b0097a8eb58cab9cae7343f2b1b6c116a7bbc8 Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Tue, 27 Jul 2021 23:00:56 +0800 Subject: [PATCH] crimson/os/seastore: make fresh extents go though the extent placement manager Signed-off-by: Xuehan Xu --- src/crimson/os/seastore/cache.h | 5 ++++ src/crimson/os/seastore/cached_extent.h | 5 +++- .../os/seastore/extent_placement_manager.h | 23 +++++++++++++++++- src/crimson/os/seastore/seastore_types.cc | 2 ++ src/crimson/os/seastore/seastore_types.h | 5 ++++ src/crimson/os/seastore/transaction.h | 24 ++++++++++++++++++- src/crimson/os/seastore/transaction_manager.h | 2 +- 7 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/crimson/os/seastore/cache.h b/src/crimson/os/seastore/cache.h index a265c601e0f..2cad75a7721 100644 --- a/src/crimson/os/seastore/cache.h +++ b/src/crimson/os/seastore/cache.h @@ -367,6 +367,11 @@ public: } } + /** + * alloc_new_extent + * + * Allocates a fresh extent. if delayed is true, addr will be alloc'd later + */ template TCachedExtentRef alloc_new_extent( Transaction &t, ///< [in, out] current transaction diff --git a/src/crimson/os/seastore/cached_extent.h b/src/crimson/os/seastore/cached_extent.h index 1f1730b2b4c..8bbaa2a2c00 100644 --- a/src/crimson/os/seastore/cached_extent.h +++ b/src/crimson/os/seastore/cached_extent.h @@ -23,6 +23,7 @@ class CachedExtent; using CachedExtentRef = boost::intrusive_ptr; class SegmentedAllocator; class TransactionManager; +class ExtentPlacementManager; // #define DEBUG_CACHED_EXTENT_REF #ifdef DEBUG_CACHED_EXTENT_REF @@ -471,6 +472,7 @@ protected: friend class crimson::os::seastore::ool_record_t; friend class crimson::os::seastore::SegmentedAllocator; friend class crimson::os::seastore::TransactionManager; + friend class crimson::os::seastore::ExtentPlacementManager; }; std::ostream &operator<<(std::ostream &, CachedExtent::extent_state_t); @@ -565,7 +567,8 @@ public: void erase(CachedExtent &extent) { assert(extent.parent_index); - auto erased = extent_index.erase(extent); + auto erased = extent_index.erase( + extent_index.s_iterator_to(extent)); extent.parent_index = nullptr; if (erased) { diff --git a/src/crimson/os/seastore/extent_placement_manager.h b/src/crimson/os/seastore/extent_placement_manager.h index 934f012c01c..e7cfb8a8abd 100644 --- a/src/crimson/os/seastore/extent_placement_manager.h +++ b/src/crimson/os/seastore/extent_placement_manager.h @@ -214,7 +214,6 @@ class SegmentedAllocator : public ExtentAllocator { finish_record_ret finish_write( Transaction& t, ool_record_t& record); - segment_off_t fake_paddr_off = 0; bool _needs_roll(segment_off_t length) const; write_iertr::future<> _write( @@ -325,6 +324,28 @@ public: return extent; } + template< + typename T, + std::enable_if_t, int> = 0> + TCachedExtentRef alloc_new_extent( + Transaction& t, + segment_off_t length, + ool_placement_hint_t hint = ool_placement_hint_t::NONE) + { + auto dtype = get_allocator_type(hint); + TCachedExtentRef extent; + if (need_delayed_allocation(dtype)) { + // set a unique temperary paddr, this is necessary because + // transaction's write_set is indexed by paddr + extent = cache.alloc_new_extent(t, length, true); + } else { + extent = cache.alloc_new_extent(t, length); + } + extent->backend_type = dtype; + extent->hint = hint; + return extent; + } + /** * delayed_alloc_or_ool_write * diff --git a/src/crimson/os/seastore/seastore_types.cc b/src/crimson/os/seastore/seastore_types.cc index 82871df3d90..5b18e4f55d1 100644 --- a/src/crimson/os/seastore/seastore_types.cc +++ b/src/crimson/os/seastore/seastore_types.cc @@ -17,6 +17,8 @@ std::ostream &segment_to_stream(std::ostream &out, const segment_id_t &t) return out << "ZERO_SEG"; else if (t == FAKE_SEG_ID) return out << "FAKE_SEG"; + else if (t == DELAYED_TEMP_SEG_ID) + return out << "DELAYED_TEMP_SEG"; else return out << t; } diff --git a/src/crimson/os/seastore/seastore_types.h b/src/crimson/os/seastore/seastore_types.h index 465cd2dfb47..f5e05297591 100644 --- a/src/crimson/os/seastore/seastore_types.h +++ b/src/crimson/os/seastore/seastore_types.h @@ -55,6 +55,8 @@ constexpr segment_id_t FAKE_SEG_ID = */ constexpr segment_id_t ZERO_SEG_ID = std::numeric_limits::max() - 5; +constexpr segment_id_t DELAYED_TEMP_SEG_ID = + std::numeric_limits::max() - 6; std::ostream &segment_to_stream(std::ostream &, const segment_id_t &t); @@ -215,6 +217,9 @@ constexpr paddr_t make_fake_paddr(segment_off_t off) { constexpr paddr_t zero_paddr() { return paddr_t{ZERO_SEG_ID, 0}; } +constexpr paddr_t delayed_temp_paddr(segment_off_t off) { + return paddr_t{DELAYED_TEMP_SEG_ID, off}; +} struct __attribute((packed)) paddr_le_t { ceph_le32 segment = ceph_le32(NULL_SEG_ID); diff --git a/src/crimson/os/seastore/transaction.h b/src/crimson/os/seastore/transaction.h index 7fda438bba8..0161a5e90c8 100644 --- a/src/crimson/os/seastore/transaction.h +++ b/src/crimson/os/seastore/transaction.h @@ -7,6 +7,7 @@ #include +#include "crimson/common/log.h" #include "crimson/os/seastore/ordering_handle.h" #include "crimson/os/seastore/seastore_types.h" #include "crimson/os/seastore/cached_extent.h" @@ -39,6 +40,11 @@ public: if (out) *out = CachedExtentRef(&*iter); return get_extent_ret::PRESENT; + } else if (auto iter = delayed_set.find_offset(addr); + iter != delayed_set.end()) { + if (out) + *out = CachedExtentRef(&*iter); + return get_extent_ret::PRESENT; } else if ( auto iter = read_set.find(addr); iter != read_set.end()) { @@ -60,7 +66,12 @@ public: // will affect relative paddrs, and it should be rare to retire a fresh // extent. ref->state = CachedExtent::extent_state_t::INVALID; - write_set.erase(*ref); + if (ref->is_inline()) { + write_set.erase(*ref); + } else { + // if ref is not relative, it must be in the delayed set + delayed_set.erase(*ref); + } } else if (ref->is_mutation_pending()) { ref->state = CachedExtent::extent_state_t::INVALID; write_set.erase(*ref); @@ -89,6 +100,8 @@ public: ceph_assert(!is_weak()); if (delayed) { assert(ref->is_logical()); + ref->set_paddr(delayed_temp_paddr(delayed_temp_offset)); + delayed_temp_offset += ref->get_length(); delayed_alloc_list.emplace_back(ref->cast()); delayed_set.insert(*ref); } else { @@ -216,6 +229,10 @@ public: i->state = CachedExtent::extent_state_t::INVALID; write_set.erase(*i++); } + for (auto i = delayed_set.begin(); + i != delayed_set.end();) { + delayed_set.erase(*i++); + } } friend class crimson::os::seastore::SeaStore; @@ -224,8 +241,10 @@ public: void reset_preserve_handle(journal_seq_t initiated_after) { root.reset(); offset = 0; + delayed_temp_offset = 0; read_set.clear(); write_set.clear(); + delayed_set.clear(); fresh_block_list.clear(); mutated_block_list.clear(); delayed_alloc_list.clear(); @@ -274,9 +293,12 @@ private: RootBlockRef root; ///< ref to root if read or written by transaction segment_off_t offset = 0; ///< relative offset of next block + segment_off_t delayed_temp_offset = 0; read_set_t read_set; ///< set of extents read by paddr ExtentIndex write_set; ///< set of extents written by paddr + ExtentIndex delayed_set; ///< set of extents whose paddr + /// allocation are delayed std::list fresh_block_list; ///< list of fresh blocks std::list mutated_block_list; ///< list of mutated blocks diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index 695484d45f9..2a455ab426b 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -284,7 +284,7 @@ public: Transaction &t, laddr_t hint, extent_len_t len) { - auto ext = cache->alloc_new_extent( + auto ext = epm->alloc_new_extent( t, len); return lba_manager->alloc_extent( -- 2.39.5