#include "crimson/os/seastore/logging.h"
#include "crimson/os/seastore/async_cleaner.h"
+#include "crimson/os/seastore/backref_manager.h"
#include "crimson/os/seastore/transaction_manager.h"
SET_SUBSYS(seastore_cleaner);
});
}
+bool AsyncCleaner::check_usage()
+{
+ SpaceTrackerIRef tracker(space_tracker->make_empty());
+ ecb->with_transaction_weak(
+ "check_usage",
+ [this, &tracker](auto &t) {
+ return backref_manager.scan_mapped_space(
+ t,
+ [&tracker](
+ paddr_t paddr,
+ extent_len_t len,
+ extent_types_t type,
+ laddr_t laddr)
+ {
+ if (paddr.get_addr_type() == paddr_types_t::SEGMENT) {
+ if (is_backref_node(type)) {
+ assert(laddr == L_ADDR_NULL);
+ tracker->allocate(
+ paddr.as_seg_paddr().get_segment_id(),
+ paddr.as_seg_paddr().get_segment_off(),
+ len);
+ } else if (laddr == L_ADDR_NULL) {
+ tracker->release(
+ paddr.as_seg_paddr().get_segment_id(),
+ paddr.as_seg_paddr().get_segment_off(),
+ len);
+ } else {
+ tracker->allocate(
+ paddr.as_seg_paddr().get_segment_id(),
+ paddr.as_seg_paddr().get_segment_off(),
+ len);
+ }
+ }
+ });
+ }).unsafe_get0();
+ return space_tracker->equals(*tracker);
+}
+
void AsyncCleaner::mark_space_used(
paddr_t addr,
extent_len_t len)
#include "osd/osd_types.h"
-#include "crimson/os/seastore/backref_manager.h"
#include "crimson/os/seastore/cached_extent.h"
#include "crimson/os/seastore/seastore_types.h"
#include "crimson/os/seastore/segment_manager.h"
bool equals(const SpaceTrackerI &other) const;
};
+class BackrefManager;
+
class AsyncCleaner : public SegmentProvider, public JournalTrimmer {
enum class cleaner_state_t {
STOP,
* Should be removed once proper support is added. TODO
*/
bool disable_trim = false;
+
public:
AsyncCleaner(
config_t config,
return *ool_segment_seq_allocator;
}
+ void set_extent_callback(ExtentCallbackInterface *cb) {
+ ecb = cb;
+ }
+
using mount_ertr = crimson::errorator<
crimson::ct_error::input_output_error>;
using mount_ret = mount_ertr::future<>;
mount_ret mount();
+ void start_scan_space() {
+ ceph_assert(state == cleaner_state_t::MOUNT);
+ state = cleaner_state_t::SCAN_SPACE;
+ assert(space_tracker->equals(*space_tracker->make_empty()));
+ }
+
+ void start_gc();
+
bool is_ready() const {
return state >= cleaner_state_t::READY;
}
/*
- * SegmentProvider interfaces
+ * JournalTrimmer interfaces
*/
+
journal_seq_t get_journal_head() const final {
return journal_head;
}
- const segment_info_t& get_seg_info(segment_id_t id) const final {
- return segments[id];
- }
-
void set_journal_head(journal_seq_t head) final {
ceph_assert(head != JOURNAL_SEQ_NULL);
ceph_assert(journal_head == JOURNAL_SEQ_NULL ||
gc_process.maybe_wake_on_space_used();
}
+ journal_seq_t get_dirty_tail() const final {
+ return journal_dirty_tail;
+ }
+
+ journal_seq_t get_alloc_tail() const final {
+ return journal_alloc_tail;
+ }
+
+ void update_journal_tails(
+ journal_seq_t dirty_tail, journal_seq_t alloc_tail) final;
+
+ /*
+ * SegmentProvider interfaces
+ */
+
+ const segment_info_t& get_seg_info(segment_id_t id) const final {
+ return segments[id];
+ }
+
segment_id_t allocate_segment(
segment_seq_t, segment_type_t, data_category_t, reclaim_gen_t) final;
return sm_group.get();
}
- journal_seq_t get_dirty_tail() const final {
- return journal_dirty_tail;
- }
-
- journal_seq_t get_alloc_tail() const final {
- return journal_alloc_tail;
- }
-
- void update_journal_tails(
- journal_seq_t dirty_tail, journal_seq_t alloc_tail) final;
-
- void adjust_segment_util(double old_usage, double new_usage) {
- auto old_index = get_bucket_index(old_usage);
- auto new_index = get_bucket_index(new_usage);
- assert(stats.segment_util.buckets[old_index].count > 0);
- stats.segment_util.buckets[old_index].count--;
- stats.segment_util.buckets[new_index].count++;
- }
-
void mark_space_used(
paddr_t addr,
extent_len_t len);
paddr_t addr,
extent_len_t len);
- SpaceTrackerIRef get_empty_space_tracker() const {
- return space_tracker->make_empty();
- }
-
- void start_scan_space() {
- ceph_assert(state == cleaner_state_t::MOUNT);
- state = cleaner_state_t::SCAN_SPACE;
- assert(debug_check_space(*get_empty_space_tracker()));
- }
+ seastar::future<> reserve_projected_usage(std::size_t projected_usage);
- void start_gc();
+ void release_projected_usage(size_t projected_usage);
store_statfs_t stat() const {
store_statfs_t st;
seastar::future<> stop();
+ // Testing interfaces
+
seastar::future<> run_until_halt() {
ceph_assert(state == cleaner_state_t::HALT);
return gc_process.run_until_halt();
}
- void set_extent_callback(ExtentCallbackInterface *cb) {
- ecb = cb;
- }
-
- bool debug_check_space(const SpaceTrackerI &tracker) {
- return space_tracker->equals(tracker);
- }
+ bool check_usage();
void set_disable_trim(bool val) {
disable_trim = val;
void log_gc_state(const char *caller) const;
-public:
- seastar::future<> reserve_projected_usage(std::size_t projected_usage);
-
- void release_projected_usage(size_t projected_usage);
-
-private:
void maybe_wake_gc_blocked_io() {
if (!is_ready()) {
return;
|| gc_should_trim_alloc();
}
+ void adjust_segment_util(double old_usage, double new_usage) {
+ auto old_index = get_bucket_index(old_usage);
+ auto new_index = get_bucket_index(new_usage);
+ assert(stats.segment_util.buckets[old_index].count > 0);
+ stats.segment_util.buckets[old_index].count--;
+ stats.segment_util.buckets[new_index].count++;
+ }
+
void init_mark_segment_closed(
segment_id_t segment,
segment_seq_t seq,
}
bool check_usage() {
- auto t = create_weak_test_transaction();
- SpaceTrackerIRef tracker(async_cleaner->get_empty_space_tracker());
- with_trans_intr(
- *t.t,
- [this, &tracker](auto &t) {
- return backref_manager->scan_mapped_space(
- t,
- [&tracker](
- paddr_t paddr,
- extent_len_t len,
- extent_types_t type,
- laddr_t laddr) {
- if (paddr.get_addr_type() == paddr_types_t::SEGMENT) {
- if (is_backref_node(type)) {
- assert(laddr == L_ADDR_NULL);
- tracker->allocate(
- paddr.as_seg_paddr().get_segment_id(),
- paddr.as_seg_paddr().get_segment_off(),
- len);
- } else if (laddr == L_ADDR_NULL) {
- tracker->release(
- paddr.as_seg_paddr().get_segment_id(),
- paddr.as_seg_paddr().get_segment_off(),
- len);
- } else {
- tracker->allocate(
- paddr.as_seg_paddr().get_segment_id(),
- paddr.as_seg_paddr().get_segment_off(),
- len);
- }
- }
- });
- }).unsafe_get0();
- return async_cleaner->debug_check_space(*tracker);
+ return async_cleaner->check_usage();
}
void replay() {