]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osdc/ObjectCacher: *do* pin object during write
authorSage Weil <sage@inktank.com>
Tue, 27 Nov 2012 05:13:32 +0000 (21:13 -0800)
committerSage Weil <sage@inktank.com>
Tue, 27 Nov 2012 05:13:32 +0000 (21:13 -0800)
This hopefully resolves #3431.

We originally did this in 46897fd4ffc2fe2fc2cc0c39b5d4c510df1e6c25, and
then reverted in caed0e917f8044d389d01de5ee5ecbf0d16ff349.

The current conundrum:
 - commit_set() will issue a write and queue a waiter on a tid
 - discard will discard all BufferHeads and unpin the object
 - trim will try to close and fail assert(ob->can_close())

But:
 - we can't wake the waiter on discard because we don't know what range(s)
   it is waiting for; discard needn't be the whole object.

So: pin the object so it doesn't get trimmed, and unpin when we write.

Adjust can_close() so that it is based on the lru pin status, and assert
that pinned implies the previous conditions are all true.

Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Sam Lang <sam.lang@inktank.com>
src/osdc/ObjectCacher.cc
src/osdc/ObjectCacher.h

index c933bad164a2f659e391468fb9303131197c0382..807a35e4fb6235238c7cba40a35474a8c7a50de2 100644 (file)
@@ -734,7 +734,9 @@ void ObjectCacher::bh_write(BufferHead *bh)
 {
   assert(lock.is_locked());
   ldout(cct, 7) << "bh_write " << *bh << dendl;
-  
+
+  bh->ob->get();
+
   // finishers
   C_WriteCommit *oncommit = new C_WriteCommit(this, bh->ob->oloc.pool,
                                               bh->ob->get_soid(), bh->start(), bh->length());
@@ -842,6 +844,8 @@ void ObjectCacher::bh_write_commit(int64_t poolid, sobject_t oid, loff_t start,
 
     // is the entire object set now clean and fully committed?
     ObjectSet *oset = ob->oset;
+    ob->put();
+
     if (flush_set_callback &&
        was_dirty_or_tx > 0 &&
        oset->dirty_or_tx == 0) {        // nothing dirty/tx
index b431463cdee5c7d6caf24c9c3a7b4498d1df17c1..2d180cf817a8611beac75ae703df2bcd19537091 100644 (file)
@@ -215,11 +215,11 @@ class ObjectCacher {
     void set_object_locator(object_locator_t& l) { oloc = l; }
 
     bool can_close() {
-      if (data.empty() &&
-         waitfor_commit.empty() &&
-         waitfor_rd.empty() && waitfor_wr.empty() &&
-         dirty_or_tx == 0) {
-       assert(lru_is_expireable());
+      if (lru_is_expireable()) {
+       assert(data.empty());
+       assert(waitfor_commit.empty());
+       assert(waitfor_rd.empty());
+       assert(waitfor_wr.empty());
        return true;
       }
       return false;