]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
journal: don't hold future lock during assignment 14538/head
authorJason Dillaman <dillaman@redhat.com>
Fri, 20 Jan 2017 19:26:43 +0000 (14:26 -0500)
committerNathan Cutler <ncutler@suse.com>
Thu, 13 Apr 2017 21:06:26 +0000 (23:06 +0200)
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 <dillaman@redhat.com>
(cherry picked from commit 0f21ceef8336e35ca16148a9d58f511037911418)

src/journal/FutureImpl.cc
src/journal/FutureImpl.h

index 1597c7398dc756daa89b8f6a0ecb9bdc0e1fdfc0..e46a3c9cbf3723b04603e2425148f294d8304a82 100644 (file)
@@ -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) {
index 00542729beb5d4c8030be544ca44e7f39a3bad76..96d2d24f3bc3ea4bf8862fc80c05244d83851ade 100644 (file)
@@ -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();