From 585c1d39dda3c9c054825e17daff473d80112cf4 Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Wed, 17 May 2023 03:35:20 +0000 Subject: [PATCH] crimson/os/seastore/lba_manager: decrease refcount of the physical lba mappings when removing indirect lba mappings Signed-off-by: Xuehan Xu (cherry picked from commit 31204c2e1cb05ac1476abbcc5d5198f38e326095) --- src/crimson/os/seastore/cached_extent.h | 2 +- .../lba_manager/btree/btree_lba_manager.cc | 81 +++++++++++++++++-- .../lba_manager/btree/btree_lba_manager.h | 5 ++ 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/crimson/os/seastore/cached_extent.h b/src/crimson/os/seastore/cached_extent.h index 99d140ff53f..0940cc1a05b 100644 --- a/src/crimson/os/seastore/cached_extent.h +++ b/src/crimson/os/seastore/cached_extent.h @@ -1195,7 +1195,7 @@ public: laddr = nladdr; } - void maybe_set_intermediate_laddr(LBAMapping* mapping) { + void maybe_set_intermediate_laddr(LBAMapping &mapping) { laddr = mapping.is_indirect() ? mapping.get_intermediate_key() : mapping.get_key(); 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 9a4809d6a99..4a4b5e40690 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 @@ -616,6 +616,56 @@ void BtreeLBAManager::register_metrics() ); } +BtreeLBAManager::ref_iertr::future>> +BtreeLBAManager::_decref_intermediate( + Transaction &t, + laddr_t addr, + extent_len_t len) +{ + auto c = get_context(t); + return with_btree( + cache, + c, + [c, addr, len](auto &btree) mutable { + return btree.upper_bound_right( + c, addr + ).si_then([&btree, addr, len, c](auto iter) { + return seastar::do_with( + std::move(iter), + [&btree, addr, len, c](auto &iter) { + ceph_assert(!iter.is_end()); + ceph_assert(iter.get_key() <= addr); + auto val = iter.get_val(); + ceph_assert(iter.get_key() + val.len >= addr + len); + ceph_assert(val.pladdr.is_paddr()); + ceph_assert(val.refcount >= 1); + val.refcount -= 1; + + LOG_PREFIX(BtreeLBAManager::_decref_intermediate); + TRACET("decreased refcount of intermediate key {} -- {}", + c.trans, + iter.get_key(), + val); + + if (!val.refcount) { + return btree.remove(c, iter + ).si_then([val] { + return std::make_optional< + std::pair>( + val.pladdr.get_paddr(), val.len); + }); + } else { + return btree.update(c, iter, val, nullptr + ).si_then([](auto) { + return seastar::make_ready_future< + std::optional>>(std::nullopt); + }); + } + }); + }); + }); +} + BtreeLBAManager::update_refcount_ret BtreeLBAManager::update_refcount( Transaction &t, @@ -634,13 +684,32 @@ BtreeLBAManager::update_refcount( return out; }, nullptr - ).si_then([&t, addr, delta, FNAME](auto result) { + ).si_then([&t, addr, delta, FNAME, this](auto result) { DEBUGT("laddr={}, delta={} done -- {}", t, addr, delta, result); - return ref_update_result_t{ - result.refcount, - result.pladdr, - result.len - }; + auto fut = ref_iertr::make_ready_future< + std::optional>>(); + if (!result.refcount && result.pladdr.is_laddr()) { + fut = _decref_intermediate( + t, + result.pladdr.get_laddr(), + result.len + ); + } + return fut.si_then([result](auto removed) { + if (result.pladdr.is_laddr() + && removed) { + return ref_update_result_t{ + result.refcount, + removed->first, + removed->second}; + } else { + return ref_update_result_t{ + result.refcount, + result.pladdr, + result.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 b37709ee6b1..403bcd05d39 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 @@ -375,6 +375,11 @@ private: op_context_t c, std::list &pin_list); + ref_iertr::future>> + _decref_intermediate( + Transaction &t, + laddr_t addr, + extent_len_t len); }; using BtreeLBAManagerRef = std::unique_ptr; -- 2.39.5