{
dout(10) << "adjust_subtree_after_rename " << *diri << " from " << *olddir << endl;
- show_subtrees();
+ //show_subtrees();
list<CDir*> dfls;
diri->get_dirfrags(dfls);
} else {
// discover?
assert(!cur->is_auth());
- if (cur->is_waiter_for(CInode::WAIT_DIR)) {
- dout(10) << "traverse: need dir, already doing discover for " << *cur << endl;
- }
- else if (cur->is_ambiguous_auth()) {
+ if (cur->is_ambiguous_auth()) {
dout(10) << "traverse: need dir, waiting for single auth on " << *cur << endl;
cur->add_waiter(CInode::WAIT_SINGLEAUTH, _get_waiter(mdr, req));
return 1;
+ } else if (dir_discovers.count(cur->ino())) {
+ dout(10) << "traverse: need dir, already doing discover for " << *cur << endl;
+ assert(cur->is_waiter_for(CInode::WAIT_DIR));
} else {
filepath want = path.postfixpath(depth);
dout(10) << "traverse: need dir, doing discover, want " << want.get_path()
// frozen?
/*
if (curdir->is_frozen()) {
- // doh!
+ // doh!
// FIXME: traverse is allowed?
dout(7) << "traverse: " << *curdir << " is frozen, waiting" << endl;
curdir->add_waiter(CDir::WAIT_UNFREEZE, _get_waiter(mdr, req));
*/
// must read directory hard data (permissions, x bit) to traverse
- if (!noperm && !mds->locker->simple_rdlock_try(&cur->authlock, _get_waiter(mdr, req))) {
+ if (!noperm &&
+ !mds->locker->simple_rdlock_try(&cur->authlock, _get_waiter(mdr, req)))
return 1;
- }
// check permissions?
// XXX
dis->set_base_dir_frag(fg);
mds->send_message_mds(dis, hint, MDS_PORT_CACHE);
- // note the dangling discover
- dir_discovers[cur->ino()].insert(hint);
+ // note the dangling discover... but only if it's already noted in dir_discovers (i.e. someone is waiting)
+ if (dir_discovers.count(cur->ino())) {
+ dir_discovers[cur->ino()].insert(hint);
+ assert(cur->is_waiter_for(CInode::WAIT_DIR));
+ }
}
else if (m->is_flag_error_dir()) {
// dir error at the end there?
// set done_locking flag, to avoid problems with wrlock moving auth target
mdr->done_locking = true;
+ // -- open all srcdn inode frags, if any --
+ // we need these open so that auth can properly delegate from inode to dirfrags
+ // after the inode is _ours_.
+ if (srcdn->is_primary() &&
+ !srcdn->is_auth() &&
+ srci->is_dir()) {
+ dout(10) << "srci is remote dir, opening all frags" << endl;
+ list<frag_t> frags;
+ srci->dirfragtree.get_leaves(frags);
+ for (list<frag_t>::iterator p = frags.begin();
+ p != frags.end();
+ ++p) {
+ CDir *dir = srci->get_dirfrag(*p);
+ if (dir) {
+ dout(10) << " opened " << *dir << endl;
+ mdr->pin(dir);
+ } else {
+ mdcache->open_remote_dir(srci, *p, new C_MDS_RetryRequest(mdcache, mdr));
+ return;
+ }
+ }
+ }
// -- declare now --
if (mdr->now == utime_t())
indis->_encode(req->stray);
dirdis->_encode(req->stray);
dndis->_encode(req->stray);
+ delete indis;
delete dirdis;
delete dndis;
}
CDentry *destdn = trace[trace.size()-1];
dout(10) << " destdn " << *destdn << endl;
mdr->pin(destdn);
+
// discover srcdn
filepath srcpath(mdr->slave_request->srcdnpath);