diff options
author | Samuel Just <sam.just@inktank.com> | 2014-02-21 03:31:35 +0100 |
---|---|---|
committer | Samuel Just <sam.just@inktank.com> | 2014-02-22 21:35:40 +0100 |
commit | 9b852413248d863c9094faacea60596f88fedeaf (patch) | |
tree | 82d7105c948747fb4b4d0414490456e2f312aa3d /src/osd/ECBackend.cc | |
parent | Merge branch 'wip-6685-firefly' into firefly (diff) | |
download | ceph-9b852413248d863c9094faacea60596f88fedeaf.tar.xz ceph-9b852413248d863c9094faacea60596f88fedeaf.zip |
ECBackend::filter_read_op: clean up read state properly
Fixes: #7494
Signed-off-by: Samuel Just <sam.just@inktank.com>
Diffstat (limited to 'src/osd/ECBackend.cc')
-rw-r--r-- | src/osd/ECBackend.cc | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/src/osd/ECBackend.cc b/src/osd/ECBackend.cc index 9e2765e8067..e4572ab6ec0 100644 --- a/src/osd/ECBackend.cc +++ b/src/osd/ECBackend.cc @@ -916,7 +916,10 @@ void ECBackend::handle_sub_read_reply( i != op.buffers_read.end(); ++i) { assert(!op.errors.count(i->first)); - assert(rop.to_read.count(i->first)); + if (!rop.to_read.count(i->first)) { + // We canceled this read! @see filter_read_op + continue; + } list<pair<uint64_t, uint64_t> >::const_iterator req_iter = rop.to_read.find(i->first)->second.to_read.begin(); list< @@ -1004,36 +1007,61 @@ void ECBackend::filter_read_op( const OSDMapRef osdmap, ReadOp &op) { + set<hobject_t> to_cancel; for (map<pg_shard_t, set<hobject_t> >::iterator i = op.source_to_obj.begin(); i != op.source_to_obj.end(); - ) { - if (!osdmap->is_down(i->first.osd)) { - ++i; + ++i) { + if (osdmap->is_down(i->first.osd)) { + to_cancel.insert(i->second.begin(), i->second.end()); + op.in_progress.erase(i->first); continue; } + } + + if (to_cancel.empty()) + return; + + for (map<pg_shard_t, set<hobject_t> >::iterator i = op.source_to_obj.begin(); + i != op.source_to_obj.end(); + ) { for (set<hobject_t>::iterator j = i->second.begin(); j != i->second.end(); - ++j) { - get_parent()->cancel_pull(*j); + ) { + if (to_cancel.count(*j)) + i->second.erase(j++); + else + ++j; + } + if (i->second.empty()) { + op.source_to_obj.erase(i++); + } else { + assert(!osdmap->is_down(i->first.osd)); + ++i; + } + } - assert(op.to_read.count(*j)); - read_request_t &req = op.to_read.find(*j)->second; - assert(req.cb); - delete req.cb; - req.cb = NULL; + for (set<hobject_t>::iterator i = to_cancel.begin(); + i != to_cancel.end(); + ++i) { + get_parent()->cancel_pull(*i); - op.to_read.erase(*j); - op.complete.erase(*j); - op.obj_to_source.erase(*j); - op.in_progress.erase(i->first); - recovery_ops.erase(*j); - if (op.in_progress.empty()) { - get_parent()->schedule_work( - get_parent()->bless_gencontext( - new FinishReadOp(this, op.tid))); - } - } - op.source_to_obj.erase(i++); + assert(op.to_read.count(*i)); + read_request_t &req = op.to_read.find(*i)->second; + dout(10) << __func__ << ": canceling " << req + << " for obj " << *i << dendl; + assert(req.cb); + delete req.cb; + req.cb = NULL; + + op.to_read.erase(*i); + op.complete.erase(*i); + recovery_ops.erase(*i); + } + + if (op.in_progress.empty()) { + get_parent()->schedule_work( + get_parent()->bless_gencontext( + new FinishReadOp(this, op.tid))); } }; |