From: Yingxin Cheng Date: Wed, 27 Jul 2022 03:50:40 +0000 (+0800) Subject: crimson/os/seastore: distinguish from commit-time and submit-time sequences X-Git-Tag: v18.0.0~391^2~2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=db7a484eb2a7f0c36c58102c14e9322dd8d6a5dc;p=ceph.git crimson/os/seastore: distinguish from commit-time and submit-time sequences Also, the committed journal head should be updated atomically with the rest of the complete-commit logics. Signed-off-by: Yingxin Cheng --- diff --git a/src/crimson/os/seastore/async_cleaner.cc b/src/crimson/os/seastore/async_cleaner.cc index 67690e91f8099..970ddc644afc2 100644 --- a/src/crimson/os/seastore/async_cleaner.cc +++ b/src/crimson/os/seastore/async_cleaner.cc @@ -168,7 +168,7 @@ void segments_info_t::init_closed( ++num_closed; if (type == segment_type_t::JOURNAL) { // init_closed won't initialize journal_segment_id - ceph_assert(get_journal_head() == JOURNAL_SEQ_NULL); + ceph_assert(get_submitted_journal_head() == JOURNAL_SEQ_NULL); ++num_type_journal; } else { ++num_type_ool; @@ -603,11 +603,7 @@ segment_id_t AsyncCleaner::allocate_segment( if (segment_info.is_empty()) { auto old_usage = calc_utilization(seg_id); segments.mark_open(seg_id, seq, type, category, generation); - if (type == segment_type_t::JOURNAL) { - set_journal_head(segments.get_journal_head()); - } else { - gc_process.maybe_wake_on_space_used(); - } + gc_process.maybe_wake_on_space_used(); auto new_usage = calc_utilization(seg_id); adjust_segment_util(old_usage, new_usage); INFO("opened, should_block_on_trim {}, should_block_on_reclaim {}, " diff --git a/src/crimson/os/seastore/async_cleaner.h b/src/crimson/os/seastore/async_cleaner.h index 4f6adbb540923..440c21a1646db 100644 --- a/src/crimson/os/seastore/async_cleaner.h +++ b/src/crimson/os/seastore/async_cleaner.h @@ -179,7 +179,7 @@ public: return (double)get_available_bytes() / (double)total_bytes; } - journal_seq_t get_journal_head() const { + journal_seq_t get_submitted_journal_head() const { if (unlikely(journal_segment_id == NULL_SEG_ID)) { return JOURNAL_SEQ_NULL; } @@ -269,16 +269,21 @@ private: */ class SegmentProvider { public: + // set the committed journal head virtual void set_journal_head(journal_seq_t) = 0; + // get the committed journal tail journal_seq_t get_journal_tail() const { return std::min(get_alloc_tail(), get_dirty_tail()); } + // get the committed journal dirty tail virtual journal_seq_t get_dirty_tail() const = 0; + // get the committed journal alloc tail virtual journal_seq_t get_alloc_tail() const = 0; + // set the committed journal tails virtual void update_journal_tails( journal_seq_t dirty_tail, journal_seq_t alloc_tail) = 0; @@ -289,6 +294,7 @@ public: virtual void close_segment(segment_id_t) = 0; + // set the submitted segment writes in order virtual void update_segment_avail_bytes(segment_type_t, paddr_t) = 0; virtual void update_modify_time( @@ -729,7 +735,7 @@ private: journal_seq_t journal_dirty_tail; - /// head of journal + /// the committed journal head journal_seq_t journal_head; ExtentCallbackInterface *ecb = nullptr; @@ -778,6 +784,13 @@ public: head >= journal_alloc_tail); ceph_assert(journal_dirty_tail == JOURNAL_SEQ_NULL || head >= journal_dirty_tail); + + if (head.offset.get_addr_type() == addr_types_t::SEGMENT) { + auto submitted_journal_head = segments.get_submitted_journal_head(); + ceph_assert(submitted_journal_head != JOURNAL_SEQ_NULL && + head <= submitted_journal_head); + } + journal_head = head; gc_process.maybe_wake_on_space_used(); } @@ -789,11 +802,7 @@ public: void update_segment_avail_bytes(segment_type_t type, paddr_t offset) final { segments.update_written_to(type, offset); - if (type == segment_type_t::JOURNAL) { - set_journal_head(segments.get_journal_head()); - } else { - gc_process.maybe_wake_on_space_used(); - } + gc_process.maybe_wake_on_space_used(); } void update_modify_time( @@ -1228,12 +1237,16 @@ private: */ bool should_block_on_trim() const { if (disable_trim) return false; + if (!init_complete) { + return false; + } return get_tail_limit() > get_journal_tail(); } bool should_block_on_reclaim() const { if (disable_trim) return false; - if (get_segments_reclaimable() == 0) { + if (!init_complete || + get_segments_reclaimable() == 0) { return false; } auto aratio = get_projected_available_ratio(); diff --git a/src/crimson/os/seastore/journal/segment_allocator.cc b/src/crimson/os/seastore/journal/segment_allocator.cc index 81c937bfda984..b96032f9e8935 100644 --- a/src/crimson/os/seastore/journal/segment_allocator.cc +++ b/src/crimson/os/seastore/journal/segment_allocator.cc @@ -68,8 +68,6 @@ SegmentAllocator::do_open(bool is_mkfs) }; dirty_tail = mkfs_seq; alloc_tail = mkfs_seq; - segment_provider.update_journal_tails( - dirty_tail, alloc_tail); } else { ceph_assert(dirty_tail != JOURNAL_SEQ_NULL); ceph_assert(alloc_tail != JOURNAL_SEQ_NULL); diff --git a/src/crimson/os/seastore/transaction_manager.cc b/src/crimson/os/seastore/transaction_manager.cc index b91acea653832..2f62431ddaa9f 100644 --- a/src/crimson/os/seastore/transaction_manager.cc +++ b/src/crimson/os/seastore/transaction_manager.cc @@ -48,7 +48,9 @@ TransactionManager::mkfs_ertr::future<> TransactionManager::mkfs() return async_cleaner->mount( ).safe_then([this] { return journal->open_for_mkfs(); - }).safe_then([this](auto) { + }).safe_then([this](auto start_seq) { + async_cleaner->update_journal_tails(start_seq, start_seq); + async_cleaner->set_journal_head(start_seq); return epm->open(); }).safe_then([this, FNAME]() { return with_transaction_intr( @@ -106,7 +108,8 @@ TransactionManager::mount_ertr::future<> TransactionManager::mount() }); }).safe_then([this] { return journal->open_for_mount(); - }).safe_then([this, FNAME](auto) { + }).safe_then([this, FNAME](auto start_seq) { + async_cleaner->set_journal_head(start_seq); return seastar::do_with( create_weak_transaction( Transaction::src_t::READ, "mount"), @@ -372,6 +375,7 @@ TransactionManager::submit_transaction_direct( ).safe_then([this, FNAME, &tref](auto submit_result) mutable { SUBDEBUGT(seastore_t, "committed with {}", tref, submit_result); auto start_seq = submit_result.write_result.start_seq; + async_cleaner->set_journal_head(start_seq); cache->complete_commit( tref, submit_result.record_block_base,