void MDLog::write_head(MDSInternalContextBase *c)
{
- C_OnFinisher *fin = NULL;
+ Context *fin = NULL;
if (c != NULL) {
- fin = new C_OnFinisher(new C_IO_Wrapper(mds, c), mds->finisher);
+ fin = new C_IO_Wrapper(mds, c);
}
journaler->write_head(fin);
}
C_GatherBuilder gather(g_ceph_context);
// This requires an OnFinisher wrapper because Journaler will call back the completion for write_head inside its own lock
// XXX but should maybe that be handled inside Journaler?
- gather.set_finisher(new C_OnFinisher(new C_IO_Wrapper(mds, c), mds->finisher));
+ gather.set_finisher(new C_IO_Wrapper(mds, c));
// The inode of the default Journaler we will create
ino = MDS_INO_LOG_OFFSET + mds->get_nodeid();
fin->complete(r);
}
+void C_IO_Wrapper::complete(int r)
+{
+ if (async) {
+ async = false;
+ get_mds()->finisher->queue(this, r);
+ } else {
+ MDSIOContext::complete(r);
+ }
+}
+
MDSRank *MDSInternalContextGather::get_mds()
{
derr << "Forbidden call to MDSInternalContextGather::get_mds by " << typeid(*this).name() << dendl;
class MDSIOContextBase : public MDSContext
{
- void complete(int r);
+public:
+ void complete(int r);
};
/**
*/
class C_IO_Wrapper : public MDSIOContext
{
-private:
+protected:
+ bool async;
MDSInternalContextBase *wrapped;
+ virtual void finish(int r) {
+ wrapped->complete(r);
+ wrapped = nullptr;
+ }
+ virtual void complete(int r) final;
public:
- C_IO_Wrapper(MDSRank *mds_, MDSInternalContextBase *wrapped_) : MDSIOContext(mds_), wrapped(wrapped_) {
+ C_IO_Wrapper(MDSRank *mds_, MDSInternalContextBase *wrapped_) :
+ MDSIOContext(mds_), async(true), wrapped(wrapped_) {
assert(wrapped != NULL);
}
wrapped = nullptr;
}
}
-
- virtual void finish(int r) {
- wrapped->complete(r);
- wrapped = nullptr;
- }
};
calc_recovery_set();
// Check if we need to wait for a newer OSD map before starting
- Context *fin = new C_OnFinisher(new C_IO_Wrapper(this, new C_MDS_BootStart(this, MDS_BOOT_INITIAL)), finisher);
+ Context *fin = new C_IO_Wrapper(this, new C_MDS_BootStart(this, MDS_BOOT_INITIAL));
bool const ready = objecter->wait_for_map(
mdsmap->get_last_failure_osd_epoch(),
fin);
/* We are transitioning out of standby: wait for OSD map update
before making final pass */
dout(1) << "standby_replay_restart (final takeover pass)" << dendl;
- Context *fin = new C_OnFinisher(new C_IO_Wrapper(this,
- new C_MDS_BootStart(this, MDS_BOOT_PREPARE_LOG)),
- finisher);
+ Context *fin = new C_IO_Wrapper(this, new C_MDS_BootStart(this, MDS_BOOT_PREPARE_LOG));
bool const ready =
objecter->wait_for_map(mdsmap->get_last_failure_osd_epoch(), fin);
if (ready) {
if (req_epoch > epoch) {
// well, our map is older. consult mds.
- Context *fin = new C_OnFinisher(new C_IO_Wrapper(mds,
- new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher);
+ Context *fin = new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr));
if (!mds->objecter->wait_for_map(req_epoch, fin))
return r; // wait, fin will retry this request later
// latest map. One day if COMPACT_VERSION of MClientRequest >=3,
// we can remove those code.
mdr->waited_for_osdmap = true;
- mds->objecter->wait_for_latest_osdmap(new C_OnFinisher(new C_IO_Wrapper(
- mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher));
+ mds->objecter->wait_for_latest_osdmap(new C_IO_Wrapper(
+ mds, new C_MDS_RetryRequest(mdcache, mdr)));
return r;
}
}