"GCProcess::run encountered invalid error in gc_trim_journal"
}
);
+ } else if (gc_should_trim_backref()) {
+ return gc_trim_backref(get_backref_tail()
+ ).safe_then([](auto) {
+ return seastar::now();
+ }).handle_error(
+ crimson::ct_error::assert_all{
+ "GCProcess::run encountered invalid error in gc_trim_backref"
+ }
+ );
} else if (gc_should_reclaim_space()) {
return gc_reclaim_space(
).handle_error(
}
}
-SegmentCleaner::gc_trim_journal_ret SegmentCleaner::gc_trim_journal()
-{
- return ecb->with_transaction_intr(
- Transaction::src_t::TRIM_BACKREF,
- "trim_backref",
- [this](auto &t) {
- return seastar::do_with(
- get_dirty_tail(),
- [this, &t](auto &limit) {
- return trim_backrefs(t, limit).si_then(
- [this, &t, &limit](auto trim_backrefs_to)
- -> ExtentCallbackInterface::submit_transaction_direct_iertr::future<
- journal_seq_t> {
- if (trim_backrefs_to != JOURNAL_SEQ_NULL) {
- return ecb->submit_transaction_direct(
- t, std::make_optional<journal_seq_t>(trim_backrefs_to)
- ).si_then([trim_backrefs_to=std::move(trim_backrefs_to)]() mutable {
- return seastar::make_ready_future<
- journal_seq_t>(std::move(trim_backrefs_to));
- });
- }
- return seastar::make_ready_future<journal_seq_t>(std::move(limit));
+SegmentCleaner::gc_trim_backref_ret
+SegmentCleaner::gc_trim_backref(journal_seq_t limit) {
+ return seastar::do_with(
+ journal_seq_t(),
+ [this, limit=std::move(limit)](auto &seq) mutable {
+ return repeat_eagain([this, limit=std::move(limit), &seq] {
+ return ecb->with_transaction_intr(
+ Transaction::src_t::TRIM_BACKREF,
+ "trim_backref",
+ [this, limit](auto &t) {
+ return trim_backrefs(
+ t,
+ limit
+ ).si_then([this, &t, limit](auto trim_backrefs_to)
+ -> ExtentCallbackInterface::submit_transaction_direct_iertr::future<
+ journal_seq_t> {
+ if (trim_backrefs_to != JOURNAL_SEQ_NULL) {
+ return ecb->submit_transaction_direct(
+ t, std::make_optional<journal_seq_t>(trim_backrefs_to)
+ ).si_then([trim_backrefs_to=std::move(trim_backrefs_to)]() mutable {
+ return seastar::make_ready_future<
+ journal_seq_t>(std::move(trim_backrefs_to));
+ });
+ }
+ return seastar::make_ready_future<journal_seq_t>(std::move(limit));
+ });
+ }).safe_then([&seq](auto trim_backrefs_to) {
+ seq = std::move(trim_backrefs_to);
});
+ }).safe_then([&seq] {
+ return gc_trim_backref_ertr::make_ready_future<
+ journal_seq_t>(std::move(seq));
});
- }).handle_error(
- crimson::ct_error::eagain::handle([](auto) {
- ceph_abort("unexpected eagain");
- }),
- crimson::ct_error::pass_further_all()
+ });
+}
+
+SegmentCleaner::gc_trim_journal_ret SegmentCleaner::gc_trim_journal()
+{
+ return gc_trim_backref(get_dirty_tail()
).safe_then([this](auto seq) {
return repeat_eagain([this, seq=std::move(seq)]() mutable {
return ecb->with_transaction_intr(
/// Number of maximum journal segments to block user transactions.
size_t max_journal_segments = 0;
+ /// Number of journal segments the transactions in which can
+ /// have their corresponding backrefs unmerged
+ size_t target_backref_inflight_segments = 0;
+
/// Ratio of maximum available space to disable reclaiming.
double available_ratio_gc_max = 0;
/// Ratio of minimum available space to force reclaiming.
return config_t{
12, // target_journal_segments
16, // max_journal_segments
+ 2, // target_backref_inflight_segments
.9, // available_ratio_gc_max
.2, // available_ratio_hard_limit
.8, // reclaim_ratio_hard_limit
return config_t{
2, // target_journal_segments
4, // max_journal_segments
+ 2, // target_backref_inflight_segments
.9, // available_ratio_gc_max
.2, // available_ratio_hard_limit
.8, // reclaim_ratio_hard_limit
return ret;
}
+ journal_seq_t get_backref_tail() const {
+ auto ret = segments.get_journal_head();
+ ceph_assert(ret != JOURNAL_SEQ_NULL);
+ if (ret.segment_seq >= config.target_backref_inflight_segments) {
+ ret.segment_seq -= config.target_backref_inflight_segments;
+ } else {
+ ret.segment_seq = 0;
+ ret.offset = P_ADDR_MIN;
+ }
+ return ret;
+ }
// GC status helpers
std::optional<paddr_t> next_reclaim_pos;
using gc_trim_journal_ret = gc_trim_journal_ertr::future<>;
gc_trim_journal_ret gc_trim_journal();
+ using gc_trim_backref_ertr = gc_ertr;
+ using gc_trim_backref_ret = gc_trim_backref_ertr::future<journal_seq_t>;
+ gc_trim_backref_ret gc_trim_backref(journal_seq_t limit);
+
using gc_reclaim_space_ertr = gc_ertr;
using gc_reclaim_space_ret = gc_reclaim_space_ertr::future<>;
gc_reclaim_space_ret gc_reclaim_space();
return get_dirty_tail() > journal_tail_target;
}
+ bool gc_should_trim_backref() const {
+ return get_backref_tail() > alloc_info_replay_from;
+ }
/**
* gc_should_run
*
bool gc_should_run() const {
if (disable_trim) return false;
ceph_assert(init_complete);
- return gc_should_reclaim_space() || gc_should_trim_journal();
+ return gc_should_reclaim_space()
+ || gc_should_trim_journal()
+ || gc_should_trim_backref();
}
void init_mark_segment_closed(