]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
uclient: Clear the CEPH_CAP_FILE_BUFFER ref on _flush, if safe.
authorGreg Farnum <gregory.farnum@dreamhost.com>
Tue, 8 Mar 2011 17:36:52 +0000 (09:36 -0800)
committerGreg Farnum <gregory.farnum@dreamhost.com>
Tue, 8 Mar 2011 20:30:23 +0000 (12:30 -0800)
Previously we just returned if safe, but leaving the CEPH_CAP_FILE_BUFFER
ref around breaks _fsync horribly. The root cause of this is
update_inode_file_bits calling objectcacher->truncate_set without
clearing the BUFFER ref, but the mechanics of clearing it there are
complicated, and I don't believe there are any issues with keeping
around the extra reference, as long as it's cleared when necessary.

This should fix #862.

Signed-off-by: Greg Farnum <gregory.farnum@dreamhost.com>
src/client/Client.cc
src/osdc/ObjectCacher.cc

index af13a986fad2b844a55499f6e6295c817296de70..540d91ceefb319221d6572bf2c6c98049e575cec 100644 (file)
@@ -387,7 +387,7 @@ void Client::update_inode_file_bits(Inode *in,
               << truncate_size << dendl;
       in->truncate_size = truncate_size;
       in->oset.truncate_size = truncate_size;
-      if (g_conf.client_oc && prior_size > truncate_size) { //do actual truncation
+      if (g_conf.client_oc && prior_size > truncate_size) { //do actual in-memory truncation
        vector<ObjectExtent> ls;
        filer->file_to_extents(in->ino, &in->layout,
                               truncate_size, prior_size - truncate_size,
@@ -2172,9 +2172,18 @@ void Client::_flush(Inode *in, Context *onfinish)
   if (!onfinish)
     onfinish = new C_NoopContext;
   bool safe = objectcacher->commit_set(&in->oset, onfinish);
-  if (safe && onfinish) {
-    onfinish->finish(0);
-    delete 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);
+    }
   }
 }
 
index 8676774bb4b64382ff90a2b1864672bca4206bb5..9c3e14ec916fcfc3d5cde856913c18304a56fe46 100644 (file)
@@ -1671,7 +1671,9 @@ uint64_t ObjectCacher::release_all()
 
 
 
-
+/**
+ * Truncate an ObjectSet by removing the objects in exls from the in-memory oset.
+ */
 void ObjectCacher::truncate_set(ObjectSet *oset, vector<ObjectExtent>& exls)
 {
   if (oset->objects.empty()) {