From: Mykola Golub Date: Wed, 28 Oct 2020 13:13:02 +0000 (+0000) Subject: librbd: relax requirements on finisher canceled callback X-Git-Tag: v16.1.0~730^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=20b2ef931aaecb455b6eb292cb5c00b08f70d20e;p=ceph-ci.git librbd: relax requirements on finisher canceled callback The finisher timer is started with safe_callbacks = false, and cancel_event may fail. When canceling a task it is safe to just ignore the cancel_event result and proceed, because the returned false value means the callback is in TaskFinisher::complete already but before acquiring the lock, so when it eventually acquires the lock it will just find out the task is already deleted and return. Signed-off-by: Mykola Golub --- diff --git a/src/librbd/TaskFinisher.h b/src/librbd/TaskFinisher.h index 268c7e7a917..97f6e529f6e 100644 --- a/src/librbd/TaskFinisher.h +++ b/src/librbd/TaskFinisher.h @@ -65,8 +65,7 @@ public: return false; } it->second.first->complete(-ECANCELED); - bool canceled = m_safe_timer->cancel_event(it->second.second); - ceph_assert(canceled); + m_safe_timer->cancel_event(it->second.second); m_task_contexts.erase(it); return true; } @@ -75,8 +74,7 @@ public: std::lock_guard l{*m_lock}; for (auto &[task, pair] : m_task_contexts) { pair.first->complete(-ECANCELED); - bool canceled = m_safe_timer->cancel_event(pair.second); - ceph_assert(canceled); + m_safe_timer->cancel_event(pair.second); } m_task_contexts.clear(); } @@ -102,7 +100,9 @@ public: return false; } bool canceled = m_safe_timer->cancel_event(it->second.second); - ceph_assert(canceled); + if (!canceled) { + return false; + } auto timer_ctx = new C_Task(this, task); it->second.second = timer_ctx; m_safe_timer->add_event_after(seconds, timer_ctx); @@ -117,8 +117,8 @@ public: std::lock_guard l{*m_lock}; typename TaskContexts::iterator it = m_task_contexts.find(task); if (it != m_task_contexts.end()) { - if (it->second.second != NULL) { - ceph_assert(m_safe_timer->cancel_event(it->second.second)); + if (it->second.second != NULL && + m_safe_timer->cancel_event(it->second.second)) { delete it->second.first; } else { // task already scheduled on the finisher