summaryrefslogtreecommitdiffstats
path: root/src/osd/ECBackend.cc
diff options
context:
space:
mode:
authorSamuel Just <sam.just@inktank.com>2014-02-21 03:31:35 +0100
committerSamuel Just <sam.just@inktank.com>2014-02-22 21:35:40 +0100
commit9b852413248d863c9094faacea60596f88fedeaf (patch)
tree82d7105c948747fb4b4d0414490456e2f312aa3d /src/osd/ECBackend.cc
parentMerge branch 'wip-6685-firefly' into firefly (diff)
downloadceph-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.cc74
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)));
}
};