]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: reorder _deferred_aio_finish 15004/head
authorSage Weil <sage@redhat.com>
Tue, 9 May 2017 02:18:25 +0000 (22:18 -0400)
committerSage Weil <sage@redhat.com>
Tue, 9 May 2017 02:18:25 +0000 (22:18 -0400)
Remove the OpSequencer from the deferred_queue before
marking the txc's completed.  This prevents a race with
_txc_finish trying to reap the completed sequencer that
is still on the deferred_queue, triggering an assert
in the intrusive list hook dtor.

Fixes: http://tracker.ceph.com/issues/19880
Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc

index ee8a5042d5390a67feefffd32fe3022e2d38f57e..5c0224c67f6860d8db088f1e2139e9a48e7c15a8 100644 (file)
@@ -8281,19 +8281,7 @@ void BlueStore::_deferred_aio_finish(OpSequencer *osr)
 {
   dout(10) << __func__ << " osr " << osr << dendl;
   assert(osr->deferred_running);
-
   DeferredBatch *b = osr->deferred_running;
-  {
-    std::lock_guard<std::mutex> l2(osr->qlock);
-    for (auto& i : b->txcs) {
-      TransContext *txc = &i;
-      txc->state = TransContext::STATE_DEFERRED_CLEANUP;
-      txc->osr->qcond.notify_all();
-      throttle_deferred_bytes.put(txc->cost);
-    }
-    std::lock_guard<std::mutex> l(kv_lock);
-    deferred_done_queue.emplace_back(b);
-  }
 
   {
     std::lock_guard<std::mutex> l(deferred_lock);
@@ -8307,6 +8295,18 @@ void BlueStore::_deferred_aio_finish(OpSequencer *osr)
     }
   }
 
+  {
+    std::lock_guard<std::mutex> l2(osr->qlock);
+    for (auto& i : b->txcs) {
+      TransContext *txc = &i;
+      txc->state = TransContext::STATE_DEFERRED_CLEANUP;
+      txc->osr->qcond.notify_all();
+      throttle_deferred_bytes.put(txc->cost);
+    }
+    std::lock_guard<std::mutex> l(kv_lock);
+    deferred_done_queue.emplace_back(b);
+  }
+
   // in the normal case, do not bother waking up the kv thread; it will
   // catch us on the next commit anyway.
   if (deferred_aggressive) {