In RBM, Data extents like OBJECT_DATA_BLOCK can be overwritten.
So, this commit overwrites the (delta) extents in Journal to the corresponding blocks in RBM
if they are Data extents.
Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
rewrite_generation = gen;
}
+ void set_inplace_rewrite_generation() {
+ user_hint = placement_hint_t::REWRITE;
+ rewrite_generation = OOL_GENERATION;
+ }
+
bool is_inline() const {
return poffset.is_relative();
}
using close_ertr = base_ertr;
virtual close_ertr::future<> close() = 0;
+
+ virtual bool can_inplace_rewrite(Transaction& t,
+ CachedExtentRef extent) = 0;
};
using ExtentOolWriterRef = std::unique_ptr<ExtentOolWriter>;
return make_delayed_temp_paddr(0);
}
+ bool can_inplace_rewrite(Transaction& t,
+ CachedExtentRef extent) final {
+ return false;
+ }
+
private:
alloc_write_iertr::future<> do_write(
Transaction& t,
return rb_cleaner->alloc_paddr(length);
}
+ bool can_inplace_rewrite(Transaction& t,
+ CachedExtentRef extent) final {
+ if (!extent->is_dirty()) {
+ return false;
+ }
+ assert(t.get_src() == transaction_type_t::TRIM_DIRTY);
+ ceph_assert_always(extent->get_type() == extent_types_t::ROOT ||
+ extent->get_paddr().is_absolute());
+ return crimson::os::seastore::can_inplace_rewrite(extent->get_type());
+ }
+
private:
alloc_write_iertr::future<> do_write(
Transaction& t,
background_process.set_extent_callback(cb);
}
+ bool can_inplace_rewrite(Transaction& t, CachedExtentRef extent) {
+ auto writer = get_writer(placement_hint_t::REWRITE,
+ get_extent_category(extent->get_type()),
+ OOL_GENERATION);
+ ceph_assert(writer);
+ return writer->can_inplace_rewrite(t, extent);
+ }
+
journal_type_t get_journal_type() const {
return background_process.get_journal_type();
}
}
}
+bool can_inplace_rewrite(extent_types_t type) {
+ return get_extent_category(type) == data_category_t::DATA;
+}
+
std::ostream &operator<<(std::ostream &out, sea_time_point_printer_t tp)
{
if (tp.tp == NULL_TIME) {
}
}
+bool can_inplace_rewrite(extent_types_t type);
+
// type for extent modification time, milliseconds since the epoch
using sea_time_point = seastar::lowres_system_clock::time_point;
using sea_duration = seastar::lowres_system_clock::duration;
written_ool_block_list.push_back(ref);
}
+ void add_inplace_rewrite_extent(CachedExtentRef ref) {
+ ceph_assert(!is_weak());
+ ceph_assert(ref);
+ ceph_assert(ref->get_paddr().is_absolute());
+ assert(ref->state == CachedExtent::extent_state_t::DIRTY);
+ pre_inplace_rewrite_list.emplace_back(ref->cast<LogicalCachedExtent>());
+ }
+
void add_mutated_extent(CachedExtentRef ref) {
ceph_assert(!is_weak());
assert(ref->is_exist_mutation_pending() ||
++num_allocated_invalid_extents;
}
}
+ for (auto& extent : pre_inplace_rewrite_list) {
+ if (extent->is_valid()) {
+ ret.push_back(extent);
+ }
+ }
return ret;
}
inline_block_list.clear();
written_ool_block_list.clear();
pre_alloc_list.clear();
+ pre_inplace_rewrite_list.clear();
retired_set.clear();
existing_block_list.clear();
existing_block_stats = {};
io_stat_t fresh_block_stats;
uint64_t num_delayed_invalid_extents = 0;
uint64_t num_allocated_invalid_extents = 0;
- /// blocks that will be committed with journal record inline
- std::list<CachedExtentRef> inline_block_list;
- /// blocks that will be committed with out-of-line record
- std::list<CachedExtentRef> written_ool_block_list;
- /// blocks with delayed allocation, may become inline or ool above
+ /// fresh blocks with delayed allocation, may become inline or ool below
std::list<LogicalCachedExtentRef> delayed_alloc_list;
-
- /// Extents with pre-allocated addresses,
- /// will be added to written_ool_block_list after write
+ /// fresh blocks with pre-allocated addresses with RBM,
+ /// should be released upon conflicts, will be added to ool below
std::list<LogicalCachedExtentRef> pre_alloc_list;
+ /// dirty blocks for inplace rewrite with RBM, will be added to inplace ool below
+ std::list<LogicalCachedExtentRef> pre_inplace_rewrite_list;
+
+ /// fresh blocks that will be committed with inline journal record
+ std::list<CachedExtentRef> inline_block_list;
+ /// fresh blocks that will be committed with out-of-line record
+ std::list<CachedExtentRef> written_ool_block_list;
/// list of mutated blocks, holds refcounts, subset of write_set
std::list<CachedExtentRef> mutated_block_list;
assert(extent->is_valid() && !extent->is_initial_pending());
if (extent->is_dirty()) {
+ if (epm->can_inplace_rewrite(t, extent)) {
+ DEBUGT("delta overwriting extent -- {}", t, *extent);
+ t.add_inplace_rewrite_extent(extent);
+ extent->set_inplace_rewrite_generation();
+ return rewrite_extent_iertr::now();
+ }
extent->set_target_rewrite_generation(INIT_GENERATION);
} else {
extent->set_target_rewrite_generation(target_generation);