We're going to need to preserve the pipeline phase locking on conflict.
Signed-off-by: Samuel Just <sjust@redhat.com>
return ret;
}
+ /// Resets transaction preserving
+ void reset_transaction_preserve_handle(Transaction &t) {
+ t.reset_preserve_handle(last_commit);
+ }
+
/**
* drop_from_cache
*
list_hook_options>;
public:
token_t(journal_seq_t created_after) : created_after(created_after) {}
- ~token_t();
+
+ void drop_self();
+ void add_self();
+
+ void reset(journal_seq_t _created_after) {
+ drop_self();
+ created_after = _created_after;
+ add_self();
+ }
+
+ ~token_t() {
+ if (parent) {
+ drop_self();
+ parent = nullptr;
+ }
+ }
};
void prune() {
void add_token(token_t &t) {
t.parent = this;
- live_tokens.push_back(t);
+ t.add_self();
}
void add_extent(CachedExtent &extent) {
CachedExtent::list retired_extents;
};
-inline retired_extent_gate_t::token_t::~token_t() {
- if (parent) {
- parent->live_tokens.erase(
- parent->live_tokens.s_iterator_to(*this));
- parent->prune();
- parent = nullptr;
- }
+inline void retired_extent_gate_t::token_t::add_self() {
+ assert(parent);
+ parent->live_tokens.push_back(*this);
+}
+
+inline void retired_extent_gate_t::token_t::drop_self() {
+ assert(parent);
+ parent->live_tokens.erase(
+ parent->live_tokens.s_iterator_to(*this));
+ parent->prune();
}
/**
ceph::os::Transaction::iterator iter;
- void reset(TransactionRef &&t) {
- transaction = std::move(t);
+ template <typename TM>
+ void reset_preserve_handle(TM &tm) {
+ tm->reset_transaction_preserve_handle(*transaction);
onodes.clear();
iter = ext_transaction.begin();
}
ceph::os::Transaction &&t,
F &&f) {
return seastar::do_with(
- internal_context_t{ ch, std::move(t) },
+ internal_context_t(
+ ch, std::move(t),
+ transaction_manager->create_transaction()),
std::forward<F>(f),
[this](auto &ctx, auto &f) {
return repeat_eagain([&]() {
- ctx.reset(transaction_manager->create_transaction());
+ ctx.reset_preserve_handle(transaction_manager);
return std::invoke(f, ctx);
}).handle_error(
crimson::ct_error::eagain::pass_further{},
friend class crimson::os::seastore::SeaStore;
friend class TransactionConflictCondition;
+ void reset_preserve_handle(journal_seq_t initiated_after) {
+ root.reset();
+ offset = 0;
+ read_set.clear();
+ write_set.clear();
+ fresh_block_list.clear();
+ mutated_block_list.clear();
+ retired_set.clear();
+ to_release = NULL_SEG_ID;
+ retired_uncached.clear();
+ retired_gate_token.reset(initiated_after);
+ conflicted = false;
+ }
+
private:
friend class Cache;
friend Ref make_test_transaction();
return cache->create_weak_transaction();
}
+ /// Resets transaction
+ void reset_transaction_preserve_handle(Transaction &t) {
+ return cache->reset_transaction_preserve_handle(t);
+ }
+
/**
* get_pin
*
FORWARD(close)
FORWARD(create_transaction)
FORWARD(create_weak_transaction)
+ FORWARD(reset_transaction_preserve_handle)
INT_FORWARD(get_pin)
INT_FORWARD(get_pins)
PARAM_INT_FORWARD(pin_to_extent)