return static_cast<std::size_t>(ret);
}
+seastar::future<> JournalTrimmerImpl::trim() {
+ return seastar::when_all(
+ [this] {
+ if (should_trim_alloc()) {
+ return trim_alloc(
+ ).handle_error(
+ crimson::ct_error::assert_all{
+ "encountered invalid error in trim_alloc"
+ }
+ );
+ } else {
+ return seastar::now();
+ }
+ },
+ [this] {
+ if (should_trim_dirty()) {
+ return trim_dirty(
+ ).handle_error(
+ crimson::ct_error::assert_all{
+ "encountered invalid error in trim_dirty"
+ }
+ );
+ } else {
+ return seastar::now();
+ }
+ }
+ ).discard_result();
+}
+
JournalTrimmerImpl::trim_ertr::future<>
JournalTrimmerImpl::trim_alloc()
{
return std::min(get_alloc_tail(), get_dirty_tail());
}
+ virtual std::size_t get_trim_size_per_cycle() const = 0;
+
bool check_is_ready() const {
return (get_journal_head() != JOURNAL_SEQ_NULL &&
get_dirty_tail() != JOURNAL_SEQ_NULL &&
void update_journal_tails(
journal_seq_t dirty_tail, journal_seq_t alloc_tail) final;
+ std::size_t get_trim_size_per_cycle() const final {
+ return config.rewrite_backref_bytes_per_cycle +
+ config.rewrite_dirty_bytes_per_cycle;
+ }
+
journal_type_t get_journal_type() const {
return journal_type;
}
return get_alloc_tail_target() > journal_alloc_tail;
}
+ bool should_trim() const {
+ return should_trim_alloc() || should_trim_dirty();
+ }
+
bool should_block_io_on_trim() const {
return get_tail_limit() >
get_journal_tail().add_offset(
reserved_usage -= usage;
}
- using trim_ertr = crimson::errorator<
- crimson::ct_error::input_output_error>;
- trim_ertr::future<> trim_dirty();
-
- trim_ertr::future<> trim_alloc();
+ seastar::future<> trim();
static JournalTrimmerImplRef create(
BackrefManager &backref_manager,
friend std::ostream &operator<<(std::ostream &, const stat_printer_t &);
private:
+ using trim_ertr = crimson::errorator<
+ crimson::ct_error::input_output_error>;
+ trim_ertr::future<> trim_dirty();
+
+ trim_ertr::future<> trim_alloc();
+
journal_seq_t get_tail_limit() const;
journal_seq_t get_dirty_tail_target() const;
journal_seq_t get_alloc_tail_target() const;
ExtentPlacementManager::BackgroundProcess::do_background_cycle()
{
assert(is_ready());
- if (trimmer->should_trim_alloc()) {
- return trimmer->trim_alloc(
- ).handle_error(
- crimson::ct_error::assert_all{
- "do_background_cycle encountered invalid error in trim_alloc"
- }
- );
- } else if (trimmer->should_trim_dirty()) {
- return trimmer->trim_dirty(
- ).handle_error(
- crimson::ct_error::assert_all{
- "do_background_cycle encountered invalid error in trim_dirty"
- }
- );
- } else if (cleaner->should_clean_space()) {
+ bool trimmer_reserve_success = true;
+ if (trimmer->should_trim()) {
+ trimmer_reserve_success =
+ cleaner->try_reserve_projected_usage(
+ trimmer->get_trim_size_per_cycle());
+ }
+
+ if (trimmer->should_trim() && trimmer_reserve_success) {
+ return trimmer->trim(
+ ).finally([this] {
+ cleaner->release_projected_usage(
+ trimmer->get_trim_size_per_cycle());
+ });
+ } else if (cleaner->should_clean_space() ||
+ // make sure cleaner will start
+ // when the trimmer should run but
+ // failed to reserve space.
+ !trimmer_reserve_success) {
return cleaner->clean_space(
).handle_error(
crimson::ct_error::assert_all{
void release_inline_usage(std::size_t) final {}
+ std::size_t get_trim_size_per_cycle() const final {
+ return 0;
+ }
+
/*
* SegmentProvider interfaces
*/
void release_inline_usage(std::size_t) final {}
+ std::size_t get_trim_size_per_cycle() const final {
+ return 0;
+ }
+
auto submit_record(record_t&& record) {
entries.push_back(record);
OrderingHandle handle = get_dummy_ordering_handle();
void release_inline_usage(std::size_t) final {}
+ std::size_t get_trim_size_per_cycle() const final {
+ return 0;
+ }
+
/*
* SegmentProvider interfaces
*/