}
}
+ for (auto &i: t.written_inplace_ool_block_list) {
+ if (!i->is_valid()) {
+ continue;
+ }
+ assert(i->state == CachedExtent::extent_state_t::DIRTY);
+ assert(i->version > 0);
+ remove_from_dirty(i);
+ // set the version to zero because the extent state is now clean
+ // in order to handle this transparently
+ i->version = 0;
+ i->dirty_from_or_retired_at = JOURNAL_SEQ_MIN;
+ i->state = CachedExtent::extent_state_t::CLEAN;
+ assert(i->is_logical());
+ i->cast<LogicalCachedExtent>()->clear_delta();
+ touch_extent(*i);
+ DEBUGT("inplace rewrite ool block is commmitted -- {}", t, *i);
+ }
+
for (auto &i: t.existing_block_list) {
if (i->is_valid()) {
alloc_delta.alloc_blk_ranges.emplace_back(
t.num_allocated_invalid_extents);
auto& ool_stats = t.get_ool_write_stats();
- ceph_assert(ool_stats.extents.num == t.written_ool_block_list.size());
+ ceph_assert(ool_stats.extents.num == t.written_ool_block_list.size() +
+ t.written_inplace_ool_block_list.size());
if (record.is_empty()) {
SUBINFOT(seastore_t,
void on_replace_prior(Transaction &t) final;
+ virtual void clear_delta() {}
+
virtual ~LogicalCachedExtent();
protected:
).safe_then([&t, &ex, paddr, FNAME]() {
TRACET("ool extent written at {} -- {}",
t, paddr, *ex);
- t.mark_allocated_extent_ool(ex);
+ if (ex->is_initial_pending()) {
+ t.mark_allocated_extent_ool(ex);
+ } else if (ex->is_dirty()) {
+ assert(t.get_src() == transaction_type_t::TRIM_DIRTY);
+ t.mark_inplace_rewrite_extent_ool(ex);
+ } else {
+ ceph_assert("impossible");
+ }
return alloc_write_iertr::now();
});
});
ceph::bufferlist get_delta() final;
void apply_delta(const ceph::bufferlist &bl) final;
+
+ void clear_delta() final {
+ delta.clear();
+ }
};
using ObjectDataBlockRef = TCachedExtentRef<ObjectDataBlock>;
written_ool_block_list.push_back(ref);
}
+ void mark_inplace_rewrite_extent_ool(LogicalCachedExtentRef& ref) {
+ assert(ref->get_paddr().is_absolute());
+ assert(!ref->is_inline());
+ written_inplace_ool_block_list.push_back(ref);
+ }
+
void add_inplace_rewrite_extent(CachedExtentRef ref) {
ceph_assert(!is_weak());
ceph_assert(ref);
delayed_alloc_list.clear();
inline_block_list.clear();
written_ool_block_list.clear();
+ written_inplace_ool_block_list.clear();
pre_alloc_list.clear();
pre_inplace_rewrite_list.clear();
retired_set.clear();
std::list<CachedExtentRef> inline_block_list;
/// fresh blocks that will be committed with out-of-line record
std::list<CachedExtentRef> written_ool_block_list;
+ /// dirty blocks that will be committed out-of-line with inplace rewrite
+ std::list<LogicalCachedExtentRef> written_inplace_ool_block_list;
/// list of mutated blocks, holds refcounts, subset of write_set
std::list<CachedExtentRef> mutated_block_list;
}
void apply_delta(const ceph::bufferlist &bl) final;
+
+ void clear_delta() final {
+ delta.clear();
+ }
};
using TestBlockRef = TCachedExtentRef<TestBlock>;