ostream& operator<<(ostream& out, CDir& dir)
{
string path;
- dir.get_inode()->make_path_string(path);
+ dir.get_inode()->make_path_string_projected(path);
out << "[dir " << dir.dirfrag() << " " << path << "/"
<< " [" << dir.first << ",head]";
if (dir.is_auth()) {
return parent->dir;
return NULL;
}
+CDir *CInode::get_projected_parent_dir()
+{
+ CDentry *p = get_projected_parent_dn();
+ if (p)
+ return p->dir;
+ return NULL;
+}
CInode *CInode::get_parent_inode()
{
if (parent)
CDentry* get_parent_dn() { return parent; }
CDentry* get_projected_parent_dn() { return projected_parent.size() ? projected_parent.back():parent; }
CDir *get_parent_dir();
+ CDir *get_projected_parent_dir();
CInode *get_parent_inode();
bool is_lt(const MDSCacheObject *r) const {
}
}
+CDir *MDCache::get_projected_subtree_root(CDir *dir)
+{
+ // find the underlying dir that delegates (or is about to delegate) auth
+ while (true) {
+ if (dir->is_subtree_root())
+ return dir;
+ dir = dir->get_inode()->get_projected_parent_dir();
+ if (!dir)
+ return 0; // none
+ }
+}
+
void MDCache::remove_subtree(CDir *dir)
{
dout(10) << "remove_subtree " << *dir << dendl;
void subtree_merge_writebehind_finish(CInode *in, Mutation *mut);
void eval_subtree_root(CInode *diri);
CDir *get_subtree_root(CDir *dir);
+ CDir *get_projected_subtree_root(CDir *dir);
bool is_leaf_subtree(CDir *dir) {
assert(subtrees.count(dir));
return subtrees[dir].empty();
(srcdnl->get_inode()->is_anchored() ||
(srcdnl->get_inode()->is_dir() && (srcdnl->get_inode()->inode.rstat.ranchors ||
srcdnl->get_inode()->nested_anchors ||
- !mdcache->is_leaf_subtree(mdcache->get_subtree_root(srcdn->get_dir()))))) &&
+ !mdcache->is_leaf_subtree(mdcache->get_projected_subtree_root(srcdn->get_dir()))))) &&
!mdr->more()->src_reanchor_atid) {
dout(10) << "reanchoring src->dst " << *srcdnl->get_inode() << dendl;
vector<Anchor> trace;