]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/cache/pwl: correct cache state 45660/head
authorYin Congmin <congmin.yin@intel.com>
Tue, 28 Dec 2021 06:10:35 +0000 (14:10 +0800)
committerYin Congmin <congmin.yin@intel.com>
Wed, 30 Mar 2022 13:45:29 +0000 (21:45 +0800)
update cache state after dirty_entries or log_enties list updated.

Fixes: https://tracker.ceph.com/issues/50614
Signed-off-by: Yin Congmin <congmin.yin@intel.com>
src/librbd/cache/pwl/AbstractWriteLog.cc
src/librbd/cache/pwl/AbstractWriteLog.h
src/librbd/cache/pwl/rwl/WriteLog.cc
src/librbd/cache/pwl/ssd/WriteLog.cc

index b11d947d34fec8781b83aae08a46d93cf949157b..0a01238e265443aa531eb7ea5c5a4c6bb86b684e 100644 (file)
@@ -574,11 +574,32 @@ void AbstractWriteLog<I>::pwl_init(Context *on_finish, DeferredContexts &later)
   m_image_ctx.op_work_queue->queue(on_finish, 0);
 }
 
+template <typename I>
+void AbstractWriteLog<I>::update_image_cache_state() {
+  using klass = AbstractWriteLog<I>;
+  Context *ctx = util::create_context_callback<
+                 klass, &klass::handle_update_image_cache_state>(this);
+  update_image_cache_state(ctx);
+}
+
 template <typename I>
 void AbstractWriteLog<I>::update_image_cache_state(Context *on_finish) {
+  ldout(m_image_ctx.cct, 10) << dendl;
   m_cache_state->write_image_cache_state(on_finish);
 }
 
+template <typename I>
+void AbstractWriteLog<I>::handle_update_image_cache_state(int r) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << "r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to update image cache state: " << cpp_strerror(r)
+               << dendl;
+    return;
+  }
+}
+
 template <typename I>
 void AbstractWriteLog<I>::init(Context *on_finish) {
   CephContext *cct = m_image_ctx.cct;
@@ -630,8 +651,9 @@ void AbstractWriteLog<I>::shut_down(Context *on_finish) {
         std::lock_guard locker(m_lock);
         check_image_cache_state_clean();
         m_wake_up_enabled = false;
-        m_cache_state->clean = true;
         m_log_entries.clear();
+        m_cache_state->clean = true;
+        m_cache_state->empty = true;
 
         remove_pool_file();
 
@@ -1304,6 +1326,10 @@ void AbstractWriteLog<I>::complete_op_log_entries(GenericLogOperations &&ops,
       std::lock_guard locker(m_lock);
       m_unpublished_reserves -= published_reserves;
       m_dirty_log_entries.splice(m_dirty_log_entries.end(), dirty_entries);
+      if (m_cache_state->clean && !this->m_dirty_log_entries.empty()) {
+        m_cache_state->clean = false;
+        update_image_cache_state();
+      }
     }
     op->complete(result);
     m_perfcounter->tinc(l_librbd_pwl_log_op_dis_to_app_t,
@@ -1733,6 +1759,10 @@ void AbstractWriteLog<I>::process_writeback_dirty_entries() {
         ldout(cct, 20) << "Nothing new to flush" << dendl;
         /* Do flush complete only when all flush ops are finished */
         all_clean = !m_flush_ops_in_flight;
+        if (!m_cache_state->clean && all_clean) {
+          m_cache_state->clean = true;
+          update_image_cache_state();
+        }
         break;
       }
 
@@ -1982,6 +2012,10 @@ void AbstractWriteLog<I>::flush_dirty_entries(Context *on_finish) {
     std::lock_guard locker(m_lock);
     flushing = (0 != m_flush_ops_in_flight);
     all_clean = m_dirty_log_entries.empty();
+    if (!m_cache_state->clean && all_clean && !flushing) {
+      m_cache_state->clean = true;
+      update_image_cache_state();
+    }
     stop_flushing = (m_shutting_down);
   }
 
index e53c632069479abdef2f8541158d820066dcd385..63f82ab0f6a97c0ca07536f340a87241d0b177c8 100644 (file)
@@ -236,6 +236,7 @@ private:
 
   void pwl_init(Context *on_finish, pwl::DeferredContexts &later);
   void update_image_cache_state(Context *on_finish);
+  void handle_update_image_cache_state(int r);
   void check_image_cache_state_clean();
 
   void flush_dirty_entries(Context *on_finish);
@@ -399,7 +400,7 @@ protected:
   virtual uint64_t get_max_extent() {
     return 0;
   }
-
+  void update_image_cache_state(void);
 };
 
 } // namespace pwl
index c5de5fb4e421538499dce37446e349a37d20c7c9..335dea83e8339fbbe53f7675725ce81752b278f8 100644 (file)
@@ -117,6 +117,10 @@ void WriteLog<I>::alloc_op_log_entries(GenericLogOperations &ops)
     m_log_entries.push_back(log_entry);
     ldout(m_image_ctx.cct, 20) << "operation=[" << *operation << "]" << dendl;
   }
+  if (m_cache_state->empty && !m_log_entries.empty()) {
+    m_cache_state->empty = false;
+    this->update_image_cache_state();
+  }
 }
 
 /*
@@ -321,7 +325,7 @@ bool WriteLog<I>::initialize_pool(Context *on_finish, pwl::DeferredContexts &lat
     } TX_FINALLY {
     } TX_END;
   } else {
-    m_cache_state->present = true;
+    ceph_assert(m_cache_state->present);
     /* Open existing pool */
     if ((m_log_pool =
          pmemobj_open(this->m_log_pool_name.c_str(),
@@ -552,6 +556,10 @@ bool WriteLog<I>::retire_entries(const unsigned long int frees_per_tx) {
       ceph_assert(this->m_first_valid_entry == initial_first_valid_entry);
       this->m_first_valid_entry = first_valid_entry;
       this->m_free_log_entries += retiring_entries.size();
+      if (!m_cache_state->empty && m_log_entries.empty()) {
+        m_cache_state->empty = true;
+        this->update_image_cache_state();
+      }
       for (auto &entry: retiring_entries) {
         if (entry->write_bytes()) {
           ceph_assert(this->m_bytes_cached >= entry->write_bytes());
index a3b183411f3fbe635b260cb18a372c1cbbd1461e..f705198b60d46b2009511dea559f3721569e2d8e 100644 (file)
@@ -197,7 +197,7 @@ bool WriteLog<I>::initialize_pool(Context *on_finish,
       return false;
     }
   } else {
-    m_cache_state->present = true;
+    ceph_assert(m_cache_state->present);
     r = create_and_open_bdev();
     if (r < 0) {
       on_finish->complete(r);
@@ -541,6 +541,10 @@ void WriteLog<I>::alloc_op_log_entries(GenericLogOperations &ops) {
     m_log_entries.push_back(log_entry);
     ldout(m_image_ctx.cct, 20) << "operation=[" << *operation << "]" << dendl;
   }
+  if (m_cache_state->empty && !m_log_entries.empty()) {
+    m_cache_state->empty = false;
+    this->update_image_cache_state();
+  }
 }
 
 template <typename I>
@@ -813,6 +817,10 @@ bool WriteLog<I>::retire_entries(const unsigned long int frees_per_tx) {
           this->m_bytes_allocated -= allocated_bytes;
           ceph_assert(this->m_bytes_cached >= cached_bytes);
           this->m_bytes_cached -= cached_bytes;
+          if (!m_cache_state->empty && m_log_entries.empty()) {
+            m_cache_state->empty = true;
+            this->update_image_cache_state();
+          }
 
           ldout(m_image_ctx.cct, 20)
             << "Finished root update: initial_first_valid_entry="