From 67533e14439e9b23ee4be5d62277bba6cd99895c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 19 May 2011 14:50:41 -0700 Subject: [PATCH] client: be more careful with FILE_BUFFER cap refs We should either hold a ref or not; whether we release one can't depend on whether one is held because we can't assume the ref belongs to us. This changes the fix in cf6b1de4 so that the ObjectCacher just calls the flush callback if it happens to trim all dirty buffers. We also drop the (bogus) assert about the number of refs held. Signed-off-by: Sage Weil --- src/client/Client.cc | 17 ++++------------- src/osdc/ObjectCacher.cc | 7 +++++++ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 90011e49a98be..01df97097d974 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -2198,19 +2198,11 @@ void Client::_flush(Inode *in, Context *onfinish) if (!onfinish) onfinish = new C_NoopContext; + bool safe = objectcacher->commit_set(&in->oset, onfinish); - if (safe) { - if (onfinish) { - onfinish->finish(0); - delete onfinish; - } - /* if we're safe, there shouldn't be any refs to CEPH_CAP_FILE_BUFFER - * unless we're buffering the entire thing. In that case, clear the bit. - */ - if (in->cap_refs[CEPH_CAP_FILE_BUFFER]) { - assert(in->cap_refs[CEPH_CAP_FILE_BUFFER] == 1); - put_cap_ref(in, CEPH_CAP_FILE_BUFFER); - } + if (safe && onfinish) { + onfinish->finish(0); + delete onfinish; } } @@ -2226,7 +2218,6 @@ void Client::flush_set_callback(ObjectCacher::ObjectSet *oset) void Client::_flushed(Inode *in) { dout(10) << "_flushed " << *in << dendl; - assert(in->cap_refs[CEPH_CAP_FILE_BUFFER] == 1); // release clean pages too, if we dont hold RDCACHE reference if (in->cap_refs[CEPH_CAP_FILE_CACHE] == 0) diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index 9c3e14ec916fc..5883b172d163c 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -1683,6 +1683,8 @@ void ObjectCacher::truncate_set(ObjectSet *oset, vector& exls) dout(10) << "truncate_set " << oset << dendl; + bool were_dirty = oset->dirty_tx > 0; + for (vector::iterator p = exls.begin(); p != exls.end(); ++p) { @@ -1707,6 +1709,11 @@ void ObjectCacher::truncate_set(ObjectSet *oset, vector& exls) } } } + + // did we truncate off dirty data? + if (flush_set_callback && + were_dirty && oset->dirty_tx == 0) + flush_set_callback(flush_set_callback_arg, oset); } -- 2.39.5