fin->complete(r);
}
+elist<MDSIOContextBase*> MDSIOContextBase::ctx_list(member_offset(MDSIOContextBase, list_item));
+std::atomic_flag MDSIOContextBase::ctx_list_lock = ATOMIC_FLAG_INIT;
+
+MDSIOContextBase::MDSIOContextBase(bool track)
+{
+ created_at = ceph::coarse_mono_clock::now();
+ if (track) {
+ simple_spin_lock(&ctx_list_lock);
+ ctx_list.push_back(&list_item);
+ simple_spin_unlock(&ctx_list_lock);
+ }
+}
+
+MDSIOContextBase::~MDSIOContextBase()
+{
+ simple_spin_lock(&ctx_list_lock);
+ list_item.remove_myself();
+ simple_spin_unlock(&ctx_list_lock);
+}
+
+bool MDSIOContextBase::check_ios_in_flight(ceph::coarse_mono_time cutoff,
+ std::string& slow_count,
+ ceph::coarse_mono_time& oldest)
+{
+ static const unsigned MAX_COUNT = 100;
+ unsigned slow = 0;
+
+ simple_spin_lock(&ctx_list_lock);
+ for (elist<MDSIOContextBase*>::iterator p = ctx_list.begin(); !p.end(); ++p) {
+ MDSIOContextBase *c = *p;
+ if (c->created_at >= cutoff)
+ break;
+ ++slow;
+ if (slow > MAX_COUNT)
+ break;
+ if (slow == 1)
+ oldest = c->created_at;
+ }
+ simple_spin_unlock(&ctx_list_lock);
+
+ if (slow > 0) {
+ if (slow > MAX_COUNT)
+ slow_count = std::to_string(MAX_COUNT) + "+";
+ else
+ slow_count = std::to_string(slow);
+ return true;
+ } else {
+ return false;
+ }
+}
+
void MDSIOContextBase::complete(int r) {
MDSRank *mds = get_mds();
dout(10) << "MDSIOContextBase::complete: " << typeid(*this).name() << dendl;
assert(mds != NULL);
Mutex::Locker l(mds->mds_lock);
+
if (mds->is_daemon_stopping()) {
dout(4) << "MDSIOContextBase::complete: dropping for stopping "
<< typeid(*this).name() << dendl;