TRACET("{} ool extent written at {} -- {}",
t, segment_allocator.get_name(),
extent_addr, *extent);
- t.mark_delayed_extent_ool(extent, extent_addr);
+ t.update_delayed_ool_extent_addr(extent, extent_addr);
extent_addr = extent_addr.as_seg_paddr().add_offset(
extent->get_length());
}
});
}
-ExtentPlacementManager::alloc_paddr_iertr::future<>
-ExtentPlacementManager::delayed_allocate_and_write(
- Transaction &t,
- const std::list<LogicalCachedExtentRef> &delayed_extents)
+ExtentPlacementManager::dispatch_result_t
+ExtentPlacementManager::dispatch_delayed_extents(Transaction &t)
{
- LOG_PREFIX(ExtentPlacementManager::delayed_allocate_and_write);
- DEBUGT("start with {} delayed extents",
- t, delayed_extents.size());
- assert(writer_refs.size());
- return seastar::do_with(
- std::map<ExtentOolWriter*, std::list<LogicalCachedExtentRef>>(),
- [this, &t, &delayed_extents](auto& alloc_map) {
- for (auto& extent : delayed_extents) {
- // For now, just do ool allocation for any delayed extent
+ dispatch_result_t res;
+ res.delayed_extents = t.get_delayed_alloc_list();
+
+ // init projected usage
+ for (auto &extent : t.get_inline_block_list()) {
+ if (extent->is_valid()) {
+ res.usage.inline_usage += extent->get_length();
+ }
+ }
+
+ for (auto &extent : res.delayed_extents) {
+ if (dispatch_delayed_extent(extent)) {
+ res.usage.inline_usage += extent->get_length();
+ t.mark_delayed_extent_inline(extent);
+ } else {
+ res.usage.ool_usage += extent->get_length();
+ t.mark_delayed_extent_ool(extent);
auto writer_ptr = get_writer(
extent->get_user_hint(),
get_extent_category(extent->get_type()),
extent->get_rewrite_generation());
- alloc_map[writer_ptr].emplace_back(extent);
+ res.alloc_map[writer_ptr].emplace_back(extent);
}
- return trans_intr::do_for_each(alloc_map, [&t](auto& p) {
- auto writer = p.first;
- auto& extents = p.second;
- return writer->alloc_write_ool_extents(t, extents);
- });
+ }
+ return res;
+}
+
+ExtentPlacementManager::alloc_paddr_iertr::future<>
+ExtentPlacementManager::write_delayed_ool_extents(
+ Transaction& t,
+ extents_by_writer_t& alloc_map) {
+ return trans_intr::do_for_each(alloc_map, [&t](auto& p) {
+ auto writer = p.first;
+ auto& extents = p.second;
+ return writer->alloc_write_ool_extents(t, extents);
});
}
});
}
+std::ostream &operator<<(std::ostream &out, const ExtentPlacementManager::projected_usage_t &usage)
+{
+ return out << "projected_usage_t("
+ << "inline_usage=" << usage.inline_usage
+ << ", ool_usage=" << usage.ool_usage << ")";
}
+
+}
+
}
/**
- * delayed_allocate_and_write
+ * dispatch_result_t
*
- * Performs delayed allocation and do writes for out-of-line extents.
+ * ool extents are placed in alloc_map and passed to
+ * EPM::write_delayed_ool_extents,
+ * delayed_extents is used to update lba mapping.
+ * usage is used to reserve projected space
+ */
+ struct projected_usage_t {
+ std::size_t inline_usage = 0;
+ std::size_t ool_usage = 0;
+ };
+ using extents_by_writer_t =
+ std::map<ExtentOolWriter*, std::list<LogicalCachedExtentRef>>;
+ struct dispatch_result_t {
+ extents_by_writer_t alloc_map;
+ std::list<LogicalCachedExtentRef> delayed_extents;
+ projected_usage_t usage;
+ };
+
+ /**
+ * dispatch_delayed_extents
+ *
+ * Performs delayed allocation
+ */
+ dispatch_result_t dispatch_delayed_extents(Transaction& t);
+
+ /**
+ * write_delayed_ool_extents
+ *
+ * Do writes for out-of-line extents.
*/
using alloc_paddr_iertr = ExtentOolWriter::alloc_write_iertr;
- alloc_paddr_iertr::future<> delayed_allocate_and_write(
+ alloc_paddr_iertr::future<> write_delayed_ool_extents(
Transaction& t,
- const std::list<LogicalCachedExtentRef>& delayed_extents);
+ extents_by_writer_t& alloc_map);
/**
* write_preallocated_ool_extents
++num_devices;
}
+ /**
+ * dispatch_delayed_extent
+ *
+ * Specify the extent inline or ool
+ * return true indicates inline otherwise ool
+ */
+ bool dispatch_delayed_extent(LogicalCachedExtentRef& extent) {
+ // TODO: all delayed extents are ool currently
+ boost::ignore_unused(extent);
+ return false;
+ }
+
ExtentOolWriter* get_writer(placement_hint_t hint,
data_category_t category,
rewrite_gen_t gen) {
using ExtentPlacementManagerRef = std::unique_ptr<ExtentPlacementManager>;
+std::ostream &operator<<(std::ostream &, const ExtentPlacementManager::projected_usage_t &);
+
}
+
+#if FMT_VERSION >= 90000
+template <>
+struct fmt::formatter<crimson::os::seastore::ExtentPlacementManager::projected_usage_t>
+ : fmt::ostream_formatter {};
+#endif
write_set.insert(*ref);
}
- void mark_delayed_extent_ool(LogicalCachedExtentRef& ref, paddr_t final_addr) {
+ void mark_delayed_extent_ool(LogicalCachedExtentRef& ref) {
+ written_ool_block_list.push_back(ref);
+ }
+
+ void update_delayed_ool_extent_addr(LogicalCachedExtentRef& ref,
+ paddr_t final_addr) {
write_set.erase(*ref);
assert(ref->get_paddr().is_delayed());
ref->set_paddr(final_addr, /* need_update_mapping: */ true);
assert(!ref->get_paddr().is_null());
assert(!ref->is_inline());
- written_ool_block_list.push_back(ref);
write_set.insert(*ref);
}
return ret;
}
+ const auto &get_inline_block_list() {
+ return inline_block_list;
+ }
+
const auto &get_mutated_block_list() {
return mutated_block_list;
}