From: Sage Weil Date: Wed, 24 Oct 2012 19:44:25 +0000 (-0700) Subject: osdc/ObjectCacher: do read completions after assimilating read result X-Git-Tag: v0.55~130^2~55^2^2~13 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e287296584fbbeb98ebdc4fda049c5f480814c76;p=ceph.git osdc/ObjectCacher: do read completions after assimilating read result Wait until we have applied the entire read result to the cache before we trigger any read completion events. This is a cleaner and safer approach since we can be sure that the callback won't get blocked again on data we have but haven't applied yet. It also fixes a crash I just observed where the completion did a read, called trim(), and invalidated/destroyed the iterator/bh p was referencing. Signed-off-by: Sage Weil --- diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index 8463657083cf..803bb4c652d6 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -553,7 +553,10 @@ void ObjectCacher::bh_read_finish(int64_t poolid, sobject_t oid, loff_t start, << " with " << bp.length() << " bytes of zeroes" << dendl; bl.push_back(bp); } - + + list ls; + int err = 0; + if (objects[poolid].count(oid) == 0) { ldout(cct, 7) << "bh_read_finish no object cache" << dendl; } else { @@ -603,19 +606,20 @@ void ObjectCacher::bh_read_finish(int64_t poolid, sobject_t oid, loff_t start, p++; // finishers? - // called with lock held. - list ls; for (map >::iterator p = bh->waitfor_read.begin(); p != bh->waitfor_read.end(); p++) ls.splice(ls.end(), p->second); bh->waitfor_read.clear(); - finish_contexts(cct, ls, bh->error); + if (bh->error < 0) + err = bh->error; - // clean up? ob->try_merge_bh(bh); } } + + // called with lock held. + finish_contexts(cct, ls, err); }