From: Jason Dillaman Date: Fri, 20 Jan 2017 19:26:43 +0000 (-0500) Subject: journal: don't hold future lock during assignment X-Git-Tag: v12.0.0~127^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0f21ceef8336e35ca16148a9d58f511037911418;p=ceph.git 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 --- diff --git a/src/journal/FutureImpl.cc b/src/journal/FutureImpl.cc index 1597c7398dc7..e46a3c9cbf37 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 00542729beb5..96d2d24f3bc3 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();