From f6f876fe51e40570596c25ac84ba3689f72776c2 Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Fri, 8 Mar 2013 17:49:27 -0800 Subject: [PATCH] ObjectCacher: keep track of outstanding reads on an object 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 --- src/osdc/ObjectCacher.cc | 4 ++-- src/osdc/ObjectCacher.h | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index 8d9269314f8e4..c583b4c249167 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -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; diff --git a/src/osdc/ObjectCacher.h b/src/osdc/ObjectCacher.h index 5200dd90209ee..a49afe44ad7ef 100644 --- a/src/osdc/ObjectCacher.h +++ b/src/osdc/ObjectCacher.h @@ -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 > waitfor_commit; + xlist 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::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(); } }; -- 2.39.5