summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Farnum <greg@gregs42.com>2013-04-11 08:45:06 -0700
committerGregory Farnum <greg@gregs42.com>2013-04-11 08:45:06 -0700
commite32849c4eef2f5d911288aabeac0a6967b1e6ae4 (patch)
tree1f050a26f8bf1252daebdb49a594880c82d2e339
parenta3298713bb0078e53071b702cba4530436b7a946 (diff)
parent4977f3eab0cb265efeceeb02862c09e460549828 (diff)
downloadceph-e32849c4eef2f5d911288aabeac0a6967b1e6ae4.tar.gz
Merge pull request #212 from ceph/wip-4451
-rw-r--r--src/client/Client.cc24
-rw-r--r--src/mds/Capability.h1
-rw-r--r--src/mds/MDCache.cc45
-rw-r--r--src/mds/MDCache.h1
-rw-r--r--src/mds/MDS.cc1
-rw-r--r--src/mds/Server.cc15
6 files changed, 58 insertions, 29 deletions
diff --git a/src/client/Client.cc b/src/client/Client.cc
index 420c3ad00f2..aae22ffa980 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -1534,9 +1534,7 @@ void Client::handle_client_session(MClientSession *m)
case CEPH_SESSION_OPEN:
renew_caps(session);
session->state = MetaSession::STATE_OPEN;
- if (unmounting) {
- _close_mds_session(session);
- } else {
+ if (!unmounting) {
connect_mds_targets(from);
}
signal_cond_list(session->waiting_for_open);
@@ -1966,6 +1964,8 @@ void Client::send_reconnect(MetaSession *session)
resend_unsafe_requests(session);
messenger->send_message(m, session->con);
+
+ mount_cond.Signal();
}
@@ -3778,17 +3778,17 @@ void Client::unmount()
}
- // send session closes!
- for (map<int,MetaSession*>::iterator p = mds_sessions.begin();
- p != mds_sessions.end();
- ++p) {
- if (p->second->state != MetaSession::STATE_CLOSING) {
- _close_mds_session(p->second);
+ while (!mds_sessions.empty()) {
+ // send session closes!
+ for (map<int,MetaSession*>::iterator p = mds_sessions.begin();
+ p != mds_sessions.end();
+ ++p) {
+ if (p->second->state != MetaSession::STATE_CLOSING) {
+ _close_mds_session(p->second);
+ }
}
- }
- // wait for sessions to close
- while (!mds_sessions.empty()) {
+ // wait for sessions to close
ldout(cct, 2) << "waiting for " << mds_sessions.size() << " mds sessions to close" << dendl;
mount_cond.Wait(client_lock);
}
diff --git a/src/mds/Capability.h b/src/mds/Capability.h
index 946afdc02b9..54d2312daeb 100644
--- a/src/mds/Capability.h
+++ b/src/mds/Capability.h
@@ -272,6 +272,7 @@ public:
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();
diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc
index 3f090bb3238..3129ed7c267 100644
--- a/src/mds/MDCache.cc
+++ b/src/mds/MDCache.cc
@@ -4097,20 +4097,25 @@ bool MDCache::parallel_fetch_traverse_dir(inodeno_t ino, filepath& path,
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());
@@ -5041,8 +5046,32 @@ void MDCache::rejoin_import_cap(CInode *in, client_t client, ceph_mds_cap_reconn
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)
diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h
index 73780e26892..d837586a3ac 100644
--- a/src/mds/MDCache.h
+++ b/src/mds/MDCache.h
@@ -486,6 +486,7 @@ public:
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
diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc
index 3b3b2d6dc2e..935fb0c417e 100644
--- a/src/mds/MDS.cc
+++ b/src/mds/MDS.cc
@@ -1504,6 +1504,7 @@ void MDS::active_start()
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
}
diff --git a/src/mds/Server.cc b/src/mds/Server.cc
index dc7ea23f763..11ab834d856 100644
--- a/src/mds/Server.cc
+++ b/src/mds/Server.cc
@@ -574,7 +574,7 @@ void Server::handle_client_reconnect(MClientReconnect *m)
// 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;
@@ -636,15 +636,12 @@ void Server::handle_client_reconnect(MClientReconnect *m)
}
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);
@@ -652,11 +649,11 @@ void Server::handle_client_reconnect(MClientReconnect *m)
// 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);
}
}