From 30ffda19bad844ee493b668825ed72a425c05c2d Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Wed, 9 Jul 2025 17:54:44 +0800 Subject: [PATCH] crimson/os/seastore/transaction_manager: complete indirect mappings before reading Signed-off-by: Xuehan Xu --- src/crimson/os/seastore/transaction_manager.h | 102 ++++++++++-------- 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index cbc75bcced720..32500343c806d 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -293,55 +293,67 @@ public: // must be user-oriented required by maybe_init assert(is_user_transaction(t.get_src())); - extent_len_t direct_partial_off = partial_off; - bool is_clone = pin.is_clone(); - std::optional maybe_indirect_info; - if (pin.is_indirect()) { - auto intermediate_offset = pin.get_intermediate_offset(); - direct_partial_off = intermediate_offset + partial_off; - maybe_indirect_info = indirect_info_t{ - intermediate_offset, pin.get_length()}; - } - - LOG_PREFIX(TransactionManager::read_pin); - SUBDEBUGT(seastore_tm, "{} {} 0x{:x}~0x{:x} direct_off=0x{:x} ...", - t, T::TYPE, pin, partial_off, partial_len, direct_partial_off); - return pin.refresh( - ).si_then([&t, this, direct_partial_off, partial_len, - maybe_init=std::move(maybe_init)](auto npin) mutable { - // checking the lba child must be atomic with creating - // and linking the absent child - auto ret = get_extent_if_linked(t, std::move(npin)); - if (ret.index() == 1) { - return std::get<1>(ret - ).si_then([direct_partial_off, partial_len, this, &t](auto extent) { - return cache->read_extent_maybe_partial( - t, std::move(extent), direct_partial_off, partial_len); - }).si_then([maybe_init=std::move(maybe_init)](auto extent) { - if (!extent->is_seen_by_users()) { - maybe_init(*extent); - extent->set_seen_by_users(); - } - return std::move(extent); - }); + ).si_then([this, &t](auto npin) { + if (npin.is_indirect()) { + return lba_manager->complete_indirect_lba_mapping( + t, std::move(npin)); } else { - auto &r = std::get<0>(ret); - return this->pin_to_extent( - t, std::move(r.mapping), std::move(r.child_pos), - direct_partial_off, partial_len, - std::move(maybe_init)); + return LBAManager::complete_lba_mapping_iertr::make_ready_future< + LBAMapping>(std::move(npin)); } - }).si_then([FNAME, maybe_indirect_info, is_clone, &t](TCachedExtentRef ext) { - if (maybe_indirect_info.has_value()) { - SUBDEBUGT(seastore_tm, "got indirect +0x{:x}~0x{:x} is_clone={} {}", - t, maybe_indirect_info->intermediate_offset, - maybe_indirect_info->length, is_clone, *ext); - } else { - SUBDEBUGT(seastore_tm, "got direct is_clone={} {}", - t, is_clone, *ext); + }).si_then([&t, this, partial_off, partial_len, + maybe_init=std::move(maybe_init)](auto npin) mutable { + + extent_len_t direct_partial_off = partial_off; + bool is_clone = npin.is_clone(); + std::optional maybe_indirect_info; + if (npin.is_indirect()) { + auto intermediate_offset = npin.get_intermediate_offset(); + direct_partial_off = intermediate_offset + partial_off; + maybe_indirect_info = indirect_info_t{ + intermediate_offset, npin.get_length()}; } - return maybe_indirect_extent_t{ext, maybe_indirect_info, is_clone}; + + LOG_PREFIX(TransactionManager::read_pin); + SUBDEBUGT(seastore_tm, "{} {} 0x{:x}~0x{:x} direct_off=0x{:x} ...", + t, T::TYPE, npin, partial_off, partial_len, direct_partial_off); + + return [this, &t, npin, direct_partial_off, partial_len, + maybe_init=std::move(maybe_init)]() mutable { + // checking the lba child must be atomic with creating + // and linking the absent child + auto ret = get_extent_if_linked(t, std::move(npin)); + if (ret.index() == 1) { + return std::get<1>(ret + ).si_then([direct_partial_off, partial_len, this, &t](auto extent) { + return cache->read_extent_maybe_partial( + t, std::move(extent), direct_partial_off, partial_len); + }).si_then([maybe_init=std::move(maybe_init)](auto extent) { + if (!extent->is_seen_by_users()) { + maybe_init(*extent); + extent->set_seen_by_users(); + } + return std::move(extent); + }); + } else { + auto &r = std::get<0>(ret); + return this->pin_to_extent( + t, std::move(r.mapping), std::move(r.child_pos), + direct_partial_off, partial_len, + std::move(maybe_init)); + } + }().si_then([FNAME, maybe_indirect_info, is_clone, &t](TCachedExtentRef ext) { + if (maybe_indirect_info.has_value()) { + SUBDEBUGT(seastore_tm, "got indirect +0x{:x}~0x{:x} is_clone={} {}", + t, maybe_indirect_info->intermediate_offset, + maybe_indirect_info->length, is_clone, *ext); + } else { + SUBDEBUGT(seastore_tm, "got direct is_clone={} {}", + t, is_clone, *ext); + } + return maybe_indirect_extent_t{ext, maybe_indirect_info, is_clone}; + }); }); } -- 2.39.5