From 081fe72398633b66b93bc961cfd7d8599d5d0cba Mon Sep 17 00:00:00 2001 From: David Zafman Date: Thu, 21 Sep 2017 20:35:27 -0700 Subject: [PATCH] osd: For recovery get all possible shards to read on errors Signed-off-by: David Zafman (cherry picked from commit 390d12f71a1bd6e07f3516b1c73e467e9960725d) --- src/osd/ECBackend.cc | 62 +++++++++++++++++++++----------------------- src/osd/ECBackend.h | 8 +++++- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/osd/ECBackend.cc b/src/osd/ECBackend.cc index 8e11122d37d8c..b75948c4fe3cc 100644 --- a/src/osd/ECBackend.cc +++ b/src/osd/ECBackend.cc @@ -1203,7 +1203,6 @@ void ECBackend::handle_sub_read_reply( set want_to_read, dummy_minimum; get_want_to_read_shards(&want_to_read); int err; - // TODO: Should we include non-acting nodes here when for_recovery is set? if ((err = ec_impl->minimum_to_decode(want_to_read, have, &dummy_minimum)) < 0) { dout(20) << __func__ << " minimum_to_decode failed" << dendl; if (rop.in_progress.empty()) { @@ -1485,19 +1484,12 @@ void ECBackend::call_write_ordered(std::function &&cb) { } } -int ECBackend::get_min_avail_to_read_shards( +void ECBackend::get_all_avail_shards( const hobject_t &hoid, - const set &want, - bool for_recovery, - bool do_redundant_reads, - set *to_read) + set &have, + map &shards, + bool for_recovery) { - // Make sure we don't do redundant reads for recovery - assert(!for_recovery || !do_redundant_reads); - - set have; - map shards; - for (set::const_iterator i = get_parent()->get_acting_shards().begin(); i != get_parent()->get_acting_shards().end(); @@ -1548,6 +1540,22 @@ int ECBackend::get_min_avail_to_read_shards( } } } +} + +int ECBackend::get_min_avail_to_read_shards( + const hobject_t &hoid, + const set &want, + bool for_recovery, + bool do_redundant_reads, + set *to_read) +{ + // Make sure we don't do redundant reads for recovery + assert(!for_recovery || !do_redundant_reads); + + set have; + map shards; + + get_all_avail_shards(hoid, have, shards, for_recovery); set need; int r = ec_impl->minimum_to_decode(want, have, &need); @@ -1573,30 +1581,18 @@ int ECBackend::get_min_avail_to_read_shards( int ECBackend::get_remaining_shards( const hobject_t &hoid, const set &avail, - set *to_read) + set *to_read, + bool for_recovery) { - set need; - map shards; + assert(to_read); - for (set::const_iterator i = - get_parent()->get_acting_shards().begin(); - i != get_parent()->get_acting_shards().end(); - ++i) { - dout(10) << __func__ << ": checking acting " << *i << dendl; - const pg_missing_t &missing = get_parent()->get_shard_missing(*i); - if (!missing.is_missing(hoid)) { - assert(!need.count(i->shard)); - need.insert(i->shard); - assert(!shards.count(i->shard)); - shards.insert(make_pair(i->shard, *i)); - } - } + set have; + map shards; - if (!to_read) - return 0; + get_all_avail_shards(hoid, have, shards, for_recovery); - for (set::iterator i = need.begin(); - i != need.end(); + for (set::iterator i = have.begin(); + i != have.end(); ++i) { assert(shards.count(shard_id_t(*i))); if (avail.find(*i) == avail.end()) @@ -2318,7 +2314,7 @@ int ECBackend::send_all_remaining_reads( already_read.insert(i->shard); dout(10) << __func__ << " have/error shards=" << already_read << dendl; set shards; - int r = get_remaining_shards(hoid, already_read, &shards); + int r = get_remaining_shards(hoid, already_read, &shards, rop.for_recovery); if (r) return r; if (shards.empty()) diff --git a/src/osd/ECBackend.h b/src/osd/ECBackend.h index 85c2ee6b4f8ef..120e2d298bfad 100644 --- a/src/osd/ECBackend.h +++ b/src/osd/ECBackend.h @@ -320,6 +320,11 @@ private: const PushReplyOp &op, pg_shard_t from, RecoveryMessages *m); + void get_all_avail_shards( + const hobject_t &hoid, + set &have, + map &shards, + bool for_recovery); public: /** @@ -650,7 +655,8 @@ public: int get_remaining_shards( const hobject_t &hoid, const set &avail, - set *to_read); + set *to_read, + bool for_recovery); int objects_get_attrs( const hobject_t &hoid, -- 2.39.5