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: v11.2.1~151^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bafa2b0c83d32b97a6dd85e681f2344384c539ac;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 (cherry picked from commit 0f21ceef8336e35ca16148a9d58f511037911418) --- 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();