record.extents.reserve(t.fresh_block_list.size());
for (auto &i: t.fresh_block_list) {
DEBUGT("fresh block {}", t, *i);
+ if (!i->is_inline()) {
+ continue;
+ }
get_by_ext(efforts.fresh_by_ext,
i->get_type()).increment(i->get_length());
bufferlist bl;
DEBUGT("enter", t);
for (auto &i: t.fresh_block_list) {
- i->set_paddr(final_block_start.add_relative(i->get_paddr()));
+ if (i->is_inline()) {
+ i->set_paddr(final_block_start.add_relative(i->get_paddr()));
+ }
i->last_committed_crc = i->get_crc32c();
i->on_initial_write();
/// hint for allocators
ool_placement_hint_t hint;
- bool is_relative() const {
+ bool is_inline() const {
return poffset.is_relative();
}
private:
auto cache = std::make_unique<Cache>(*sm);
auto lba_manager = lba_manager::create_lba_manager(*sm, *cache);
+ auto epm = std::make_unique<ExtentPlacementManager>(*cache, *lba_manager);
+
+ epm->add_allocator(
+ device_type_t::SEGMENTED,
+ std::make_unique<SegmentedAllocator>(
+ *segment_cleaner,
+ *sm,
+ *lba_manager,
+ *journal,
+ *cache));
+
journal->set_segment_provider(&*segment_cleaner);
auto tm = std::make_unique<TransactionManager>(
std::move(segment_cleaner),
std::move(journal),
std::move(cache),
- std::move(lba_manager));
+ std::move(lba_manager),
+ std::move(epm));
auto cm = std::make_unique<collection_manager::FlatCollectionManager>(*tm);
return std::make_unique<SeaStore>(
SegmentCleanerRef _segment_cleaner,
JournalRef _journal,
CacheRef _cache,
- LBAManagerRef _lba_manager)
+ LBAManagerRef _lba_manager,
+ ExtentPlacementManagerRef&& epm)
: segment_manager(_segment_manager),
segment_cleaner(std::move(_segment_cleaner)),
cache(std::move(_cache)),
lba_manager(std::move(_lba_manager)),
- journal(std::move(_journal))
+ journal(std::move(_journal)),
+ epm(std::move(epm))
{
segment_cleaner->set_extent_callback(this);
journal->set_write_pipeline(&write_pipeline);
{
LOG_PREFIX(TransactionManager::submit_transaction_direct);
DEBUGT("about to prepare", tref);
- return trans_intr::make_interruptible(
- tref.get_handle().enter(write_pipeline.prepare)
- ).then_interruptible([this, FNAME, &tref]() mutable
- -> submit_transaction_iertr::future<> {
+
+ return epm->delayed_alloc_or_ool_write(tref)
+ .handle_error_interruptible(
+ crimson::ct_error::input_output_error::pass_further(),
+ crimson::ct_error::assert_all("invalid error")
+ ).si_then([&tref, this] {
+ return tref.get_handle().enter(write_pipeline.prepare);
+ }).si_then([this, FNAME, &tref]() mutable
+ -> submit_transaction_iertr::future<> {
auto record = cache->prepare_record(tref);
tref.get_handle().maybe_release_collection_lock();
auto lextent = extent->cast<LogicalCachedExtent>();
cache->retire_extent(t, extent);
- auto nlextent = cache->alloc_new_extent_by_type(
+ auto nlextent = epm->alloc_new_extent_by_type(
t,
lextent->get_type(),
lextent->get_length())->cast<LogicalCachedExtent>();
*lextent,
*nlextent);
+ if (need_delayed_allocation(extent->backend_type)) {
+ // hold old poffset for later mapping updating assert check
+ nlextent->set_paddr(lextent->get_paddr());
+ return rewrite_extent_iertr::now();
+ }
return lba_manager->update_mapping(
t,
lextent->get_laddr(),
#include "crimson/os/seastore/segment_manager.h"
#include "crimson/os/seastore/lba_manager.h"
#include "crimson/os/seastore/journal.h"
+#include "crimson/os/seastore/extent_placement_manager.h"
namespace crimson::os::seastore {
class Journal;
SegmentCleanerRef segment_cleaner,
JournalRef journal,
CacheRef cache,
- LBAManagerRef lba_manager);
+ LBAManagerRef lba_manager,
+ ExtentPlacementManagerRef&& epm);
/// Writes initial metadata to disk
using mkfs_ertr = base_ertr;
CacheRef cache;
LBAManagerRef lba_manager;
JournalRef journal;
+ ExtentPlacementManagerRef epm;
WritePipeline write_pipeline;
auto cache = std::make_unique<Cache>(segment_manager);
auto lba_manager = lba_manager::create_lba_manager(segment_manager, *cache);
+ auto epm = std::make_unique<ExtentPlacementManager>(*cache, *lba_manager);
+
+ epm->add_allocator(
+ device_type_t::SEGMENTED,
+ std::make_unique<SegmentedAllocator>(
+ *segment_cleaner,
+ segment_manager,
+ *lba_manager,
+ *journal,
+ *cache));
+
journal->set_segment_provider(&*segment_cleaner);
return std::make_unique<TransactionManager>(
std::move(segment_cleaner),
std::move(journal),
std::move(cache),
- std::move(lba_manager));
+ std::move(lba_manager),
+ std::move(epm));
}
auto get_seastore(SegmentManagerRef sm) {