From: Xuehan Xu Date: Mon, 27 Apr 2026 09:10:06 +0000 (+0800) Subject: crimson/os/seastore: destroy Transaction only when no other reference X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3ec6b956d8c27624a6b075d2f86bcb4c6d7425cc;p=ceph.git crimson/os/seastore: destroy Transaction only when no other reference exists Fixes: https://tracker.ceph.com/issues/76268 Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/os/seastore/cache.cc b/src/crimson/os/seastore/cache.cc index c6d4564b3d47..e1682f835cdd 100644 --- a/src/crimson/os/seastore/cache.cc +++ b/src/crimson/os/seastore/cache.cc @@ -1021,6 +1021,7 @@ void Cache::invalidate_extent( LOG_PREFIX(Cache::invalidate_extent); bool do_conflict_log = true; + std::vector invalidated_trans; for (auto &&i: extent.read_transactions) { if (!i.t->conflicted) { if (do_conflict_log) { @@ -1030,8 +1031,15 @@ void Cache::invalidate_extent( assert(!i.t->is_weak()); account_conflict(t.get_src(), i.t->get_src()); mark_transaction_conflicted(*i.t, extent); + invalidated_trans.emplace_back(i.t); } } + for (auto trans : invalidated_trans) { + trans->clear_read_set(); + trans->invalidate_clear_write_set(); + trans->retired_set.clear(); + trans->views.clear(); + } extent.set_invalid(t); } diff --git a/src/crimson/os/seastore/cache.h b/src/crimson/os/seastore/cache.h index b29067015165..eeb45adaca30 100644 --- a/src/crimson/os/seastore/cache.h +++ b/src/crimson/os/seastore/cache.h @@ -121,7 +121,7 @@ public: ++(get_by_src(stats.trans_created_by_src, src)); - auto ret = std::make_unique( + auto ret = boost::intrusive_ptr(new Transaction( get_dummy_ordering_handle(), is_weak, src, @@ -129,7 +129,7 @@ public: return on_transaction_destruct(t); }, ++next_id, - cache_hint + cache_hint) ); SUBDEBUGT(seastore_t, "created name={}, source={}, is_weak={}", *ret, name, src, is_weak); diff --git a/src/crimson/os/seastore/transaction.h b/src/crimson/os/seastore/transaction.h index 7b0a4433c513..b5191ce54111 100644 --- a/src/crimson/os/seastore/transaction.h +++ b/src/crimson/os/seastore/transaction.h @@ -114,9 +114,10 @@ struct rbm_pending_ool_t { * - TRACE: DEBUG details * - seastore_cache logs */ -class Transaction { +class Transaction : public boost::intrusive_ref_counter< + Transaction, boost::thread_unsafe_counter> { public: - using Ref = std::unique_ptr; + using Ref = boost::intrusive_ptr; using on_destruct_func_t = std::function; enum class get_extent_ret { PRESENT, @@ -926,13 +927,13 @@ using TransactionRef = Transaction::Ref; /// Should only be used with dummy staged-fltree node extent manager inline TransactionRef make_test_transaction() { static transaction_id_t next_id = 0; - return std::make_unique( + return boost::intrusive_ptr(new Transaction( get_dummy_ordering_handle(), false, Transaction::src_t::MUTATE, [](Transaction&) {}, ++next_id, - CACHE_HINT_TOUCH + CACHE_HINT_TOUCH) ); } diff --git a/src/crimson/os/seastore/transaction_interruptor.h b/src/crimson/os/seastore/transaction_interruptor.h index 848c8525642c..c79cce9932b7 100644 --- a/src/crimson/os/seastore/transaction_interruptor.h +++ b/src/crimson/os/seastore/transaction_interruptor.h @@ -24,7 +24,7 @@ struct TransactionConflictCondition { }; public: - TransactionConflictCondition(Transaction &t) : t(t) {} + TransactionConflictCondition(Transaction &t) : t(t), tref(&t) {} template std::optional may_interrupt() { @@ -49,6 +49,7 @@ private: bool is_conflicted() const; Transaction &t; + TransactionRef tref; }; using trans_intr = crimson::interruptible::interruptor<