From: Zhang Song Date: Thu, 24 Apr 2025 09:25:37 +0000 (+0800) Subject: crimson/os/seastore/BtreeLBAManager: cleanup the impl of alloc mapping and remap X-Git-Tag: v20.1.0~222^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1ee35a76193ebb524e25373026cfd649ee2c1a03;p=ceph.git crimson/os/seastore/BtreeLBAManager: cleanup the impl of alloc mapping and remap Signed-off-by: Zhang Song (cherry picked from commit d143fa7bb09b004f60efd6c94a6d34e00205249c) --- diff --git a/src/crimson/os/seastore/lba_manager.h b/src/crimson/os/seastore/lba_manager.h index bbc05898c63f..120e3b9b962c 100644 --- a/src/crimson/os/seastore/lba_manager.h +++ b/src/crimson/os/seastore/lba_manager.h @@ -45,7 +45,7 @@ public: * lba value. */ using get_mappings_iertr = base_iertr; - using get_mappings_ret = get_mappings_iertr::future; + using get_mappings_ret = get_mappings_iertr::future; virtual get_mappings_ret get_mappings( Transaction &t, laddr_t offset, extent_len_t length) = 0; @@ -59,7 +59,7 @@ public: */ using get_mapping_iertr = base_iertr::extend< crimson::ct_error::enoent>; - using get_mapping_ret = get_mapping_iertr::future; + using get_mapping_ret = get_mapping_iertr::future; virtual get_mapping_ret get_mapping( Transaction &t, laddr_t offset) = 0; @@ -72,7 +72,7 @@ public: * is called on the LBAMapping. */ using alloc_extent_iertr = base_iertr; - using alloc_extent_ret = alloc_extent_iertr::future; + using alloc_extent_ret = alloc_extent_iertr::future; virtual alloc_extent_ret alloc_extent( Transaction &t, laddr_t hint, @@ -80,7 +80,7 @@ public: extent_ref_count_t refcount) = 0; using alloc_extents_ret = alloc_extent_iertr::future< - std::vector>; + std::vector>; virtual alloc_extents_ret alloc_extents( Transaction &t, laddr_t hint, @@ -126,12 +126,8 @@ public: len = _len; } }; - struct lba_remap_ret_t { - ref_update_result_t ruret; - std::vector remapped_mappings; - }; using remap_iertr = ref_iertr; - using remap_ret = remap_iertr::future; + using remap_ret = remap_iertr::future>; /** * remap_mappings @@ -141,7 +137,7 @@ public: */ virtual remap_ret remap_mappings( Transaction &t, - LBAMappingRef orig_mapping, + LBAMapping orig_mapping, std::vector remaps, std::vector extents // Required if and only // if pin isn't indirect 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 6cb38c5c1ae8..8914e8d5b12b 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 @@ -788,6 +788,106 @@ BtreeLBAManager::_decref_intermediate( }); } +BtreeLBAManager::remap_ret +BtreeLBAManager::remap_mappings( + Transaction &t, + LBAMapping orig_mapping, + std::vector remaps, + std::vector extents) +{ + LOG_PREFIX(BtreeLBAManager::remap_mappings); + struct state_t { + LBAMapping orig_mapping; + std::vector remaps; + std::vector extents; + std::vector alloc_infos; + std::vector ret; + }; + return seastar::do_with( + state_t(std::move(orig_mapping), std::move(remaps), std::move(extents), {}, {}), + [this, &t, FNAME](state_t &state) + { + return update_refcount( + t, state.orig_mapping.get_key(), -1, false + ).si_then([this, &t, &state, FNAME](auto ret) { + // Remapping the shared direct mapping is prohibited, + // the refcount of indirect mapping should always be 1. + ceph_assert(ret.is_removed_mapping()); + + auto orig_laddr = state.orig_mapping.get_key(); + if (!state.orig_mapping.is_indirect()) { + auto &addr = ret.get_removed_mapping().map_value.pladdr; + ceph_assert(addr.is_paddr() && !addr.get_paddr().is_zero()); + return alloc_extents( + t, + (state.remaps.front().offset + orig_laddr).checked_to_laddr(), + std::move(state.extents), + EXTENT_DEFAULT_REF_COUNT + ).si_then([&state](auto ret) { + state.ret = std::move(ret); + return remap_iertr::make_ready_future(); + }); + } + + extent_len_t orig_len = state.orig_mapping.get_length(); + auto intermediate_key = state.orig_mapping.get_intermediate_key(); + ceph_assert(intermediate_key != L_ADDR_NULL); + DEBUGT("remap indirect mapping {}", t, state.orig_mapping); + for (auto &remap : state.remaps) { + DEBUGT("remap 0x{:x}~0x{:x}", t, remap.offset, remap.len); + ceph_assert(remap.len != 0); + ceph_assert(remap.offset + remap.len <= orig_len); + auto remapped_laddr = (orig_laddr + remap.offset) + .checked_to_laddr(); + auto remapped_intermediate_key = (intermediate_key + remap.offset) + .checked_to_laddr(); + state.alloc_infos.emplace_back( + alloc_mapping_info_t::create_indirect( + remapped_laddr, remap.len, remapped_intermediate_key)); + } + + return alloc_sparse_mappings( + t, state.alloc_infos.front().key, state.alloc_infos, + alloc_policy_t::deterministic + ).si_then([&t, &state, this](std::list cursors) { + return seastar::futurize_invoke([&t, &state, this] { + if (state.remaps.size() > 1) { + auto base = state.orig_mapping.get_intermediate_base(); + return update_refcount( + t, base, state.remaps.size() - 1, false + ).si_then([](update_mapping_ret_bare_t ret) { + return ret.take_cursor(); + }); + } else { + return remap_iertr::make_ready_future< + LBACursorRef>(state.orig_mapping.direct_cursor->duplicate()); + } + }).si_then([&state, cursors=std::move(cursors)](auto direct) mutable { + for (auto &cursor : cursors) { + state.ret.emplace_back(LBAMapping::create_indirect( + direct->duplicate(), std::move(cursor))); + } + return remap_iertr::make_ready_future(); + }); + }); + }).si_then([&state] { + assert(state.ret.size() == state.remaps.size()); +#ifndef NDEBUG + auto mapping_it = state.ret.begin(); + auto remap_it = state.remaps.begin(); + for (;mapping_it != state.ret.end(); mapping_it++, remap_it++) { + auto &mapping = *mapping_it; + auto &remap = *remap_it; + assert(mapping.get_key() == state.orig_mapping.get_key() + remap.offset); + assert(mapping.get_length() == remap.len); + } +#endif + return remap_iertr::make_ready_future< + std::vector>(std::move(state.ret)); + }); + }); +} + BtreeLBAManager::update_refcount_ret BtreeLBAManager::update_refcount( Transaction &t, 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 c31923641e84..33cdcee8e5a2 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 @@ -79,14 +79,11 @@ public: return seastar::do_with( std::move(alloc_infos), [&t, hint, this](auto &alloc_infos) { - return _alloc_extents( - t, - hint, - alloc_infos - ).si_then([](auto mappings) { - assert(mappings.size() == 1); - auto mapping = std::move(mappings.front()); - return mapping; + return alloc_contiguous_mappings( + t, hint, alloc_infos, alloc_policy_t::linear_search + ).si_then([](auto cursors) { + assert(cursors.size() == 1); + return LBAMapping::create_direct(std::move(cursors.front())); }); }); } @@ -101,29 +98,27 @@ public: std::vector alloc_infos = { alloc_mapping_info_t::create_indirect( laddr, len, intermediate_key)}; - return alloc_cloned_mappings( - t, - laddr, - std::move(alloc_infos) - ).si_then([&t, this, intermediate_base](auto imappings) { - assert(imappings.size() == 1); - auto &imapping = imappings.front(); - return update_refcount(t, intermediate_base, 1, false - ).si_then([imapping=std::move(imapping)](auto p) mutable { - auto mapping = std::move(p.mapping); - ceph_assert(mapping->is_stable()); - ceph_assert(imapping->is_indirect()); - mapping->make_indirect( - imapping->get_key(), - imapping->get_length(), - imapping->get_intermediate_key()); - return seastar::make_ready_future< - LBAMappingRef>(std::move(mapping)); - }); - }).handle_error_interruptible( - crimson::ct_error::input_output_error::pass_further{}, - crimson::ct_error::assert_all{"unexpect enoent"} - ); + return seastar::do_with( + std::move(alloc_infos), + [this, &t, laddr, intermediate_base](auto &infos) { + return alloc_sparse_mappings( + t, laddr, infos, alloc_policy_t::deterministic + ).si_then([this, &t, intermediate_base](auto cursors) { + ceph_assert(cursors.size() == 1); + ceph_assert(cursors.front()->is_indirect()); + return update_refcount(t, intermediate_base, 1, false + ).si_then([cursors=std::move(cursors)](auto p) mutable { + assert(p.is_alive_mapping()); + auto mapping = LBAMapping::create_indirect( + p.take_cursor(), std::move(cursors.front())); + ceph_assert(mapping.is_stable()); + return alloc_extent_iertr::make_ready_future< + LBAMapping>(std::move(mapping)); + }); + }); + }).handle_error_interruptible( + crimson::ct_error::input_output_error::pass_further{}, + crimson::ct_error::assert_all{"unexpect enoent"}); } alloc_extent_ret alloc_extent( @@ -145,15 +140,12 @@ public: ext)}; return seastar::do_with( std::move(alloc_infos), - [this, &t, hint, refcount](auto &alloc_infos) { - return _alloc_extents( - t, - hint, - alloc_infos - ).si_then([](auto mappings) { - assert(mappings.size() == 1); - auto mapping = std::move(mappings.front()); - return mapping; + [this, &t, hint](auto &alloc_infos) { + return alloc_contiguous_mappings( + t, hint, alloc_infos, alloc_policy_t::linear_search + ).si_then([](auto cursors) { + assert(cursors.size() == 1); + return LBAMapping::create_direct(std::move(cursors.front())); }); }); } @@ -165,8 +157,11 @@ public: extent_ref_count_t refcount) final { std::vector alloc_infos; + assert(!extents.empty()); + auto has_laddr = extents.front()->has_laddr(); for (auto &extent : extents) { assert(extent); + assert(extent->has_laddr() == has_laddr); alloc_infos.emplace_back( alloc_mapping_info_t::create_direct( extent->has_laddr() ? extent->get_laddr() : L_ADDR_NULL, @@ -178,8 +173,35 @@ public: } return seastar::do_with( std::move(alloc_infos), - [this, &t, hint](auto &alloc_infos) { - return _alloc_extents(t, hint, alloc_infos); + [this, &t, hint, has_laddr](auto &alloc_infos) + { + if (has_laddr) { + return alloc_sparse_mappings( + t, hint, alloc_infos, alloc_policy_t::deterministic) +#ifndef NDEBUG + .si_then([&alloc_infos](std::list cursors) { + assert(alloc_infos.size() == cursors.size()); + auto info_p = alloc_infos.begin(); + auto cursor_p = cursors.begin(); + for (; info_p != alloc_infos.end(); info_p++, cursor_p++) { + auto &cursor = *cursor_p; + assert(cursor->get_laddr() == info_p->key); + } + return alloc_extent_iertr::make_ready_future< + std::list>(std::move(cursors)); + }) +#endif + ; + } else { + return alloc_contiguous_mappings( + t, hint, alloc_infos, alloc_policy_t::linear_search); + } + }).si_then([](std::list cursors) { + std::vector ret; + for (auto &cursor : cursors) { + ret.emplace_back(LBAMapping::create_direct(std::move(cursor))); + } + return ret; }); } @@ -194,118 +216,9 @@ public: remap_ret remap_mappings( Transaction &t, - LBAMappingRef orig_mapping, + LBAMapping orig_mapping, std::vector remaps, - std::vector extents) final { - LOG_PREFIX(BtreeLBAManager::remap_mappings); - assert((orig_mapping->is_indirect()) - == (remaps.size() != extents.size())); - return seastar::do_with( - lba_remap_ret_t{}, - std::move(remaps), - std::move(extents), - std::move(orig_mapping), - [&t, FNAME, this](auto &ret, const auto &remaps, - auto &extents, auto &orig_mapping) { - return update_refcount(t, orig_mapping->get_key(), -1, false - ).si_then([&ret, this, &extents, &remaps, - &t, &orig_mapping, FNAME](auto r) { - ret.ruret = std::move(r.ref_update_res); - if (!orig_mapping->is_indirect()) { - ceph_assert(ret.ruret.refcount == 0 && - ret.ruret.addr.is_paddr() && - !ret.ruret.addr.get_paddr().is_zero()); - } - auto fut = alloc_extent_iertr::make_ready_future< - std::vector>(); - laddr_t orig_laddr = orig_mapping->get_key(); - if (orig_mapping->is_indirect()) { - std::vector alloc_infos; - for (auto &remap : remaps) { - extent_len_t orig_len = orig_mapping->get_length(); - paddr_t orig_paddr = orig_mapping->get_val(); - laddr_t intermediate_base = orig_mapping->is_indirect() - ? orig_mapping->get_intermediate_base() - : L_ADDR_NULL; - laddr_t intermediate_key = orig_mapping->is_indirect() - ? orig_mapping->get_intermediate_key() - : L_ADDR_NULL; - auto remap_offset = remap.offset; - auto remap_len = remap.len; - auto remap_laddr = (orig_laddr + remap_offset).checked_to_laddr(); - ceph_assert(intermediate_base != L_ADDR_NULL); - ceph_assert(intermediate_key != L_ADDR_NULL); - ceph_assert(remap_len < orig_len); - ceph_assert(remap_offset + remap_len <= orig_len); - ceph_assert(remap_len != 0); - SUBDEBUGT(seastore_lba, - "remap laddr: {}, remap paddr: {}, remap length: {}," - " intermediate_base: {}, intermediate_key: {}", t, - remap_laddr, orig_paddr, remap_len, - intermediate_base, intermediate_key); - auto remapped_intermediate_key = (intermediate_key + remap_offset).checked_to_laddr(); - alloc_infos.emplace_back( - alloc_mapping_info_t::create_indirect( - remap_laddr, - remap_len, - remapped_intermediate_key)); - } - fut = alloc_cloned_mappings( - t, - (remaps.front().offset + orig_laddr).checked_to_laddr(), - std::move(alloc_infos) - ).si_then([&orig_mapping](auto imappings) mutable { - std::vector mappings; - for (auto &imapping : imappings) { - auto mapping = orig_mapping->duplicate(); - auto bmapping = static_cast(mapping.get()); - bmapping->adjust_mutable_indirect_attrs( - imapping->get_key(), - imapping->get_length(), - imapping->get_intermediate_key()); - mappings.emplace_back(std::move(mapping)); - } - return seastar::make_ready_future>( - std::move(mappings)); - }); - } else { // !orig_mapping->is_indirect() - fut = alloc_extents( - t, - (remaps.front().offset + orig_laddr).checked_to_laddr(), - std::move(extents), - EXTENT_DEFAULT_REF_COUNT); - } - - return fut.si_then([&ret, &remaps, &orig_mapping](auto &&refs) { - assert(refs.size() == remaps.size()); -#ifndef NDEBUG - auto ref_it = refs.begin(); - auto remap_it = remaps.begin(); - for (;ref_it != refs.end(); ref_it++, remap_it++) { - auto &ref = *ref_it; - auto &remap = *remap_it; - assert(ref->get_key() == orig_mapping->get_key() + remap.offset); - assert(ref->get_length() == remap.len); - } -#endif - ret.remapped_mappings = std::move(refs); - return seastar::now(); - }); - }).si_then([&remaps, &t, &orig_mapping, this] { - if (remaps.size() > 1 && orig_mapping->is_indirect()) { - auto intermediate_base = orig_mapping->get_intermediate_base(); - return _incref_extent(t, intermediate_base, remaps.size() - 1 - ).si_then([](auto) { - return seastar::now(); - }); - } - return ref_iertr::now(); - }).si_then([&ret, &remaps] { - assert(ret.remapped_mappings.size() == remaps.size()); - return seastar::make_ready_future(std::move(ret)); - }); - }); - } + std::vector extents) final; /** * init_cached_extent @@ -572,43 +485,6 @@ private: }); } - alloc_extent_iertr::future> alloc_cloned_mappings( - Transaction &t, - laddr_t laddr, - std::vector alloc_infos) - { -#ifndef NDEBUG - for (auto &alloc_info : alloc_infos) { - assert(alloc_info.value.pladdr.get_laddr() != L_ADDR_NULL); - assert(alloc_info.value.refcount == EXTENT_DEFAULT_REF_COUNT); - } -#endif - return seastar::do_with( - std::move(alloc_infos), - [this, &t, laddr](auto &alloc_infos) { - return _alloc_extents( - t, - laddr, - alloc_infos - ).si_then([&alloc_infos](auto mappings) { - assert(alloc_infos.size() == mappings.size()); - std::vector rets; - auto mit = mappings.begin(); - auto ait = alloc_infos.begin(); - for (; mit != mappings.end(); mit++, ait++) { - auto mapping = static_cast(mit->release()); - [[maybe_unused]] auto &alloc_info = *ait; - assert(mapping->get_key() == alloc_info.key); - assert(mapping->get_raw_val().get_laddr() == - alloc_info.value.pladdr.get_laddr()); - assert(mapping->get_length() == alloc_info.value.len); - rets.emplace_back(mapping); - } - return rets; - }); - }); - } - using _get_cursor_ret = get_mapping_iertr::future; _get_cursor_ret get_cursor( op_context_t c, diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index 6d6e4562712c..f2169e0ffdcc 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -636,10 +636,9 @@ public: std::vector(remaps.begin(), remaps.end()), std::move(extents) ).si_then([FNAME, &t](auto ret) { - SUBDEBUGT(seastore_tm, "remapped {} pins", - t, ret.remapped_mappings.size()); + SUBDEBUGT(seastore_tm, "remapped {} pins", t, ret.size()); return Cache::retire_extent_iertr::make_ready_future< - std::vector>(std::move(ret.remapped_mappings)); + std::vector>(std::move(ret)); }); }).handle_error_interruptible( remap_pin_iertr::pass_further{},