Skip to content

Commit

Permalink
fix recovery context double-locking
Browse files Browse the repository at this point in the history
  • Loading branch information
liewegas committed Jan 17, 2018
1 parent 430efd9 commit a0c1e49
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/osd/ECBackend.cc
Expand Up @@ -1368,7 +1368,7 @@ void ECBackend::filter_read_op(

if (op.in_progress.empty()) {
get_parent()->schedule_recovery_work(
get_parent()->bless_gencontext(
get_parent()->bless_unlocked_gencontext(
new FinishReadOp(this, op.tid)));
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/osd/PGBackend.h
Expand Up @@ -141,6 +141,8 @@ typedef ceph::shared_ptr<const OSDMap> OSDMapRef;
virtual Context *bless_context(Context *c) = 0;
virtual GenContext<ThreadPool::TPHandle&> *bless_gencontext(
GenContext<ThreadPool::TPHandle&> *c) = 0;
virtual GenContext<ThreadPool::TPHandle&> *bless_unlocked_gencontext(
GenContext<ThreadPool::TPHandle&> *c) = 0;

virtual void send_message(int to_osd, Message *m) = 0;
virtual void queue_transaction(
Expand Down
26 changes: 26 additions & 0 deletions src/osd/PrimaryLogPG.cc
Expand Up @@ -158,6 +158,12 @@ GenContext<ThreadPool::TPHandle&> *PrimaryLogPG::bless_gencontext(
this, c, get_osdmap()->get_epoch());
}

GenContext<ThreadPool::TPHandle&> *PrimaryLogPG::bless_unlocked_gencontext(
GenContext<ThreadPool::TPHandle&> *c) {
return new UnlockedBlessedGenContext<ThreadPool::TPHandle&>(
this, c, get_osdmap()->get_epoch());
}

class PrimaryLogPG::BlessedContext : public Context {
PrimaryLogPGRef pg;
unique_ptr<Context> c;
Expand All @@ -180,6 +186,26 @@ class PrimaryLogPG::BlessedContext : public Context {
}
};

class PrimaryLogPG::UnlockedBlessedContext : public Context {
PrimaryLogPGRef pg;
unique_ptr<Context> c;
epoch_t e;
public:
BlessedContext(PrimaryLogPG *pg, Context *c, epoch_t e)
: pg(pg), c(c), e(e) {}
void finish(int r) override {
if (pg->pg_has_reset_since(e))
c.reset();
else
c.release()->complete(r);
}
bool sync_finish(int r) {
// we assume here all blessed/wrapped Contexts can complete synchronously.
c.release()->complete(r);
return true;
}
};


Context *PrimaryLogPG::bless_context(Context *c) {
return new BlessedContext(this, c, get_osdmap()->get_epoch());
Expand Down
3 changes: 3 additions & 0 deletions src/osd/PrimaryLogPG.h
Expand Up @@ -298,11 +298,14 @@ class PrimaryLogPG : public PG, public PGBackend::Listener {
Context *on_complete) override;

template<class T> class BlessedGenContext;
template<class T> class UnlockedBlessedGenContext;
class BlessedContext;
Context *bless_context(Context *c) override;

GenContext<ThreadPool::TPHandle&> *bless_gencontext(
GenContext<ThreadPool::TPHandle&> *c) override;
GenContext<ThreadPool::TPHandle&> *bless_unlocked_gencontext(
GenContext<ThreadPool::TPHandle&> *c) override;

void send_message(int to_osd, Message *m) override {
osd->send_message_osd_cluster(to_osd, m, get_osdmap()->get_epoch());
Expand Down
2 changes: 1 addition & 1 deletion src/osd/ReplicatedBackend.cc
Expand Up @@ -877,7 +877,7 @@ void ReplicatedBackend::_do_pull_response(OpRequestRef op)
t.register_on_complete(
new PG_RecoveryQueueAsync(
get_parent(),
get_parent()->bless_gencontext(c)));
get_parent()->bless_unlocked_gencontext(c)));
}
replies.erase(replies.end() - 1);

Expand Down

0 comments on commit a0c1e49

Please sign in to comment.