From: Samuel Just Date: Thu, 9 Oct 2025 21:19:41 +0000 (+0000) Subject: crimson/.../transaction_manager: convert rewrite_logical_extent to coroutine X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3d0128c1634ff725823dae2da64704f5014e9726;p=ceph-ci.git crimson/.../transaction_manager: convert rewrite_logical_extent to coroutine Signed-off-by: Samuel Just --- diff --git a/src/crimson/os/seastore/transaction_manager.cc b/src/crimson/os/seastore/transaction_manager.cc index d46fb8f5005..761be357649 100644 --- a/src/crimson/os/seastore/transaction_manager.cc +++ b/src/crimson/os/seastore/transaction_manager.cc @@ -633,96 +633,80 @@ TransactionManager::rewrite_logical_extent( * extents since we're going to do it again once we either do the ool write * or allocate a relative inline addr. TODO: refactor AsyncCleaner to * avoid this complication. */ - return lba_manager->get_mapping(t, *extent - ).si_then([this, &t, extent, nextent](auto mapping) { - return lba_manager->update_mapping( - t, - std::move(mapping), - extent->get_length(), - extent->get_paddr(), - *nextent - ).discard_result(); - }).handle_error_interruptible( + auto mapping = co_await lba_manager->get_mapping( + t, *extent + ).handle_error_interruptible( rewrite_extent_iertr::pass_further{}, crimson::ct_error::assert_all{"unexpected enoent"} ); + co_await lba_manager->update_mapping( + t, + std::move(mapping), + extent->get_length(), + extent->get_paddr(), + *nextent + ); } else { assert(get_extent_category(extent->get_type()) == data_category_t::DATA); + auto length = extent->get_length(); - return cache->read_extent_maybe_partial( - t, std::move(extent), 0, length - ).si_then([this, FNAME, &t](auto extent) { - assert(extent->is_fully_loaded()); - cache->retire_extent(t, extent); - auto extents = cache->alloc_new_data_extents_by_type( - t, - extent->get_type(), - extent->get_length(), - extent->get_user_hint(), - // get target rewrite generation - extent->get_rewrite_generation()); - return seastar::do_with( - std::move(extents), - 0, - extent->get_length(), - extent_ref_count_t(0), - [this, FNAME, extent, &t] - (auto &extents, auto &off, auto &left, auto &refcount) - { - return trans_intr::do_for_each( - extents, - [extent, this, FNAME, &t, &off, &left, &refcount](auto &_nextent) - { - auto nextent = _nextent->template cast(); - bool first_extent = (off == 0); - ceph_assert(left >= nextent->get_length()); - nextent->rewrite(t, *extent, off); - DEBUGT("rewriting data -- {} to {}", t, *extent, *nextent); - - /* This update_mapping is, strictly speaking, unnecessary for delayed_alloc - * extents since we're going to do it again once we either do the ool write - * or allocate a relative inline addr. TODO: refactor AsyncCleaner to - * avoid this complication. */ - auto fut = base_iertr::now(); - if (first_extent) { - assert(off == 0); - fut = lba_manager->get_mapping(t, *extent - ).si_then([this, &t, extent, nextent, - &refcount](auto mapping) { - return lba_manager->update_mapping( - t, - std::move(mapping), - extent->get_length(), - extent->get_paddr(), - *nextent - ).si_then([&refcount](auto c) { - refcount = c; - }); - }).handle_error_interruptible( - rewrite_extent_iertr::pass_further{}, - crimson::ct_error::assert_all{"unexpected enoent"} - ); - } else { - ceph_assert(refcount != 0); - fut = lba_manager->alloc_extent( - t, - (extent->get_laddr() + off).checked_to_laddr(), - *nextent, - refcount - ).si_then([extent, nextent, off](auto mapping) { - ceph_assert(mapping.get_key() == extent->get_laddr() + off); - ceph_assert(mapping.get_val() == nextent->get_paddr()); - return seastar::now(); - }); - } - return fut.si_then([&off, &left, nextent] { - off += nextent->get_length(); - left -= nextent->get_length(); - return seastar::now(); - }); - }); - }); - }); + extent = co_await cache->read_extent_maybe_partial( + t, std::move(extent), 0, length); + assert(extent->is_fully_loaded()); + cache->retire_extent(t, extent); + auto extents = cache->alloc_new_data_extents_by_type( + t, + extent->get_type(), + extent->get_length(), + extent->get_user_hint(), + // get target rewrite generation + extent->get_rewrite_generation()); + extent_len_t off = 0; + auto left = extent->get_length(); + extent_ref_count_t refcount = 0; + for (auto &_nextent : extents) { + auto nextent = _nextent->template cast(); + bool first_extent = (off == 0); + ceph_assert(left >= nextent->get_length()); + nextent->rewrite(t, *extent, off); + DEBUGT("rewriting data -- {} to {}", t, *extent, *nextent); + + /* This update_mapping is, strictly speaking, unnecessary for delayed_alloc + * extents since we're going to do it again once we either do the ool write + * or allocate a relative inline addr. TODO: refactor AsyncCleaner to + * avoid this complication. */ + if (first_extent) { + assert(off == 0); + auto mapping = co_await lba_manager->get_mapping( + t, *extent + ).handle_error_interruptible( + rewrite_extent_iertr::pass_further{}, + crimson::ct_error::assert_all{"unexpected enoent"} + ); + refcount = co_await lba_manager->update_mapping( + t, + std::move(mapping), + extent->get_length(), + extent->get_paddr(), + *nextent + ).handle_error_interruptible( + rewrite_extent_iertr::pass_further{}, + crimson::ct_error::assert_all{"unexpected enoent"} + ); + } else { + ceph_assert(refcount != 0); + auto mapping = co_await lba_manager->alloc_extent( + t, + (extent->get_laddr() + off).checked_to_laddr(), + *nextent, + refcount + ); + ceph_assert(mapping.get_key() == extent->get_laddr() + off); + ceph_assert(mapping.get_val() == nextent->get_paddr()); + } + off += nextent->get_length(); + left -= nextent->get_length(); + } } }