CInode *head_in = mdcache->get_inode(m->get_ino());
if (!head_in) {
- dout(7) << "handle_client_caps on unknown ino " << m->get_ino() << ", dropping" << dendl;
+ if (mds->is_clientreplay()) {
+ dout(7) << "handle_client_caps on unknown ino " << m->get_ino()
+ << ", will try again after replayed client requests" << dendl;
+ mdcache->wait_replay_cap_reconnect(m->get_ino(), new C_MDS_RetryMessage(mds, m));
+ return;
+ }
+ dout(1) << "handle_client_caps on unknown ino " << m->get_ino() << ", dropping" << dendl;
m->put();
return;
}
}
}
+ for (map<inodeno_t, list<MDSInternalContextBase*> >::iterator p = cap_reconnect_waiters.begin();
+ p != cap_reconnect_waiters.end();
+ ++p)
+ mds->queue_waiters(p->second);
+
cap_imports.clear();
cap_imports_dirty.clear();
+ cap_reconnect_waiters.clear();
if (warn_str.peek() != EOF) {
mds->clog->warn() << "failed to reconnect caps for missing inodes:" << "\n";
in->choose_lock_states(dirty_caps);
dout(15) << " chose lock states on " << *in << dendl;
}
+
+ map<inodeno_t, list<MDSInternalContextBase*> >::iterator it =
+ cap_reconnect_waiters.find(in->ino());
+ if (it != cap_reconnect_waiters.end()) {
+ mds->queue_waiters(it->second);
+ cap_reconnect_waiters.erase(it);
+ }
}
}
map<inodeno_t,map<client_t,map<mds_rank_t,ceph_mds_cap_reconnect> > > cap_imports; // ino -> client -> frommds -> capex
map<inodeno_t,int> cap_imports_dirty;
set<inodeno_t> cap_imports_missing;
+ map<inodeno_t, list<MDSInternalContextBase*> > cap_reconnect_waiters;
int cap_imports_num_opening;
set<CInode*> rejoin_undef_inodes;
void set_reconnect_dirty_caps(inodeno_t ino, int dirty) {
cap_imports_dirty[ino] |= dirty;
}
+ void wait_replay_cap_reconnect(inodeno_t ino, MDSInternalContextBase *c) {
+ cap_reconnect_waiters[ino].push_back(c);
+ }
// [reconnect/rejoin caps]
map<CInode*,map<client_t, inodeno_t> > reconnected_caps; // inode -> client -> realmino