From a8c1cf36b1c2aa8efc7e5f97104048267501ab4c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 8 May 2017 22:18:25 -0400 Subject: [PATCH] os/bluestore: reorder _deferred_aio_finish 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 --- src/os/bluestore/BlueStore.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index ee8a5042d539..5c0224c67f68 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -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 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 l(kv_lock); - deferred_done_queue.emplace_back(b); - } { std::lock_guard l(deferred_lock); @@ -8307,6 +8295,18 @@ void BlueStore::_deferred_aio_finish(OpSequencer *osr) } } + { + std::lock_guard 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 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) { -- 2.47.3