From a637390b0456d423197754f469d9e5a1d342c4d6 Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Thu, 30 May 2024 19:26:49 +0800 Subject: [PATCH] crimson/os/seastore/btree_lba_manager: allow _alloc_extents to alloc non-continuous extents as long as it doesn't violate the order of lba keys Signed-off-by: Xuehan Xu (cherry picked from commit 05a51cfd9358c94effee3e4abf2b6bcb04bdffa2) --- .../lba_manager/btree/btree_lba_manager.cc | 34 ++++++++++- .../lba_manager/btree/btree_lba_manager.h | 57 ++++++++++++++----- 2 files changed, 75 insertions(+), 16 deletions(-) diff --git a/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.cc b/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.cc index 74364d6245cb1..bf0a8e3ec791e 100644 --- a/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.cc +++ b/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.cc @@ -307,10 +307,27 @@ BtreeLBAManager::_alloc_extents( std::vector &alloc_infos, extent_ref_count_t refcount) { + ceph_assert(hint != L_ADDR_NULL); extent_len_t total_len = 0; +#ifndef NDEBUG + bool laddr_null = (alloc_infos.front().key == L_ADDR_NULL); + laddr_t last_end = hint; for (auto &info : alloc_infos) { - total_len += info.len; + assert((info.key == L_ADDR_NULL) == (laddr_null)); + if (!laddr_null) { + assert(info.key >= last_end); + last_end = info.key + info.len; + } + } +#endif + if (alloc_infos.front().key == L_ADDR_NULL) { + for (auto &info : alloc_infos) { + total_len += info.len; + } + } else { + total_len = alloc_infos.back().key + alloc_infos.back().len - hint; } + struct state_t { laddr_t last_end; @@ -379,6 +396,9 @@ BtreeLBAManager::_alloc_extents( alloc_infos, [c, addr, hint, &btree, &state, FNAME, total_len, &rets, refcount](auto &alloc_info) { + if (alloc_info.key != L_ADDR_NULL) { + state.last_end = alloc_info.key; + } return btree.insert( c, *state.insert_iter, @@ -396,13 +416,23 @@ BtreeLBAManager::_alloc_extents( c.trans, addr, total_len, hint, state.last_end); if (alloc_info.extent) { ceph_assert(alloc_info.val.is_paddr()); + assert(alloc_info.val == iter.get_val().pladdr); + assert(alloc_info.len == iter.get_val().len); + if (alloc_info.extent->has_laddr()) { + assert(alloc_info.key == alloc_info.extent->get_laddr()); + assert(alloc_info.key == iter.get_key()); + } else { + alloc_info.extent->set_laddr(iter.get_key()); + } alloc_info.extent->set_laddr(iter.get_key()); } ceph_assert(inserted); rets.emplace_back(iter.get_pin(c)); return iter.next(c).si_then([&state, &alloc_info](auto it) { state.insert_iter = it; - state.last_end += alloc_info.len; + if (alloc_info.key == L_ADDR_NULL) { + state.last_end += alloc_info.len; + } }); }); }); diff --git a/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h b/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h index 43807efb5fcf9..7a4dbbd5c26ed 100644 --- a/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h +++ b/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h @@ -225,10 +225,36 @@ public: struct alloc_mapping_info_t { + laddr_t key = L_ADDR_NULL; // once assigned, the allocation to + // key must be exact and successful extent_len_t len = 0; pladdr_t val; uint32_t checksum = 0; LogicalCachedExtent* extent = nullptr; + + static alloc_mapping_info_t create_zero(extent_len_t len) { + return {L_ADDR_NULL, len, P_ADDR_ZERO, 0, nullptr}; + } + static alloc_mapping_info_t create_indirect( + laddr_t laddr, + extent_len_t len, + laddr_t intermediate_key) { + return { + laddr, + len, + intermediate_key, + 0, // crc will only be used and checked with LBA direct mappings + // also see pin_to_extent(_by_type) + nullptr}; + } + static alloc_mapping_info_t create_direct( + laddr_t laddr, + extent_len_t len, + paddr_t paddr, + uint32_t checksum, + LogicalCachedExtent *extent) { + return {laddr, len, paddr, checksum, extent}; + } }; alloc_extent_ret reserve_region( @@ -237,7 +263,7 @@ public: extent_len_t len) final { std::vector alloc_infos = { - alloc_mapping_info_t{len, P_ADDR_ZERO, 0, nullptr}}; + alloc_mapping_info_t::create_zero(len)}; return seastar::do_with( std::move(alloc_infos), [&t, hint, this](auto &alloc_infos) { @@ -293,8 +319,14 @@ public: { // The real checksum will be updated upon transaction commit assert(ext.get_last_committed_crc() == 0); - std::vector alloc_infos = {{ - ext.get_length(), ext.get_paddr(), ext.get_last_committed_crc(), &ext}}; + assert(!ext.has_laddr()); + std::vector alloc_infos = { + alloc_mapping_info_t::create_direct( + L_ADDR_NULL, + ext.get_length(), + ext.get_paddr(), + ext.get_last_committed_crc(), + &ext)}; return seastar::do_with( std::move(alloc_infos), [this, &t, hint, refcount](auto &alloc_infos) { @@ -319,11 +351,13 @@ public: { std::vector alloc_infos; for (auto &extent : extents) { - alloc_infos.emplace_back(alloc_mapping_info_t{ - extent->get_length(), - pladdr_t(extent->get_paddr()), - extent->get_last_committed_crc(), - extent.get()}); + alloc_infos.emplace_back( + alloc_mapping_info_t::create_direct( + extent->has_laddr() ? extent->get_laddr() : L_ADDR_NULL, + extent->get_length(), + extent->get_paddr(), + extent->get_last_committed_crc(), + extent.get())); } return seastar::do_with( std::move(alloc_infos), @@ -573,12 +607,7 @@ private: { assert(intermediate_key != L_ADDR_NULL); std::vector alloc_infos = { - alloc_mapping_info_t{ - len, - intermediate_key, - 0, // crc will only be used and checked with LBA direct mappings - // also see pin_to_extent(_by_type) - nullptr}}; + alloc_mapping_info_t::create_indirect(L_ADDR_NULL, len, intermediate_key)}; return seastar::do_with( std::move(alloc_infos), [this, &t, laddr](auto &alloc_infos) { -- 2.39.5