diff --git a/src/crimson/os/seastore/async_cleaner.cc b/src/crimson/os/seastore/async_cleaner.cc index 9d515e13cd9..7ccf710d9e2 100644 --- a/src/crimson/os/seastore/async_cleaner.cc +++ b/src/crimson/os/seastore/async_cleaner.cc @@ -717,8 +717,11 @@ JournalTrimmerImpl::trim_dirty() return trans_intr::do_for_each( dirty_list, [this, &t](auto &e) { - return extent_callback->rewrite_extent( + return extent_callback->maybe_remove_shadow(t, *e + ).si_then([this, &t, e] { + return extent_callback->rewrite_extent( t, e, INIT_GENERATION, NULL_TIME); + }); }); }); }).si_then([this, &t] { diff --git a/src/crimson/os/seastore/async_cleaner.h b/src/crimson/os/seastore/async_cleaner.h index 647e0b233b3..9751dc15eea 100644 --- a/src/crimson/os/seastore/async_cleaner.h +++ b/src/crimson/os/seastore/async_cleaner.h @@ -398,6 +398,18 @@ public: laddr_t prefix, std::size_t max_proceed_size) = 0; + /** + * maybe_remove_shadow + * + * Remove the shadow of the extent if it exists + */ + using maybe_remove_shadow_iertr = base_iertr; + using maybe_remove_shadow_ret = + maybe_remove_shadow_iertr::future<>; + virtual maybe_remove_shadow_ret maybe_remove_shadow( + Transaction &t, + CachedExtent &e) = 0; + /** * get_extents_if_live * diff --git a/src/crimson/os/seastore/lba/btree_lba_manager.cc b/src/crimson/os/seastore/lba/btree_lba_manager.cc index dbdcfb2109c..10a38fa9d32 100644 --- a/src/crimson/os/seastore/lba/btree_lba_manager.cc +++ b/src/crimson/os/seastore/lba/btree_lba_manager.cc @@ -1139,6 +1139,11 @@ BtreeLBAManager::update_mappings( ceph_assert(in.len == len); if (likely(in.pladdr.get_paddr() == prev_addr)) { ret.pladdr = addr; + if (c.trans.get_src() == transaction_type_t::TRIM_DIRTY) { + // This is a dirty onode/omap extent that are rewritten, + // the shadow extent should be removed. + ret.shadow_paddr = P_ADDR_NULL; + } } else { // this can only happen when the extent is EXIST_CLEAN // and is demoted onto the cold tier by a DEMOTE trans. diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index 87799086e92..2ca10ed8101 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -993,6 +993,42 @@ public: laddr_t start, std::size_t max_proceed_size) final; + maybe_remove_shadow_ret maybe_remove_shadow( + Transaction &t, + CachedExtent &e) { + if (!e.is_logical()) { + co_return; + } + auto &extent = static_cast(e); + auto cursor = co_await lba_manager->get_cursor(t, extent + ).handle_error_interruptible( + crimson::ct_error::input_output_error::pass_further{}, + crimson::ct_error::enoent::assert_failure{} + ); + if (cursor->has_shadow_paddr()) { + if (auto shadow = extent.get_shadow(); shadow) { + cache->retire_extent(t, shadow); + } else { + auto laddr = cursor->get_laddr(); + std::ignore = cache->retire_absent_extent_addr_by_type( + t, laddr, + cursor->get_shadow_paddr(), + cursor->get_length(), + cursor->get_extent_type(), + [&extent, laddr](auto &ext) { + auto lextent = ext.template cast(); + assert(ext.is_logical()); + assert(!lextent->has_laddr()); + assert(!ext.has_been_invalidated()); + lextent->set_laddr(laddr); + ext.set_shadow_extent(true); + extent.set_shadow(lextent); + } + ); + } + } + } + using ExtentCallbackInterface::get_extents_if_live_ret; get_extents_if_live_ret get_extents_if_live( Transaction &t,