From: David Zafman Date: Thu, 11 May 2017 17:20:13 +0000 (-0700) Subject: osd: Don't disable cache if doing multiple reads X-Git-Tag: ses5-milestone8~1^2~19^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fbdb70605669e701af602083a423a260bd6547fb;p=ceph.git osd: Don't disable cache if doing multiple reads Handle unusual case that a read fails after the first Signed-off-by: David Zafman --- diff --git a/src/osd/ReplicatedBackend.cc b/src/osd/ReplicatedBackend.cc index 12010168bcbc..9d533aa21770 100644 --- a/src/osd/ReplicatedBackend.cc +++ b/src/osd/ReplicatedBackend.cc @@ -2242,15 +2242,14 @@ void ReplicatedBackend::clear_pull( pulling.erase(piter); } -// This can read the local replica multiple times. This -// isn't so bad as long as the ObjectStore caches and -// h->cache_dont_need is NOT true. int ReplicatedBackend::start_pushes( const hobject_t &soid, ObjectContextRef obc, RPGHandle *h) { - int pushes = 0; + list< map::const_iterator > shards; + + dout(20) << __func__ << " soid " << soid << dendl; // who needs it? assert(get_parent()->get_actingbackfill_shards().size() > 0); for (set::iterator i = @@ -2263,17 +2262,28 @@ int ReplicatedBackend::start_pushes( get_parent()->get_shard_missing().find(peer); assert(j != get_parent()->get_shard_missing().end()); if (j->second.is_missing(soid)) { - ++pushes; - h->pushes[peer].push_back(PushOp()); - int r = prep_push_to_replica(obc, soid, peer, - &(h->pushes[peer].back()), h->cache_dont_need); - if (r < 0) { - // prep_push_to_replica() should fail on first attempt or not at all - assert(pushes == 1); - h->pushes[peer].pop_back(); - return r; + shards.push_back(j); + } + } + + // If more than 1 read will occur ignore possible request to not cache + bool cache = shards.size() == 1 ? h->cache_dont_need : false; + + for (auto j : shards) { + pg_shard_t peer = j->first; + h->pushes[peer].push_back(PushOp()); + int r = prep_push_to_replica(obc, soid, peer, + &(h->pushes[peer].back()), cache); + if (r < 0) { + // Back out all failed reads + for (auto k : shards) { + pg_shard_t p = k->first; + dout(10) << __func__ << " clean up peer " << p << dendl; + h->pushes[p].pop_back(); + if (p == peer) break; } + return r; } } - return pushes; + return shards.size(); }