From 24f768dc68a3feb640c76511162df23f2db9abc1 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 27 Sep 2017 09:40:08 -0400 Subject: [PATCH] librbd: hold cache_lock while clearing cache nonexistence flags When transitioning from a snapshot that had an associated parent to a snapshot where the parent was flattened and removed, the cache was being referenced without holding the required lock. Fixes: http://tracker.ceph.com/issues/21558 Signed-off-by: Jason Dillaman (cherry picked from commit 16ef97830cde30efb96f7aee69834b3a5c2d5248) --- src/librbd/image/RefreshParentRequest.cc | 5 +++-- src/librbd/image/SetSnapRequest.cc | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librbd/image/RefreshParentRequest.cc b/src/librbd/image/RefreshParentRequest.cc index 28058abe7b557..f42121f60d6cc 100644 --- a/src/librbd/image/RefreshParentRequest.cc +++ b/src/librbd/image/RefreshParentRequest.cc @@ -69,12 +69,13 @@ void RefreshParentRequest::send() { template void RefreshParentRequest::apply() { + assert(m_child_image_ctx.cache_lock.is_locked()); + assert(m_child_image_ctx.snap_lock.is_wlocked()); + assert(m_child_image_ctx.parent_lock.is_wlocked()); if (m_child_image_ctx.parent != nullptr) { // closing parent image m_child_image_ctx.clear_nonexistence_cache(); } - assert(m_child_image_ctx.snap_lock.is_wlocked()); - assert(m_child_image_ctx.parent_lock.is_wlocked()); std::swap(m_child_image_ctx.parent, m_parent_image_ctx); } diff --git a/src/librbd/image/SetSnapRequest.cc b/src/librbd/image/SetSnapRequest.cc index def86f99a5d8e..e68215380ce5f 100644 --- a/src/librbd/image/SetSnapRequest.cc +++ b/src/librbd/image/SetSnapRequest.cc @@ -324,6 +324,7 @@ int SetSnapRequest::apply() { ldout(cct, 10) << __func__ << dendl; RWLock::WLocker owner_locker(m_image_ctx.owner_lock); + Mutex::Locker cache_locker(m_image_ctx.cache_lock); RWLock::WLocker snap_locker(m_image_ctx.snap_lock); RWLock::WLocker parent_locker(m_image_ctx.parent_lock); if (m_snap_id != CEPH_NOSNAP) { -- 2.39.5