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;
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();
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,
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;
}
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);
}
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();
+ }
}
/*
} 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(),
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());
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);
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>
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="