]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore/BlueFS: make _sync_and_flush_log smarter
authorSage Weil <sage@redhat.com>
Fri, 24 Jun 2016 13:43:52 +0000 (09:43 -0400)
committerSage Weil <sage@redhat.com>
Thu, 30 Jun 2016 16:56:56 +0000 (12:56 -0400)
If we know what event we need to wait for, only wait long enough for it
to flush.  This helps the situation where another thread flushed what we
needed, and more dirty stuff was added to log_t, but we don't need to
wait for that too for our caller to be happy.

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

index 55c7df226c35bc9a13bf62d2d94473a09eb0e651..61f9388d8e8e57429b1a8f902b1c233478faaef5 100644 (file)
@@ -1023,17 +1023,26 @@ void BlueFS::_pad_bl(bufferlist& bl)
   }
 }
 
-int BlueFS::_flush_and_sync_log(std::unique_lock<std::mutex>& l)
+int BlueFS::_flush_and_sync_log(std::unique_lock<std::mutex>& l,
+                               uint64_t want_seq)
 {
   while (log_flushing) {
-    dout(10) << __func__ << " log is currently flushing, waiting" << dendl;
+    dout(10) << __func__ << " want_seq " << want_seq
+            << " log is currently flushing, waiting" << dendl;
     log_cond.wait(l);
   }
+  if (want_seq && want_seq <= log_seq_stable) {
+    dout(10) << __func__ << " want_seq " << want_seq << " <= log_seq_stable "
+            << log_seq_stable << ", done" << dendl;
+    return 0;
+  }
   if (log_t.empty()) {
-    dout(10) << __func__ << " " << log_t << " not dirty, no-op" << dendl;
+    dout(10) << __func__ << " want_seq " << want_seq
+            << " " << log_t << " not dirty, no-op" << dendl;
     return 0;
   }
   uint64_t seq = log_t.seq = ++log_seq;
+  assert(want_seq == 0 || want_seq <= seq);
   log_t.uuid = super.uuid;
   dout(10) << __func__ << " " << log_t << dendl;
   assert(!log_t.empty());
@@ -1325,7 +1334,7 @@ void BlueFS::_fsync(FileWriter *h, std::unique_lock<std::mutex>& l)
     uint64_t s = log_seq;
     dout(20) << __func__ << " file metadata was dirty (" << old_dirty_seq
             << ") on " << h->file->fnode << ", flushing log" << dendl;
-    _flush_and_sync_log(l);
+    _flush_and_sync_log(l, old_dirty_seq);
     assert(h->file->dirty_seq == 0 ||  // cleaned
           h->file->dirty_seq > s);    // or redirtied by someone else
   }
index 5feb68329ddd6beb11a97697c6e66b78beab6dc2..ac07e1c3868e25caaed029be69c8ac51b1936ec2 100644 (file)
@@ -238,7 +238,8 @@ private:
   void wait_for_aio(FileWriter *h);  // safe to call without a lock
   void _fsync(FileWriter *h, std::unique_lock<std::mutex>& l);
 
-  int _flush_and_sync_log(std::unique_lock<std::mutex>& l);
+  int _flush_and_sync_log(std::unique_lock<std::mutex>& l,
+                         uint64_t want_seq = 0);
   uint64_t _estimate_log_size();
   void _maybe_compact_log();
   void _compact_log();