The number of journal segments should not be based on the committed
journal_head. Otherwise, if a new journal segment is just opened and the
committed journal_head hasn't been updated, the result will be wrong.
This causes ceph_assert(get_segments_reclaimable() == 0) in
SegmentCleaner::get_next_reclaim_segment().
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
(cherry picked from commit
5ae59cf52159bdc1ad3637da8654524cb7b4b4b6)
background_callback->maybe_wake_background();
}
+void JournalTrimmerImpl::set_journal_head_sequence(
+ segment_seq_t seq)
+{
+ if (journal_head != JOURNAL_SEQ_NULL) {
+ ceph_assert(seq == journal_head.segment_seq + 1);
+ }
+ if (journal_head_seq != NULL_SEG_SEQ) {
+ ceph_assert(seq == journal_head_seq + 1);
+ }
+ journal_head_seq = seq;
+}
+
void JournalTrimmerImpl::update_journal_tails(
journal_seq_t dirty_tail,
journal_seq_t alloc_tail)
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) {
+ assert(trimmer != nullptr);
+ trimmer->set_journal_head_sequence(seq);
+ }
background_callback->maybe_wake_background();
auto new_usage = calc_utilization(seg_id);
adjust_segment_util(old_usage, new_usage);
// set the committed journal head
virtual void set_journal_head(journal_seq_t) = 0;
+ // get the opened journal head sequence
+ virtual segment_seq_t get_journal_head_sequence() const = 0;
+
+ // set the opened journal head sequence
+ virtual void set_journal_head_sequence(segment_seq_t) = 0;
+
// get the committed journal dirty tail
virtual journal_seq_t get_dirty_tail() const = 0;
}
assert(get_journal_head().segment_seq >=
get_journal_tail().segment_seq);
- return get_journal_head().segment_seq + 1 -
+ assert(get_journal_head_sequence() >=
+ get_journal_head().segment_seq);
+ return get_journal_head_sequence() + 1 -
get_journal_tail().segment_seq;
}
};
void set_journal_head(journal_seq_t) final;
+ segment_seq_t get_journal_head_sequence() const final {
+ return journal_head_seq;
+ }
+
+ void set_journal_head_sequence(segment_seq_t) final;
+
journal_seq_t get_dirty_tail() const final {
return journal_dirty_tail;
}
}
void reset() {
+ journal_head_seq = NULL_SEG_SEQ;
journal_head = JOURNAL_SEQ_NULL;
journal_dirty_tail = JOURNAL_SEQ_NULL;
journal_alloc_tail = JOURNAL_SEQ_NULL;
device_off_t roll_start;
device_off_t roll_size;
+ segment_seq_t journal_head_seq = NULL_SEG_SEQ;
journal_seq_t journal_head;
journal_seq_t journal_dirty_tail;
journal_seq_t journal_alloc_tail;
void set_journal_head(journal_seq_t) final {}
+ segment_seq_t get_journal_head_sequence() const final {
+ return NULL_SEG_SEQ;
+ }
+
+ void set_journal_head_sequence(segment_seq_t) final {}
+
journal_seq_t get_dirty_tail() const final { return dummy_tail; }
journal_seq_t get_alloc_tail() const final { return dummy_tail; }
/*
* JournalTrimmer interfaces
*/
- journal_seq_t get_journal_head() const {
+ journal_seq_t get_journal_head() const final {
return JOURNAL_SEQ_NULL;
}
+ segment_seq_t get_journal_head_sequence() const final {
+ return NULL_SEG_SEQ;
+ }
+
journal_seq_t get_dirty_tail() const final {
return JOURNAL_SEQ_NULL;
}
void set_journal_head(journal_seq_t head) final {}
+ void set_journal_head_sequence(segment_seq_t) final {}
+
void update_journal_tails(
journal_seq_t dirty_tail,
journal_seq_t alloc_tail) final {}
void set_journal_head(journal_seq_t) final {}
+ segment_seq_t get_journal_head_sequence() const final {
+ return NULL_SEG_SEQ;
+ }
+
+ void set_journal_head_sequence(segment_seq_t) final {}
+
journal_seq_t get_dirty_tail() const final { return dummy_tail; }
journal_seq_t get_alloc_tail() const final { return dummy_tail; }