mds: fix resolve

This was broken by a01fba175b when an ambiguous import was changed
from CDIR_AUTH_UNKNOWN to <whoami,whoami> and disambiguate_imports wasn't
updated accordingly.  The result was inconsistent results for subtree
ownership on different nodes.

This updates disambiguate_imports to match that EImportStart::replay
change.

Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
This commit is contained in:
Sage Weil 2011-04-12 20:57:11 -07:00 committed by Sage Weil
parent 4fe48ed8ce
commit c9ce4cf95d

View File

@ -2321,6 +2321,9 @@ void MDCache::send_resolve_now(int who)
if (dir->authority().first != mds->get_nodeid()) if (dir->authority().first != mds->get_nodeid())
continue; continue;
if (mds->is_resolve() && my_ambiguous_imports.count(dir->dirfrag()))
continue; // we'll add it below
if (migrator->is_importing(dir->dirfrag())) { if (migrator->is_importing(dir->dirfrag())) {
// ambiguous (mid-import) // ambiguous (mid-import)
// NOTE: because we are first authority, import state is at least IMPORT_LOGGINSTART. // NOTE: because we are first authority, import state is at least IMPORT_LOGGINSTART.
@ -2331,25 +2334,31 @@ void MDCache::send_resolve_now(int who)
for (set<CDir*>::iterator p = bounds.begin(); p != bounds.end(); ++p) for (set<CDir*>::iterator p = bounds.begin(); p != bounds.end(); ++p)
dfls.push_back((*p)->dirfrag()); dfls.push_back((*p)->dirfrag());
m->add_ambiguous_import(dir->dirfrag(), dfls); m->add_ambiguous_import(dir->dirfrag(), dfls);
dout(10) << " ambig " << dir->dirfrag() << " " << dfls << dendl;
} else { } else {
// not ambiguous. // not ambiguous.
m->add_subtree(dir->dirfrag()); m->add_subtree(dir->dirfrag());
// bounds too // bounds too
vector<dirfrag_t> dfls;
for (set<CDir*>::iterator q = subtrees[dir].begin(); for (set<CDir*>::iterator q = subtrees[dir].begin();
q != subtrees[dir].end(); q != subtrees[dir].end();
++q) { ++q) {
CDir *bound = *q; CDir *bound = *q;
m->add_subtree_bound(dir->dirfrag(), bound->dirfrag()); m->add_subtree_bound(dir->dirfrag(), bound->dirfrag());
dfls.push_back(bound->dirfrag());
} }
dout(10) << " claim " << dir->dirfrag() << " " << dfls << dendl;
} }
} }
// ambiguous // ambiguous
for (map<dirfrag_t, vector<dirfrag_t> >::iterator p = my_ambiguous_imports.begin(); for (map<dirfrag_t, vector<dirfrag_t> >::iterator p = my_ambiguous_imports.begin();
p != my_ambiguous_imports.end(); p != my_ambiguous_imports.end();
++p) ++p) {
m->add_ambiguous_import(p->first, p->second); m->add_ambiguous_import(p->first, p->second);
dout(10) << " ambig " << p->first << " " << p->second << dendl;
}
// list prepare requests lacking a commit // list prepare requests lacking a commit
@ -2375,7 +2384,6 @@ void MDCache::send_resolve_now(int who)
need_resolve_ack.insert(who); need_resolve_ack.insert(who);
} }
// send // send
mds->send_message_mds(m, who); mds->send_message_mds(m, who);
} }
@ -2767,8 +2775,7 @@ void MDCache::disambiguate_imports()
CDir *dir = get_force_dirfrag(q->first); CDir *dir = get_force_dirfrag(q->first);
if (!dir) continue; if (!dir) continue;
if (dir->authority().first == CDIR_AUTH_UNKNOWN || // if i am resolving if (dir->is_ambiguous_auth()) { // works for me_ambig or if i am a surviving bystander
dir->is_ambiguous_auth()) { // if i am a surviving bystander
dout(10) << " mds" << who << " did import " << *dir << dendl; dout(10) << " mds" << who << " did import " << *dir << dendl;
adjust_bounded_subtree_auth(dir, q->second, who); adjust_bounded_subtree_auth(dir, q->second, who);
try_subtree_merge(dir); try_subtree_merge(dir);
@ -2780,18 +2787,19 @@ void MDCache::disambiguate_imports()
other_ambiguous_imports.clear(); other_ambiguous_imports.clear();
// my ambiguous imports // my ambiguous imports
pair<int,int> me_ambig(mds->whoami, mds->whoami);
while (!my_ambiguous_imports.empty()) { while (!my_ambiguous_imports.empty()) {
map<dirfrag_t, vector<dirfrag_t> >::iterator q = my_ambiguous_imports.begin(); map<dirfrag_t, vector<dirfrag_t> >::iterator q = my_ambiguous_imports.begin();
CDir *dir = get_dirfrag(q->first); CDir *dir = get_dirfrag(q->first);
if (!dir) continue; if (!dir) continue;
if (dir->authority().first != CDIR_AUTH_UNKNOWN) { if (dir->authority() != me_ambig) {
dout(10) << "ambiguous import auth known, must not be me " << *dir << dendl; dout(10) << "ambiguous import auth known, must not be me " << *dir << dendl;
cancel_ambiguous_import(q->first); cancel_ambiguous_import(q->first);
mds->mdlog->start_submit_entry(new EImportFinish(dir, false)); mds->mdlog->start_submit_entry(new EImportFinish(dir, false));
} else { } else {
dout(10) << "ambiguous import auth unknown, must be me " << *dir << dendl; dout(10) << "ambiguous import auth unclaimed, must be me " << *dir << dendl;
finish_ambiguous_import(q->first); finish_ambiguous_import(q->first);
mds->mdlog->start_submit_entry(new EImportFinish(dir, true)); mds->mdlog->start_submit_entry(new EImportFinish(dir, true));
} }