From f8d93e71463875eab24dbbee8506c9237393a063 Mon Sep 17 00:00:00 2001 From: Xinyu Huang Date: Fri, 21 Apr 2023 15:10:49 +0000 Subject: [PATCH] crimson/os/seastore/transaction_manager: implement alloc_remapped_extent Signed-off-by: Xinyu Huang (cherry picked from commit cf6e46e57afc44b46d7855dcb5849724f6ddfcbb) --- src/crimson/os/seastore/cache.h | 42 ++++++++++++++++ src/crimson/os/seastore/cached_extent.h | 6 +++ src/crimson/os/seastore/transaction_manager.h | 49 +++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/src/crimson/os/seastore/cache.h b/src/crimson/os/seastore/cache.h index 153d7c3c96ca3..2f7346fe3583b 100644 --- a/src/crimson/os/seastore/cache.h +++ b/src/crimson/os/seastore/cache.h @@ -895,6 +895,48 @@ public: return ret; } + /** + * alloc_remapped_extent + * + * Allocates an EXIST_CLEAN extent. Use the buffer to fill the new extent + * if buffer exists. + */ + template + TCachedExtentRef alloc_remapped_extent( + Transaction &t, + laddr_t remap_laddr, + paddr_t remap_paddr, + extent_len_t remap_length, + laddr_t original_laddr, + std::optional &&original_bptr) { + LOG_PREFIX(Cache::alloc_remapped_extent); + SUBTRACET(seastore_cache, "allocate {} {}B, hint={}", + t, T::TYPE, remap_length, remap_laddr); + assert(remap_laddr >= original_laddr); + TCachedExtentRef ext; + if (original_bptr.has_value()) { + // shallow copy the buffer from original extent + auto nbp = ceph::bufferptr( + *original_bptr, + remap_laddr - original_laddr, + remap_length); + // ExtentPlacementManager::alloc_new_extent will make a new + // (relative/temp) paddr, so make extent directly + ext = CachedExtent::make_cached_extent_ref(std::move(nbp)); + } else { + ext = CachedExtent::make_placeholder_cached_extent_ref(remap_length); + } + + ext->init(CachedExtent::extent_state_t::EXIST_CLEAN, + remap_paddr, + PLACEMENT_HINT_NULL, + NULL_GENERATION, + t.get_trans_id()); + + t.add_fresh_extent(ext); + return ext; + } + /** * alloc_new_extent * diff --git a/src/crimson/os/seastore/cached_extent.h b/src/crimson/os/seastore/cached_extent.h index f2186f1d41fc2..a074966658cc4 100644 --- a/src/crimson/os/seastore/cached_extent.h +++ b/src/crimson/os/seastore/cached_extent.h @@ -733,6 +733,12 @@ protected: return new T(std::forward(args)...); } + template + static TCachedExtentRef make_placeholder_cached_extent_ref( + extent_len_t length) { + return new T(length); + } + void reset_prior_instance() { prior_instance.reset(); } diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index 80b292203fedf..420d3da6f9d98 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -683,6 +683,55 @@ private: }); } + /** + * alloc_remapped_extent + * + * Allocates a new extent at given remap_paddr that must be absolute and + * use the buffer to fill the new extent if buffer exists. Otherwise, will + * not read disk to fill the new extent. + * Returns the new extent. + * + * Should make sure the end laddr of remap extent <= the end laddr of + * original extent when using this method. + */ + using alloc_remapped_extent_iertr = + alloc_extent_iertr::extend_ertr; + using alloc_remapped_extent_ret = + alloc_remapped_extent_iertr::future; + template + alloc_remapped_extent_ret alloc_remapped_extent( + Transaction &t, + laddr_t remap_laddr, + paddr_t remap_paddr, + extent_len_t remap_length, + laddr_t original_laddr, + std::optional &&original_bptr) { + LOG_PREFIX(TransactionManager::alloc_remapped_extent); + SUBDEBUG(seastore_tm, "alloc remapped extent: remap_laddr: {}, " + "remap_paddr: {}, remap_length: {}, has data in cache: {} ", + remap_laddr, remap_paddr, remap_length, + original_bptr.has_value() ? "true":"false"); + auto ext = cache->alloc_remapped_extent( + t, + remap_laddr, + remap_paddr, + remap_length, + original_laddr, + std::move(original_bptr)); + return lba_manager->alloc_extent( + t, + remap_laddr, + remap_length, + remap_paddr, + ext.get() + ).si_then([remap_laddr, remap_length, remap_paddr](auto &&ref) { + assert(ref->get_key() == remap_laddr); + assert(ref->get_val() == remap_paddr); + assert(ref->get_length() == remap_length); + return alloc_remapped_extent_iertr::make_ready_future + (std::move(ref)); + }); + } public: // Testing interfaces -- 2.39.5