From bafa2b0c83d32b97a6dd85e681f2344384c539ac Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Fri, 20 Jan 2017 14:26:43 -0500 Subject: [PATCH] journal: don't hold future lock during assignment It's possible that the future raced with its owner and reaches an empty reference count. This was resulting in the future being destructed while its lock was still held. Fixes: http://tracker.ceph.com/issues/18618 Signed-off-by: Jason Dillaman (cherry picked from commit 0f21ceef8336e35ca16148a9d58f511037911418) --- src/journal/FutureImpl.cc | 9 +++++++-- src/journal/FutureImpl.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/journal/FutureImpl.cc b/src/journal/FutureImpl.cc index 1597c7398dc75..e46a3c9cbf372 100644 --- a/src/journal/FutureImpl.cc +++ b/src/journal/FutureImpl.cc @@ -39,13 +39,12 @@ void FutureImpl::flush(Context *on_safe) { m_contexts.push_back(on_safe); } - prev_future = prepare_flush(&flush_handlers); + prev_future = prepare_flush(&flush_handlers, m_lock); } } // instruct prior futures to flush as well while (prev_future) { - Mutex::Locker locker(prev_future->m_lock); prev_future = prev_future->prepare_flush(&flush_handlers); } @@ -62,6 +61,12 @@ void FutureImpl::flush(Context *on_safe) { } FutureImplPtr FutureImpl::prepare_flush(FlushHandlers *flush_handlers) { + Mutex::Locker locker(m_lock); + return prepare_flush(flush_handlers, m_lock); +} + +FutureImplPtr FutureImpl::prepare_flush(FlushHandlers *flush_handlers, + Mutex &lock) { assert(m_lock.is_locked()); if (m_flush_state == FLUSH_STATE_NONE) { diff --git a/src/journal/FutureImpl.h b/src/journal/FutureImpl.h index 00542729beb5d..96d2d24f3bc3e 100644 --- a/src/journal/FutureImpl.h +++ b/src/journal/FutureImpl.h @@ -113,6 +113,7 @@ private: Contexts m_contexts; FutureImplPtr prepare_flush(FlushHandlers *flush_handlers); + FutureImplPtr prepare_flush(FlushHandlers *flush_handlers, Mutex &lock); void consistent(int r); void finish_unlock(); -- 2.39.5