]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix osr_drain before merge
authorSage Weil <sage@redhat.com>
Mon, 9 Jul 2018 22:22:58 +0000 (17:22 -0500)
committerSage Weil <sage@redhat.com>
Fri, 7 Sep 2018 17:07:56 +0000 (12:07 -0500)
We need to make sure the deferred writes on the source collection finish
before the merge so that ops ordered via the final target sequencer will
occur after those writes.

Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h

index a96d163202d8ab00920624d4fbad6e6309b565c7..66d728888ff0b080a316097bfc83645227c5affb 100644 (file)
@@ -9081,6 +9081,29 @@ void BlueStore::_osr_drain_preceding(TransContext *txc)
   dout(10) << __func__ << " " << osr << " done" << dendl;
 }
 
+void BlueStore::_osr_drain(OpSequencer *osr)
+{
+  dout(10) << __func__ << " " << osr << dendl;
+  ++deferred_aggressive; // FIXME: maybe osr-local aggressive flag?
+  {
+    // submit anything pending
+    deferred_lock.lock();
+    if (osr->deferred_pending && !osr->deferred_running) {
+      _deferred_submit_unlock(osr);
+    } else {
+      deferred_lock.unlock();
+    }
+  }
+  {
+    // wake up any previously finished deferred events
+    std::lock_guard<std::mutex> l(kv_lock);
+    kv_cond.notify_one();
+  }
+  osr->drain();
+  --deferred_aggressive;
+  dout(10) << __func__ << " " << osr << " done" << dendl;
+}
+
 void BlueStore::_osr_drain_all()
 {
   dout(10) << __func__ << dendl;
@@ -12263,12 +12286,11 @@ int BlueStore::_merge_collection(
 
   coll_t cid = (*c)->cid;
 
-  // flush all previous deferred writes on this sequencer.  this is a bit
-  // heavyweight, but we need to make sure all deferred writes complete
-  // before we split as the new collection's sequencer may need to order
-  // this after those writes, and we don't bother with the complexity of
-  // moving those TransContexts over to the new osr.
-  _osr_drain_preceding(txc);
+  // flush all previous deferred writes on the source collection to ensure
+  // that all deferred writes complete before we merge as the target collection's
+  // sequencer may need to order new ops after those writes.
+
+  _osr_drain((*c)->osr.get());
 
   // move any cached items (onodes and referenced shared blobs) that will
   // belong to the child collection post-split.  leave everything else behind.
index ff7dcff90409a8f71f096db5fa504f4e204b7afc..e809edd34a7e26f89d6609df3ad34735b0c51791 100644 (file)
@@ -2194,6 +2194,7 @@ private:
 
   void _osr_attach(Collection *c);
   void _osr_register_zombie(OpSequencer *osr);
+  void _osr_drain(OpSequencer *osr);
   void _osr_drain_preceding(TransContext *txc);
   void _osr_drain_all();