Export make_export() {
return Export(_wanted, issued(), pending(), client_follows, mseq+1, last_issue_stamp);
}
+ void rejoin_import() { mseq++; }
void merge(Export& other) {
// issued + pending
int newpending = other.pending | pending();
frag_t fg = cur->pick_dirfrag(path[i]);
CDir *dir = cur->get_or_open_dirfrag(this, fg);
CDentry *dn = dir->lookup(path[i]);
- CDentry::linkage_t *dnl = dn->get_linkage();
- if (!dn || dnl->is_null()) {
- if (!dir->is_complete()) {
- // fetch dir
- fetch_queue.insert(dir);
- return false;
- } else {
+ CDentry::linkage_t *dnl = dn ? dn->get_linkage() : NULL;
+
+ if (!dnl || dnl->is_null()) {
+ if (!dir->is_auth()) {
+ dout(10) << " not dirfrag auth " << *dir << dendl;
+ return true;
+ }
+ if (dnl || dir->is_complete()) {
// probably because the client created it and held a cap but it never committed
// to the journal, and the op hasn't replayed yet.
dout(5) << " dne (not created yet?) " << ino << " at " << path << dendl;
missing.insert(ino);
return true;
}
+ // fetch dir
+ fetch_queue.insert(dir);
+ return false;
}
+
cur = dnl->get_inode();
if (!cur) {
assert(dnl->is_remote());
Capability *cap = in->reconnect_cap(client, icr, session);
- if (frommds >= 0)
+ if (frommds >= 0) {
+ cap->rejoin_import();
do_cap_import(session, in, cap);
+ }
+}
+
+void MDCache::export_remaining_imported_caps()
+{
+ dout(10) << "export_remaining_imported_caps" << dendl;
+
+ for (map<inodeno_t,map<client_t,map<int,ceph_mds_cap_reconnect> > >::iterator p = cap_imports.begin();
+ p != cap_imports.end();
+ ++p) {
+ for (map<client_t,map<int,ceph_mds_cap_reconnect> >::iterator q = p->second.begin();
+ q != p->second.end();
+ ++q) {
+ Session *session = mds->sessionmap.get_session(entity_name_t::CLIENT(q->first.v));
+ if (session) {
+ // mark client caps stale.
+ MClientCaps *stale = new MClientCaps(CEPH_CAP_OP_EXPORT, p->first, 0, 0, 0);
+ mds->send_message_client_counted(stale, q->first);
+ }
+ }
+ }
+
+ cap_imports.clear();
}
void MDCache::try_reconnect_cap(CInode *in, Session *session)
void rejoin_import_cap(CInode *in, client_t client, ceph_mds_cap_reconnect& icr, int frommds);
void finish_snaprealm_reconnect(client_t client, SnapRealm *realm, snapid_t seq);
void try_reconnect_cap(CInode *in, Session *session);
+ void export_remaining_imported_caps();
// cap imports. delayed snap parent opens.
// realm inode -> client -> cap inodes needing to split to this realm
mdcache->clean_open_file_lists();
mdcache->scan_stray_dir();
+ mdcache->export_remaining_imported_caps();
finish_contexts(g_ceph_context, waiting_for_replay); // kick waiters
finish_contexts(g_ceph_context, waiting_for_active); // kick waiters
}
// notify client of success with an OPEN
mds->messenger->send_message(new MClientSession(CEPH_SESSION_OPEN), m->get_connection());
-
+
if (session->is_closed()) {
dout(10) << " session is closed, will make best effort to reconnect "
<< m->get_source_inst() << dendl;
}
filepath path(p->second.path, (uint64_t)p->second.capinfo.pathbase);
- if ((in && !in->is_auth()) ||
- !mds->mdcache->path_is_mine(path)) {
+ if (in && !in->is_auth()) {
// not mine.
dout(0) << "non-auth " << p->first << " " << path
<< ", will pass off to authority" << dendl;
// mark client caps stale.
- inode_t fake_inode;
- fake_inode.ino = p->first;
MClientCaps *stale = new MClientCaps(CEPH_CAP_OP_EXPORT, p->first, 0, 0, 0);
//stale->head.migrate_seq = 0; // FIXME ******
mds->send_message_client_counted(stale, session);
// add to cap export list.
mdcache->rejoin_export_caps(p->first, from, p->second);
} else {
- // mine. fetch later.
+ // don't know if the inode is mine
dout(0) << "missing " << p->first << " " << path
- << " (mine), will load later" << dendl;
- mdcache->rejoin_recovered_caps(p->first, from, p->second,
- -1); // "from" me.
+ << " will load or export later" << dendl;
+ mdcache->rejoin_recovered_caps(p->first, from, p->second, -1);
+ mdcache->rejoin_export_caps(p->first, from, p->second);
}
}