]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
objectcacher: explicit write-thru mode
authorSage Weil <sage@newdream.net>
Fri, 4 May 2012 21:11:59 +0000 (14:11 -0700)
committerSage Weil <sage@newdream.net>
Sat, 5 May 2012 23:32:21 +0000 (16:32 -0700)
If the max_dirty config is 0, switch to write-thru mode, which will
explicitly flush and wait on the range we just dirtied.

Closes: #2335
Signed-off-by: Sage Weil <sage@newdream.net>
src/osdc/ObjectCacher.cc

index 483d329dbbf9c4e9c3d58dbb7b507559c0adccfa..1b20fbe7200372146f080bbe82516177168c82da 100644 (file)
@@ -1092,22 +1092,35 @@ int ObjectCacher::_wait_for_write(OSDWrite *wr, uint64_t len, ObjectSet *oset, M
   utime_t start = ceph_clock_now(cct);
   int ret = 0;
 
-  // wait for writeback?
-  //  - wait for dirty and tx bytes (relative to the max_dirty threshold)
-  //  - do not wait for bytes other waiters are waiting on.  this means that
-  //    threads do not wait for each other.  this effectively allows the cache size
-  //    to balloon proportional to the data that is in flight.
-  while (get_stat_dirty() + get_stat_tx() >= conf->client_oc_max_dirty + get_stat_dirty_waiting()) {
-    ldout(cct, 10) << "wait_for_write waiting on " << len << ", dirty|tx " 
-                  << (get_stat_dirty() + get_stat_tx()) 
-                  << " >= max " << conf->client_oc_max_dirty << " + dirty_waiting " << get_stat_dirty_waiting()
-                  << dendl;
-    flusher_cond.Signal();
-    stat_dirty_waiting += len;
-    stat_cond.Wait(lock);
-    stat_dirty_waiting -= len;
-    blocked++;
-    ldout(cct, 10) << "wait_for_write woke up" << dendl;
+  if (conf->client_oc_max_dirty > 0) {
+    // wait for writeback?
+    //  - wait for dirty and tx bytes (relative to the max_dirty threshold)
+    //  - do not wait for bytes other waiters are waiting on.  this means that
+    //    threads do not wait for each other.  this effectively allows the cache size
+    //    to balloon proportional to the data that is in flight.
+    while (get_stat_dirty() + get_stat_tx() >= conf->client_oc_max_dirty + get_stat_dirty_waiting()) {
+      ldout(cct, 10) << "wait_for_write waiting on " << len << ", dirty|tx " 
+                    << (get_stat_dirty() + get_stat_tx()) 
+                    << " >= max " << conf->client_oc_max_dirty << " + dirty_waiting " << get_stat_dirty_waiting()
+                    << dendl;
+      flusher_cond.Signal();
+      stat_dirty_waiting += len;
+      stat_cond.Wait(lock);
+      stat_dirty_waiting -= len;
+      blocked++;
+      ldout(cct, 10) << "wait_for_write woke up" << dendl;
+    }
+  } else {
+    // write-thru!  flush what we just wrote.
+    Cond cond;
+    bool done;
+    C_Cond *fin = new C_Cond(&cond, &done, &ret);
+    bool flushed = flush_set(oset, wr->extents, fin);
+    assert(!flushed);   // we just dirtied it, and didn't drop our lock!
+    ldout(cct, 10) << "wait_for_write waiting on write-thru of " << len << " bytes" << dendl;
+    while (!done)
+      cond.Wait(lock);
+    ldout(cct, 10) << "wait_for_write woke up, ret " << ret << dendl;
   }
 
   // start writeback anyway?