summaryrefslogtreecommitdiff
path: root/src/osdc
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2012-05-04 14:11:59 -0700
committerSage Weil <sage@newdream.net>2012-05-05 16:32:21 -0700
commit6f3221a9f54abd592f1f073296e13fd98782bff8 (patch)
tree5718afbcb42919d48a04b100e3ed24ff77c53369 /src/osdc
parentc19f998a8afa1017c21b31ef52f98850929d2c5f (diff)
downloadceph-6f3221a9f54abd592f1f073296e13fd98782bff8.tar.gz
objectcacher: explicit write-thru mode
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>
Diffstat (limited to 'src/osdc')
-rw-r--r--src/osdc/ObjectCacher.cc45
1 files changed, 29 insertions, 16 deletions
diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc
index 483d329dbbf..1b20fbe7200 100644
--- a/src/osdc/ObjectCacher.cc
+++ b/src/osdc/ObjectCacher.cc
@@ -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?