From 51c2c5a7b4ac4c0319f7a5c83667b4b7c279e87e Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Mon, 21 Nov 2016 12:51:05 -0800 Subject: [PATCH] ECBackend::ReadOp: fill in complete in constructor, not in do_read_op Otherwise, send_all_remaining_reads creates duplicate entries. Fixes: http://tracker.ceph.com/issues/17966 Signed-off-by: Samuel Just --- src/osd/ECBackend.cc | 31 +++++++++++++------------------ src/osd/ECBackend.h | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/osd/ECBackend.cc b/src/osd/ECBackend.cc index 4bcc6620050..d078ca4cfae 100644 --- a/src/osd/ECBackend.cc +++ b/src/osd/ECBackend.cc @@ -1228,10 +1228,11 @@ struct FinishReadOp : public GenContext { ceph_tid_t tid; FinishReadOp(ECBackend *ec, ceph_tid_t tid) : ec(ec), tid(tid) {} void finish(ThreadPool::TPHandle &handle) { - assert(ec->tid_to_read_map.count(tid)); - int priority = ec->tid_to_read_map[tid].priority; + auto ropiter = ec->tid_to_read_map.find(tid); + assert(ropiter != ec->tid_to_read_map.end()); + int priority = ropiter->second.priority; RecoveryMessages rm; - ec->complete_read_op(ec->tid_to_read_map[tid], &rm); + ec->complete_read_op(ropiter->second, &rm); ec->dispatch_recovery_messages(rm, priority); } }; @@ -1565,13 +1566,15 @@ void ECBackend::start_read_op( { ceph_tid_t tid = get_parent()->get_tid(); assert(!tid_to_read_map.count(tid)); - ReadOp &op(tid_to_read_map[tid]); - op.priority = priority; - op.tid = tid; - op.to_read.swap(to_read); - op.op = _op; - op.do_redundant_reads = do_redundant_reads; - op.for_recovery = for_recovery; + auto &op = tid_to_read_map.emplace( + tid, + ReadOp( + priority, + tid, + do_redundant_reads, + for_recovery, + _op, + std::move(to_read))).first->second; dout(10) << __func__ << ": starting " << op << dendl; do_read_op( op); @@ -1590,9 +1593,6 @@ void ECBackend::do_read_op(ReadOp &op) i != op.to_read.end(); ++i) { bool need_attrs = i->second.want_attrs; - list > > &reslist = - op.complete[i->first].returned; for (set::const_iterator j = i->second.need.begin(); j != i->second.need.end(); ++j) { @@ -1607,11 +1607,6 @@ void ECBackend::do_read_op(ReadOp &op) i->second.to_read.begin(); j != i->second.to_read.end(); ++j) { - reslist.push_back( - boost::make_tuple( - j->get<0>(), - j->get<1>(), - map())); pair chunk_off_len = sinfo.aligned_offset_len_to_chunk(make_pair(j->get<0>(), j->get<1>())); for (set::const_iterator k = i->second.need.begin(); diff --git a/src/osd/ECBackend.h b/src/osd/ECBackend.h index 3689d118789..dcc02a348c2 100644 --- a/src/osd/ECBackend.h +++ b/src/osd/ECBackend.h @@ -379,6 +379,30 @@ public: void dump(Formatter *f) const; set in_progress; + + ReadOp( + int priority, + ceph_tid_t tid, + bool do_redundant_reads, + bool for_recovery, + OpRequestRef op, + map &&_to_read) + : priority(priority), tid(tid), op(op), do_redundant_reads(do_redundant_reads), + for_recovery(for_recovery), to_read(std::move(_to_read)) { + for (auto &&hpair: to_read) { + auto &returned = complete[hpair.first].returned; + for (auto &&extent: hpair.second.to_read) { + returned.push_back( + boost::make_tuple( + extent.get<0>(), + extent.get<1>(), + map())); + } + } + } + ReadOp() = delete; + ReadOp(const ReadOp &) = default; + ReadOp(ReadOp &&) = default; }; friend struct FinishReadOp; void filter_read_op( -- 2.39.5