++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;
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 {}, "
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;
}
*/
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;
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(
journal_seq_t journal_dirty_tail;
- /// head of journal
+ /// the committed journal head
journal_seq_t journal_head;
ExtentCallbackInterface *ecb = nullptr;
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();
}
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(
*/
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();
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(
});
}).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"),
).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,