In RBM, seastore issues ool writes with allocated address.
If a transaction conflict occurs at this point, the allocated address is freed,
allowing the address to be reused.
However, data inconsistency can occur if seastore issues ool writes with
freed address before the preceding ool write has not been complete.
To fix this issue, this commit frees the allocated address after ool writes is
don in the event of the transaction conflict after ool write is issued.
Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
}
efforts.mutate_delta_bytes += delta_stat.bytes;
- for (auto &i: t.pre_alloc_list) {
- epm.mark_space_free(i->get_paddr(), i->get_length());
+ if (t.get_pending_ool()) {
+ t.get_pending_ool()->is_conflicted = true;
+ } else {
+ for (auto &i: t.pre_alloc_list) {
+ epm.mark_space_free(i->get_paddr(), i->get_length());
+ }
}
auto& ool_stats = t.get_ool_write_stats();
return alloc_write_iertr::now();
}
return seastar::with_gate(write_guard, [this, &t, &extents] {
- return do_write(t, extents);
+ seastar::lw_shared_ptr<rbm_pending_ool_t> ptr =
+ seastar::make_lw_shared<rbm_pending_ool_t>();
+ ptr->pending_extents = t.get_pre_alloc_list();
+ assert(!t.is_conflicted());
+ t.set_pending_ool(ptr);
+ return do_write(t, extents
+ ).finally([this, ptr=ptr] {
+ if (ptr->is_conflicted) {
+ for (auto &e : ptr->pending_extents) {
+ rb_cleaner->mark_space_free(e->get_paddr(), e->get_length());
+ }
+ }
+ });
});
}
}
};
+struct rbm_pending_ool_t {
+ bool is_conflicted = false;
+ std::list<CachedExtentRef> pending_extents;
+};
+
/**
* Transaction
*
return static_cast<T&>(*view);
}
+ void set_pending_ool(seastar::lw_shared_ptr<rbm_pending_ool_t> ptr) {
+ pending_ool = ptr;
+ }
+
+ seastar::lw_shared_ptr<rbm_pending_ool_t> get_pending_ool() {
+ return pending_ool;
+ }
+
+ const auto& get_pre_alloc_list() {
+ return pre_alloc_list;
+ }
+
private:
friend class Cache;
friend Ref make_test_transaction();
const src_t src;
transaction_id_t trans_id = TRANS_ID_NULL;
+
+ seastar::lw_shared_ptr<rbm_pending_ool_t> pending_ool;
};
using TransactionRef = Transaction::Ref;