dout(12) << " had ino " << in->inode.ino
<< " linked at wrong position, unlinking"
<< endl;
- dn = relink(in->dn, dir, dname);
+ dn = relink(dir, dname, in);
} else {
// link
dout(12) << " had ino " << in->inode.ino
Dir *open_dir() {
if (!dir) {
if (dn) dn->get(); // pin dentry
- get();
+ get(); // pin inode
dir = new Dir(this);
}
return dir;
delete in->dir;
in->dir = 0;
- put_inode(in);
+ put_inode(in); // unpin inode
}
int get_cache_size() { return lru.lru_get_size(); }
in->dn = dn;
in->get();
+ if (in->dir) dn->get(); // dir -> dn pin
+
lru.lru_insert_mid(dn); // mid or top?
return dn;
}
Inode *in = dn->inode;
// unlink from inode
+ if (dn->inode->dir) dn->put(); // dir -> dn pin
dn->inode = 0;
in->dn = 0;
put_inode(in);
delete dn;
}
- Dentry *relink(Dentry *dn, Dir *dir, const string& name) {
- // first link new dn to dir
- /*
- char *oldname = (char*)dn->name;
- dn->name = new char[name.length()+1];
- strcpy((char*)dn->name, name.c_str());
- dir->dentries[dn->name] = dn;
- */
- //cout << "relink dir " << dir->parent_inode->inode.ino << " '" << name << "' -> inode " << dn->inode->inode.ino << endl;
+ Dentry *relink(Dir *dir, const string& name, Inode *in) {
+ Dentry *olddn = in->dn;
+ Dir *olddir = olddn->dir; // note: might == dir!
- dir->dentries[name] = dn;
+ // newdn, attach to inode. don't touch inode ref.
+ Dentry *newdn = new Dentry;
+ newdn->name = name;
+ newdn->inode = in;
+ newdn->dir = dir;
+ in->dn = newdn;
- // unlink from old dir
- dn->dir->dentries.erase(dn->name);
- //delete[] oldname;
- if (dn->dir->is_empty())
- close_dir(dn->dir);
+ if (in->dir) { // dir -> dn pin
+ newdn->get();
+ olddn->put();
+ }
- // fix up dn
- dn->name = name;
- dn->dir = dir;
+ // unlink old dn from dir
+ olddir->dentries.erase(olddn->name);
+ olddn->inode = 0;
+ olddn->dir = 0;
+ lru.lru_remove(olddn);
+
+ // link new dn to dir
+ dir->dentries[name] = newdn;
+ lru.lru_insert_mid(newdn);
+
+ // olddir now empty? (remember, olddir might == dir)
+ if (olddir->is_empty())
+ close_dir(olddir);
- return dn;
+ return newdn;
}
// move dentry to top of lru