dout(12) << " had dentry " << dname
<< " with WRONG ino " << dn->inode->inode.ino
<< dendl;
- unlink(dn);
+ unlink(dn, true);
dn = NULL;
}
}
dout(12) << " had ino " << in->inode.ino
<< " not linked or linked at the right position, relinking"
<< dendl;
- dn = relink(dir, dname, in);
+ dn = relink_inode(dir, dname, in);
} else {
// link
dout(12) << " had ino " << in->inode.ino
return dn;
}
- void unlink(Dentry *dn) {
+ void unlink(Dentry *dn, bool keepdir = false) {
Inode *in = dn->inode;
assert(in->dn == dn);
// unlink from dir
dn->dir->dentries.erase(dn->name);
- if (dn->dir->is_empty())
+ if (dn->dir->is_empty() && !keepdir)
close_dir(dn->dir);
dn->dir = 0;
delete dn;
}
- Dentry *relink(Dir *dir, const string& name, Inode *in) {
+ Dentry *relink_inode(Dir *dir, const string& name, Inode *in) {
Dentry *olddn = in->dn;
Dir *olddir = olddn->dir; // note: might == dir!
olddn->inode = 0;
olddn->dir = 0;
lru.lru_remove(olddn);
+ delete olddn;
// link new dn to dir
dir->dentries[name] = newdn;