]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: be more careful with FILE_BUFFER cap refs
authorSage Weil <sage@newdream.net>
Thu, 19 May 2011 21:50:41 +0000 (14:50 -0700)
committerSage Weil <sage@newdream.net>
Thu, 19 May 2011 22:04:31 +0000 (15:04 -0700)
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 <sage@newdream.net>
src/client/Client.cc
src/osdc/ObjectCacher.cc

index 90011e49a98beafd8512f5f6992685bf180cc73a..01df97097d974b58e5308daa7d4ee5f658f9d133 100644 (file)
@@ -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)
index 9c3e14ec916fcfc3d5cde856913c18304a56fe46..5883b172d163c4cca9c2bf3ea9a07b0c22dfe592 100644 (file)
@@ -1683,6 +1683,8 @@ void ObjectCacher::truncate_set(ObjectSet *oset, vector<ObjectExtent>& exls)
   
   dout(10) << "truncate_set " << oset << dendl;
 
+  bool were_dirty = oset->dirty_tx > 0;
+
   for (vector<ObjectExtent>::iterator p = exls.begin();
        p != exls.end();
        ++p) {
@@ -1707,6 +1709,11 @@ void ObjectCacher::truncate_set(ObjectSet *oset, vector<ObjectExtent>& 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);
 }