]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ObjectCacher: keep track of outstanding reads on an object
authorJosh Durgin <josh.durgin@inktank.com>
Sat, 9 Mar 2013 01:49:27 +0000 (17:49 -0800)
committerJosh Durgin <josh.durgin@inktank.com>
Tue, 23 Apr 2013 18:33:17 +0000 (11:33 -0700)
Reads always use C_ReadFinish as a callback (and they are the only
user of this callback). Keep an xlist of these for each object, so
they can remove themselves as they finish. To prevent racing requests
and with discard removing objects from the cache, clear the xlist in
the object destructor, so if the Object is still valid the set_item
will still be on the list.

Make the ObjectCacher constructor take an Object* instead of the pool
and object id, which are derived from the Object* anyway.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
(cherry picked from commit f6f876fe51e40570596c25ac84ba3689f72776c2)

src/osdc/ObjectCacher.cc
src/osdc/ObjectCacher.h

index a115903687366c512242df4604f22736945c3a7d..63e9dd17b8500332e14ffacbe4ebb8566e13d0d8 100644 (file)
@@ -594,8 +594,8 @@ void ObjectCacher::bh_read(BufferHead *bh)
   mark_rx(bh);
 
   // finisher
-  C_ReadFinish *onfinish = new C_ReadFinish(this, bh->ob->oloc.pool,
-                                            bh->ob->get_soid(), bh->start(), bh->length());
+  C_ReadFinish *onfinish = new C_ReadFinish(this, bh->ob,
+                                           bh->start(), bh->length());
 
   ObjectSet *oset = bh->ob->oset;
 
index 0daa97972269f859c46d747af15e46b8276a73d7..27f4cf9737987a38305752ad9c4e8de154cec164 100644 (file)
@@ -45,6 +45,7 @@ class ObjectCacher {
   CephContext *cct;
   class Object;
   class ObjectSet;
+  class C_ReadFinish;
 
   typedef void (*flush_set_callback_t) (void *p, ObjectSet *oset);
 
@@ -182,6 +183,7 @@ class ObjectCacher {
     int dirty_or_tx;
 
     map< tid_t, list<Context*> > waitfor_commit;
+    xlist<C_ReadFinish*> reads;
 
   public:
     Object(const Object& other);
@@ -198,6 +200,7 @@ class ObjectCacher {
       os->objects.push_back(&set_item);
     }
     ~Object() {
+      reads.clear();
       assert(ref == 0);
       assert(data.empty());
       assert(dirty_or_tx == 0);
@@ -453,12 +456,21 @@ class ObjectCacher {
     sobject_t oid;
     loff_t start;
     uint64_t length;
+    xlist<C_ReadFinish*>::item set_item;
+
   public:
     bufferlist bl;
-    C_ReadFinish(ObjectCacher *c, int _poolid, sobject_t o, loff_t s, uint64_t l) :
-      oc(c), poolid(_poolid), oid(o), start(s), length(l) {}
+    C_ReadFinish(ObjectCacher *c, Object *ob, loff_t s, uint64_t l) :
+      oc(c), poolid(ob->oloc.pool), oid(ob->get_soid()), start(s), length(l),
+      set_item(this) {
+      ob->reads.push_back(&set_item);
+    }
+
     void finish(int r) {
       oc->bh_read_finish(poolid, oid, start, length, bl, r);
+      // object destructor clears the list
+      if (set_item.is_on_list())
+       set_item.remove_myself();
     }
   };