]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: potential race when replaying journal ops 9816/head
authorJason Dillaman <dillaman@redhat.com>
Mon, 20 Jun 2016 13:39:24 +0000 (09:39 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 20 Jun 2016 13:39:24 +0000 (09:39 -0400)
Fixes: http://tracker.ceph.com/issues/16198
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/journal/Replay.cc
src/librbd/journal/Replay.h

index 8576e2ab3c236ded4ebabafa2cca1eb745a5dcea..ac617f09a8cc656004ae1f8449c208a44bf3dd2d 100644 (file)
@@ -147,6 +147,7 @@ Replay<I>::~Replay() {
   assert(m_aio_modify_unsafe_contexts.empty());
   assert(m_aio_modify_safe_contexts.empty());
   assert(m_op_events.empty());
+  assert(m_in_flight_op_events == 0);
 }
 
 template <typename I>
@@ -212,7 +213,7 @@ void Replay<I>::shut_down(bool cancel_ops, Context *on_finish) {
     }
 
     assert(m_flush_ctx == nullptr);
-    if (!m_op_events.empty() || flush_comp != nullptr) {
+    if (m_in_flight_op_events > 0 || flush_comp != nullptr) {
       std::swap(m_flush_ctx, on_finish);
     }
   }
@@ -691,7 +692,7 @@ void Replay<I>::handle_aio_flush_complete(Context *on_flush_safe,
     m_in_flight_aio_modify -= on_safe_ctxs.size();
 
     std::swap(on_aio_ready, m_on_aio_ready);
-    if (m_op_events.empty() &&
+    if (m_in_flight_op_events == 0 &&
         (m_in_flight_aio_flush + m_in_flight_aio_modify) == 0) {
       on_flush = m_flush_ctx;
     }
@@ -740,6 +741,7 @@ Context *Replay<I>::create_op_context_callback(uint64_t op_tid,
     return nullptr;
   }
 
+  ++m_in_flight_op_events;
   *op_event = &m_op_events[op_tid];
   (*op_event)->on_start_safe = on_safe;
 
@@ -755,7 +757,6 @@ void Replay<I>::handle_op_complete(uint64_t op_tid, int r) {
                  << "r=" << r << dendl;
 
   OpEvent op_event;
-  Context *on_flush = nullptr;
   bool shutting_down = false;
   {
     Mutex::Locker locker(m_lock);
@@ -766,10 +767,6 @@ void Replay<I>::handle_op_complete(uint64_t op_tid, int r) {
     m_op_events.erase(op_it);
 
     shutting_down = (m_flush_ctx != nullptr);
-    if (m_op_events.empty() &&
-        (m_in_flight_aio_flush + m_in_flight_aio_modify) == 0) {
-      on_flush = m_flush_ctx;
-    }
   }
 
   assert(op_event.on_start_ready == nullptr || (r < 0 && r != -ERESTART));
@@ -802,8 +799,15 @@ void Replay<I>::handle_op_complete(uint64_t op_tid, int r) {
   if (op_event.on_finish_safe != nullptr) {
     op_event.on_finish_safe->complete(r);
   }
-  if (on_flush != nullptr) {
-    on_flush->complete(0);
+
+  // shut down request might have occurred while lock was
+  // dropped -- handle if pending
+  Mutex::Locker locker(m_lock);
+  assert(m_in_flight_op_events > 0);
+  --m_in_flight_op_events;
+  if (m_flush_ctx != nullptr && m_in_flight_op_events == 0 &&
+      (m_in_flight_aio_flush + m_in_flight_aio_modify) == 0) {
+    m_image_ctx.op_work_queue->queue(m_flush_ctx, 0);
   }
 }
 
index ceb67466b011c7ef5946e223ce0e80e112c1a056..bbea390f784b337b7137da05573395c45b825dea 100644 (file)
@@ -122,6 +122,7 @@ private:
   ContextSet m_aio_modify_safe_contexts;
 
   OpEvents m_op_events;
+  uint64_t m_in_flight_op_events = 0;
 
   Context *m_flush_ctx = nullptr;
   Context *m_on_aio_ready = nullptr;