]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/async_cleaner: cleanup, replace init_complete by explicit states
authorYingxin Cheng <yingxin.cheng@intel.com>
Tue, 16 Aug 2022 08:55:04 +0000 (16:55 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Tue, 23 Aug 2022 14:05:19 +0000 (22:05 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/async_cleaner.cc
src/crimson/os/seastore/async_cleaner.h
src/crimson/os/seastore/seastore.cc
src/crimson/os/seastore/transaction_manager.cc

index 426963ad3623fa48f42e0789c9350a82e3952b89..9dc34d56fca48c8f3d8ee24b3975f3d32be57134 100644 (file)
@@ -1044,7 +1044,8 @@ AsyncCleaner::mount_ret AsyncCleaner::mount()
   LOG_PREFIX(AsyncCleaner::mount);
   const auto& sms = sm_group->get_segment_managers();
   INFO("{} segment managers", sms.size());
-  init_complete = false;
+  ceph_assert(state == cleaner_state_t::STOP);
+  state = cleaner_state_t::MOUNT;
   stats = {};
   journal_head = JOURNAL_SEQ_NULL;
   journal_alloc_tail = JOURNAL_SEQ_NULL;
@@ -1187,14 +1188,14 @@ AsyncCleaner::scan_extents_ret AsyncCleaner::scan_no_tail_segment(
   });
 }
 
-void AsyncCleaner::complete_init()
+void AsyncCleaner::start_gc()
 {
-  LOG_PREFIX(AsyncCleaner::complete_init);
+  LOG_PREFIX(AsyncCleaner::start_gc);
+  ceph_assert(state == cleaner_state_t::SCAN_SPACE);
+  state = cleaner_state_t::READY;
   if (disable_trim) {
-    init_complete = true;
     return;
   }
-  init_complete = true;
   INFO("done, start GC, {}", gc_stat_printer_t{this, true});
   ceph_assert(journal_head != JOURNAL_SEQ_NULL);
   ceph_assert(journal_alloc_tail != JOURNAL_SEQ_NULL);
@@ -1204,17 +1205,22 @@ void AsyncCleaner::complete_init()
 
 seastar::future<> AsyncCleaner::stop()
 {
+  if (is_ready()) {
+    state = cleaner_state_t::HALT;
+  } else {
+    state = cleaner_state_t::STOP;
+  }
   return gc_process.stop(
   ).then([this] {
     LOG_PREFIX(AsyncCleaner::stop);
     INFO("done, {}", gc_stat_printer_t{this, true});
+    // run_until_halt() can be called at HALT
   });
 }
 
 void AsyncCleaner::mark_space_used(
   paddr_t addr,
-  extent_len_t len,
-  bool init_scan)
+  extent_len_t len)
 {
   LOG_PREFIX(AsyncCleaner::mark_space_used);
   if (addr.get_addr_type() != paddr_types_t::SEGMENT) {
@@ -1222,7 +1228,7 @@ void AsyncCleaner::mark_space_used(
   }
   auto& seg_addr = addr.as_seg_paddr();
 
-  if (!init_scan && !init_complete) {
+  if (state < cleaner_state_t::SCAN_SPACE) {
     return;
   }
 
@@ -1246,11 +1252,10 @@ void AsyncCleaner::mark_space_used(
 
 void AsyncCleaner::mark_space_free(
   paddr_t addr,
-  extent_len_t len,
-  bool init_scan)
+  extent_len_t len)
 {
   LOG_PREFIX(AsyncCleaner::mark_space_free);
-  if (!init_complete && !init_scan) {
+  if (state < cleaner_state_t::SCAN_SPACE) {
     return;
   }
   if (addr.get_addr_type() != paddr_types_t::SEGMENT) {
@@ -1336,7 +1341,7 @@ AsyncCleaner::reserve_projected_usage(std::size_t projected_usage)
   if (disable_trim) {
     return seastar::now();
   }
-  ceph_assert(init_complete);
+  ceph_assert(is_ready());
   // The pipeline configuration prevents another IO from entering
   // prepare until the prior one exits and clears this.
   ceph_assert(!blocked_io_wake);
@@ -1379,7 +1384,7 @@ AsyncCleaner::reserve_projected_usage(std::size_t projected_usage)
 void AsyncCleaner::release_projected_usage(std::size_t projected_usage)
 {
   if (disable_trim) return;
-  ceph_assert(init_complete);
+  ceph_assert(is_ready());
   ceph_assert(stats.projected_used_bytes >= projected_usage);
   stats.projected_used_bytes -= projected_usage;
   return maybe_wake_gc_blocked_io();
@@ -1388,14 +1393,14 @@ void AsyncCleaner::release_projected_usage(std::size_t projected_usage)
 std::ostream &operator<<(std::ostream &os, AsyncCleaner::gc_stat_printer_t stats)
 {
   os << "gc_stats(";
-  if (stats.cleaner->init_complete) {
+  if (stats.cleaner->is_ready()) {
     os << "should_block_on_(trim=" << stats.cleaner->should_block_on_trim()
        << ", reclaim=" << stats.cleaner->should_block_on_reclaim() << ")"
        << ", should_(trim_dirty=" << stats.cleaner->gc_should_trim_dirty()
        << ", trim_alloc=" << stats.cleaner->gc_should_trim_alloc()
        << ", reclaim=" << stats.cleaner->gc_should_reclaim_space() << ")";
   } else {
-    os << "init";
+    os << "not-ready";
   }
   os << ", projected_avail_ratio=" << stats.cleaner->get_projected_available_ratio()
      << ", reclaim_ratio=" << stats.cleaner->get_reclaim_ratio()
@@ -1404,7 +1409,7 @@ std::ostream &operator<<(std::ostream &os, AsyncCleaner::gc_stat_printer_t stats
     os << ", journal_head=" << stats.cleaner->journal_head
        << ", alloc_tail=" << stats.cleaner->journal_alloc_tail
        << ", dirty_tail=" << stats.cleaner->journal_dirty_tail;
-    if (stats.cleaner->init_complete) {
+    if (stats.cleaner->is_ready()) {
       os << ", alloc_tail_target=" << stats.cleaner->get_alloc_tail_target()
          << ", dirty_tail_target=" << stats.cleaner->get_dirty_tail_target()
          << ", tail_limit=" << stats.cleaner->get_tail_limit();
index 60fb05487c4c32752558c159b6356a1e8227f567..91ccce27eb1f0fb40eb38291bf6c9a732fd79104 100644 (file)
@@ -526,8 +526,15 @@ public:
   bool equals(const SpaceTrackerI &other) const;
 };
 
-
 class AsyncCleaner : public SegmentProvider, public JournalTrimmer {
+  enum class cleaner_state_t {
+    STOP,
+    MOUNT,
+    SCAN_SPACE,
+    READY,
+    HALT,
+  } state = cleaner_state_t::STOP;
+
 public:
   /// Config
   struct config_t {
@@ -729,7 +736,6 @@ private:
 
   SpaceTrackerIRef space_tracker;
   segments_info_t segments;
-  bool init_complete = false;
 
   struct {
     /**
@@ -808,6 +814,10 @@ public:
   using mount_ret = mount_ertr::future<>;
   mount_ret mount();
 
+  bool is_ready() const {
+    return state >= cleaner_state_t::READY;
+  }
+
   /*
    * SegmentProvider interfaces
    */
@@ -879,19 +889,23 @@ public:
 
   void mark_space_used(
     paddr_t addr,
-    extent_len_t len,
-    bool init_scan = false);
+    extent_len_t len);
 
   void mark_space_free(
     paddr_t addr,
-    extent_len_t len,
-    bool init_scan = false);
+    extent_len_t len);
 
   SpaceTrackerIRef get_empty_space_tracker() const {
     return space_tracker->make_empty();
   }
 
-  void complete_init();
+  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()));
+  }
+
+  void start_gc();
 
   store_statfs_t stat() const {
     store_statfs_t st;
@@ -908,6 +922,7 @@ public:
   seastar::future<> stop();
 
   seastar::future<> run_until_halt() {
+    ceph_assert(state == cleaner_state_t::HALT);
     return gc_process.run_until_halt();
   }
 
@@ -962,7 +977,7 @@ private:
   segment_id_t get_next_reclaim_segment() const;
 
   journal_seq_t get_dirty_tail_target() const {
-    assert(init_complete);
+    assert(is_ready());
     auto ret = journal_head;
     ceph_assert(ret != JOURNAL_SEQ_NULL);
     if (ret.segment_seq >= config.target_journal_dirty_segments) {
@@ -975,7 +990,7 @@ private:
   }
 
   journal_seq_t get_tail_limit() const {
-    assert(init_complete);
+    assert(is_ready());
     auto ret = journal_head;
     ceph_assert(ret != JOURNAL_SEQ_NULL);
     if (ret.segment_seq >= config.max_journal_segments) {
@@ -988,7 +1003,7 @@ private:
   }
 
   journal_seq_t get_alloc_tail_target() const {
-    assert(init_complete);
+    assert(is_ready());
     auto ret = journal_head;
     ceph_assert(ret != JOURNAL_SEQ_NULL);
     if (ret.segment_seq >= config.target_journal_alloc_segments) {
@@ -1262,13 +1277,13 @@ private:
    * Encapsulates whether block pending gc.
    */
   bool should_block_on_trim() const {
-    assert(init_complete);
+    assert(is_ready());
     if (disable_trim) return false;
     return get_tail_limit() > get_journal_tail();
   }
 
   bool should_block_on_reclaim() const {
-    assert(init_complete);
+    assert(is_ready());
     if (disable_trim) return false;
     if (get_segments_reclaimable() == 0) {
       return false;
@@ -1278,7 +1293,7 @@ private:
   }
 
   bool should_block_on_gc() const {
-    assert(init_complete);
+    assert(is_ready());
     return should_block_on_trim() || should_block_on_reclaim();
   }
 
@@ -1291,7 +1306,7 @@ public:
 
 private:
   void maybe_wake_gc_blocked_io() {
-    if (!init_complete) {
+    if (!is_ready()) {
       return;
     }
     if (!should_block_on_gc() && blocked_io_wake) {
@@ -1312,7 +1327,7 @@ private:
    * Encapsulates logic for whether gc should be reclaiming segment space.
    */
   bool gc_should_reclaim_space() const {
-    assert(init_complete);
+    assert(is_ready());
     if (disable_trim) return false;
     if (get_segments_reclaimable() == 0) {
       return false;
@@ -1327,12 +1342,12 @@ private:
   }
 
   bool gc_should_trim_dirty() const {
-    assert(init_complete);
+    assert(is_ready());
     return get_dirty_tail_target() > journal_dirty_tail;
   }
 
   bool gc_should_trim_alloc() const {
-    assert(init_complete);
+    assert(is_ready());
     return get_alloc_tail_target() > journal_alloc_tail;
   }
   /**
@@ -1342,7 +1357,7 @@ private:
    */
   bool gc_should_run() const {
     if (disable_trim) return false;
-    ceph_assert(init_complete);
+    ceph_assert(is_ready());
     return gc_should_reclaim_space()
       || gc_should_trim_dirty()
       || gc_should_trim_alloc();
@@ -1354,7 +1369,7 @@ private:
       segment_type_t s_type,
       data_category_t category,
       reclaim_gen_t generation) {
-    ceph_assert(!init_complete);
+    ceph_assert(state == cleaner_state_t::MOUNT);
     auto old_usage = calc_utilization(segment);
     segments.init_closed(segment, seq, s_type, category, generation);
     auto new_usage = calc_utilization(segment);
index 53bb7e03e4ff87fe09d8662df7260de3b35e855c..079b17713f767671a78be63150dfe3b269331ac8 100644 (file)
@@ -331,6 +331,7 @@ SeaStore::mkfs_ertr::future<> SeaStore::mkfs(uuid_d new_osd_fsid)
         init_managers();
         return transaction_manager->mkfs();
       }).safe_then([this] {
+        init_managers();
         return transaction_manager->mount();
       }).safe_then([this] {
         return repeat_eagain([this] {
@@ -1860,9 +1861,10 @@ uuid_d SeaStore::get_fsid() const
 
 void SeaStore::init_managers()
 {
-  ceph_assert(!transaction_manager);
-  ceph_assert(!collection_manager);
-  ceph_assert(!onode_manager);
+  transaction_manager.reset();
+  collection_manager.reset();
+  onode_manager.reset();
+
   std::vector<Device*> sec_devices;
   for (auto &dev : secondaries) {
     sec_devices.emplace_back(dev.get());
index eccf935694f579eb8335f7774c176e40ca999a9d..add1ac2199b81e78b640a55f36a09d87d7cc2f8d 100644 (file)
@@ -121,8 +121,7 @@ TransactionManager::mount_ertr::future<> TransactionManager::mount()
           return lba_manager->init_cached_extent(t, e);
         }
       }).si_then([this, &t] {
-        assert(async_cleaner->debug_check_space(
-                 *async_cleaner->get_empty_space_tracker()));
+        async_cleaner->start_scan_space();
         return backref_manager->scan_mapped_space(
           t,
           [this](
@@ -134,13 +133,13 @@ TransactionManager::mount_ertr::future<> TransactionManager::mount()
             assert(laddr == L_ADDR_NULL);
             backref_manager->cache_new_backref_extent(paddr, type);
             cache->update_tree_extents_num(type, 1);
-            async_cleaner->mark_space_used(paddr, len, true);
+            async_cleaner->mark_space_used(paddr, len);
           } else if (laddr == L_ADDR_NULL) {
             cache->update_tree_extents_num(type, -1);
-            async_cleaner->mark_space_free(paddr, len, true);
+            async_cleaner->mark_space_free(paddr, len);
           } else {
             cache->update_tree_extents_num(type, 1);
-            async_cleaner->mark_space_used(paddr, len, true);
+            async_cleaner->mark_space_used(paddr, len);
           }
         });
       });
@@ -148,7 +147,7 @@ TransactionManager::mount_ertr::future<> TransactionManager::mount()
   }).safe_then([this] {
     return epm->open();
   }).safe_then([FNAME, this] {
-    async_cleaner->complete_init();
+    async_cleaner->start_gc();
     INFO("completed");
   }).handle_error(
     mount_ertr::pass_further{},