From: Yin Congmin Date: Tue, 28 Dec 2021 06:10:35 +0000 (+0800) Subject: librbd/cache/pwl: correct cache state X-Git-Tag: v18.0.0~1146^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F45660%2Fhead;p=ceph.git librbd/cache/pwl: correct cache state update cache state after dirty_entries or log_enties list updated. Fixes: https://tracker.ceph.com/issues/50614 Signed-off-by: Yin Congmin --- diff --git a/src/librbd/cache/pwl/AbstractWriteLog.cc b/src/librbd/cache/pwl/AbstractWriteLog.cc index b11d947d34fe..0a01238e2654 100644 --- a/src/librbd/cache/pwl/AbstractWriteLog.cc +++ b/src/librbd/cache/pwl/AbstractWriteLog.cc @@ -574,11 +574,32 @@ void AbstractWriteLog::pwl_init(Context *on_finish, DeferredContexts &later) m_image_ctx.op_work_queue->queue(on_finish, 0); } +template +void AbstractWriteLog::update_image_cache_state() { + using klass = AbstractWriteLog; + Context *ctx = util::create_context_callback< + klass, &klass::handle_update_image_cache_state>(this); + update_image_cache_state(ctx); +} + template void AbstractWriteLog::update_image_cache_state(Context *on_finish) { + ldout(m_image_ctx.cct, 10) << dendl; m_cache_state->write_image_cache_state(on_finish); } +template +void AbstractWriteLog::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 void AbstractWriteLog::init(Context *on_finish) { CephContext *cct = m_image_ctx.cct; @@ -630,8 +651,9 @@ void AbstractWriteLog::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::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::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::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); } diff --git a/src/librbd/cache/pwl/AbstractWriteLog.h b/src/librbd/cache/pwl/AbstractWriteLog.h index e53c63206947..63f82ab0f6a9 100644 --- a/src/librbd/cache/pwl/AbstractWriteLog.h +++ b/src/librbd/cache/pwl/AbstractWriteLog.h @@ -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 diff --git a/src/librbd/cache/pwl/rwl/WriteLog.cc b/src/librbd/cache/pwl/rwl/WriteLog.cc index c5de5fb4e421..335dea83e833 100644 --- a/src/librbd/cache/pwl/rwl/WriteLog.cc +++ b/src/librbd/cache/pwl/rwl/WriteLog.cc @@ -117,6 +117,10 @@ void WriteLog::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::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::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()); diff --git a/src/librbd/cache/pwl/ssd/WriteLog.cc b/src/librbd/cache/pwl/ssd/WriteLog.cc index a3b183411f3f..f705198b60d4 100644 --- a/src/librbd/cache/pwl/ssd/WriteLog.cc +++ b/src/librbd/cache/pwl/ssd/WriteLog.cc @@ -197,7 +197,7 @@ bool WriteLog::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::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 @@ -813,6 +817,10 @@ bool WriteLog::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="