From 77a6edfd77a77c844e857ed5eab6565cc3c69701 Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Mon, 21 Apr 2025 12:26:52 +0800 Subject: [PATCH] crimson/os/seastore/lba_manager: allow cloning part of the mapping Signed-off-by: Xuehan Xu --- .../os/seastore/lba/btree_lba_manager.cc | 27 ++++++++++--------- .../os/seastore/lba/btree_lba_manager.h | 2 ++ src/crimson/os/seastore/lba_manager.h | 16 ++++++----- src/crimson/os/seastore/transaction_manager.h | 13 ++++++--- .../seastore/test_transaction_manager.cc | 3 +++ 5 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/crimson/os/seastore/lba/btree_lba_manager.cc b/src/crimson/os/seastore/lba/btree_lba_manager.cc index d58e61318f783..13f35ef765871 100644 --- a/src/crimson/os/seastore/lba/btree_lba_manager.cc +++ b/src/crimson/os/seastore/lba/btree_lba_manager.cc @@ -427,17 +427,21 @@ BtreeLBAManager::clone_mapping( LBAMapping pos, LBAMapping mapping, laddr_t laddr, + extent_len_t offset, + extent_len_t len, bool updateref) { LOG_PREFIX(BtreeLBAManager::clone_mapping); assert(pos.is_viewable()); assert(mapping.is_viewable()); - DEBUGT("pos={}, mapping={}, laddr={}, updateref={}", - t, pos, mapping, laddr, updateref); + DEBUGT("pos={}, mapping={}, laddr={}, {}~{} updateref={}", + t, pos, mapping, laddr, offset, len, updateref); + assert(offset + len <= mapping.get_length()); struct state_t { LBAMapping pos; LBAMapping mapping; laddr_t laddr; + extent_len_t offset; extent_len_t len; }; auto c = get_context(t); @@ -464,11 +468,10 @@ BtreeLBAManager::clone_mapping( return update_refcount_iertr::make_ready_future< LBAMapping>(std::move(mapping)); } - }).si_then([c, this, pos=std::move(pos), - laddr](auto mapping) mutable { - auto len = mapping.get_length(); + }).si_then([c, this, pos=std::move(pos), len, + offset, laddr](auto mapping) mutable { return seastar::do_with( - state_t{std::move(pos), std::move(mapping), laddr, len}, + state_t{std::move(pos), std::move(mapping), laddr, offset, len}, [this, c](auto &state) { return with_btree( cache, @@ -479,17 +482,15 @@ BtreeLBAManager::clone_mapping( ).si_then([&state, c, &btree]() mutable { auto &cursor = state.pos.get_effective_cursor(); assert(state.laddr + state.len <= cursor.key); + auto inter_key = state.mapping.is_indirect() + ? state.mapping.get_intermediate_key() + : state.mapping.get_key(); + inter_key = (inter_key + state.offset).checked_to_laddr(); return btree.insert( c, btree.make_partial_iter(c, cursor), state.laddr, - lba_map_val_t{ - state.len, - state.mapping.is_indirect() - ? state.mapping.get_intermediate_key() - : state.mapping.get_key(), - EXTENT_DEFAULT_REF_COUNT, - 0}); + lba_map_val_t{state.len, inter_key, EXTENT_DEFAULT_REF_COUNT, 0}); }).si_then([c, &state](auto p) { auto &[iter, inserted] = p; auto &leaf_node = *iter.get_leaf_node(); diff --git a/src/crimson/os/seastore/lba/btree_lba_manager.h b/src/crimson/os/seastore/lba/btree_lba_manager.h index e91dc10270686..33b6ea87ce069 100644 --- a/src/crimson/os/seastore/lba/btree_lba_manager.h +++ b/src/crimson/os/seastore/lba/btree_lba_manager.h @@ -105,6 +105,8 @@ public: LBAMapping pos, LBAMapping mapping, laddr_t laddr, + extent_len_t offset, + extent_len_t len, bool updateref) final; #ifdef UNIT_TESTS_BUILT diff --git a/src/crimson/os/seastore/lba_manager.h b/src/crimson/os/seastore/lba_manager.h index c551e5ea21f3c..1b1d37bfdc1bd 100644 --- a/src/crimson/os/seastore/lba_manager.h +++ b/src/crimson/os/seastore/lba_manager.h @@ -117,15 +117,19 @@ public: using clone_mapping_iertr = alloc_extent_iertr; using clone_mapping_ret = clone_mapping_iertr::future; /* - * Clones "mapping" at the position "pos" with new laddr "laddr", if updateref - * is true, update the refcount of the mapping "mapping" + * Clones (part of) "mapping" at the position "pos" with the new lba key "laddr". */ virtual clone_mapping_ret clone_mapping( Transaction &t, - LBAMapping pos, - LBAMapping mapping, - laddr_t laddr, - bool updateref) = 0; + LBAMapping pos, // the destined position + LBAMapping mapping, // the mapping to be cloned + laddr_t laddr, // the new lba key of the cloned mapping + extent_len_t offset, // the offset of the part to be cloned, + // relative to the start of the mapping. + extent_len_t len, // the length of the part to be cloned + bool updateref // whether to update the refcount of the + // direct mapping + ) = 0; virtual alloc_extent_ret reserve_region( Transaction &t, diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index 40868c09adcdc..1080d3491822d 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -584,6 +584,8 @@ public: LBAMapping pos, LBAMapping mapping, laddr_t hint, + extent_len_t offset, + extent_len_t len, bool updateref) { LOG_PREFIX(TransactionManager::clone_pin); SUBDEBUGT(seastore_tm, "{} clone to hint {} ... pos={}, updateref={}", @@ -591,17 +593,20 @@ public: return seastar::do_with( std::move(pos), std::move(mapping), - [FNAME, this, &t, hint, updateref](auto &pos, auto &mapping) { + [offset, len, FNAME, this, &t, hint, updateref](auto &pos, auto &mapping) { return pos.refresh( ).si_then([&pos, &mapping](auto m) { pos = std::move(m); return mapping.refresh(); - }).si_then([FNAME, this, &pos, &t, hint, updateref](auto mapping) { + }).si_then([offset, len, FNAME, this, &pos, + &t, hint, updateref](auto mapping) { return lba_manager->clone_mapping( t, std::move(pos), std::move(mapping), hint, + offset, + len, updateref ).si_then([FNAME, &t](auto ret) { SUBDEBUGT(seastore_tm, "cloned as {}", t, ret.cloned_mapping); @@ -664,9 +669,11 @@ public: if (mapping.is_real()) { ret = true; } + auto len = mapping.get_length(); return clone_pin( t, std::move(pos), std::move(mapping), - (base + offset).checked_to_laddr(), updateref + (base + offset).checked_to_laddr(), + 0, len, updateref ).si_then([&offset, &pos, &mapping](auto ret) { offset += ret.cloned_mapping.get_length(); return ret.cloned_mapping.next( diff --git a/src/test/crimson/seastore/test_transaction_manager.cc b/src/test/crimson/seastore/test_transaction_manager.cc index 59ec6ec60c0a8..ec1e19c31481e 100644 --- a/src/test/crimson/seastore/test_transaction_manager.cc +++ b/src/test/crimson/seastore/test_transaction_manager.cc @@ -708,11 +708,14 @@ struct transaction_manager_test_t : laddr_t offset) { auto key = mapping.get_key(); auto pin = with_trans_intr(*(t.t), [&](auto &trans) { + auto len = mapping.get_length(); return tm->clone_pin( trans, std::move(pos), std::move(mapping), offset, + 0, + len, true); }).unsafe_get().cloned_mapping; EXPECT_EQ(offset, pin.get_key()); -- 2.39.5