{
if (!dn) {
// create a new Dentry
- dn = new Dentry(name);
+ dn = new Dentry(dir, name);
- // link to dir
- dn->dir = dir;
- dir->dentries[dn->name] = dn;
lru.lru_insert_mid(dn); // mid or top?
- if (!in)
- dir->num_null_dentries++;
ldout(cct, 15) << "link dir " << dir->parent_inode << " '" << name << "' to inode " << in
<< " dn " << dn << " (new dn)" << dendl;
} else {
assert(!dn->inode);
- if (in)
- dir->num_null_dentries--;
ldout(cct, 15) << "link dir " << dir->parent_inode << " '" << name << "' to inode " << in
<< " dn " << dn << " (old dn)" << dendl;
}
if (keepdentry) {
dn->lease_mds = -1;
- if (in)
- dn->dir->num_null_dentries++;
} else {
ldout(cct, 15) << "unlink removing '" << dn->name << "' dn " << dn << dendl;
// unlink from dir
- dn->dir->dentries.erase(dn->name);
- if (!in)
- dn->dir->num_null_dentries--;
- if (dn->dir->is_empty() && !keepdir)
- close_dir(dn->dir);
- dn->dir = 0;
+ Dir *dir = dn->dir;
+ dn->detach();
// delete den
lru.lru_remove(dn);
dn->put();
+
+ if (dir->is_empty() && !keepdir)
+ close_dir(dir);
}
}
#include "mds/mdstypes.h"
#include "Inode.h"
#include "InodeRef.h"
+#include "Dir.h"
class Dentry : public LRUObject {
public:
- explicit Dentry(const std::string &name) : name(name), inode_xlist_link(this) {}
+ explicit Dentry(Dir *_dir, const std::string &_name) :
+ dir(_dir), name(_name), inode_xlist_link(this)
+ {
+ auto r = dir->dentries.insert(make_pair(name, this));
+ assert(r.second);
+ dir->num_null_dentries++;
+ }
~Dentry() {
assert(ref == 0);
- inode_xlist_link.remove_myself();
+ assert(dir == nullptr);
}
/*
if (inode->ll_ref)
get(); // ll_ref -> dn pin
}
+ dir->num_null_dentries--;
}
void unlink(void) {
if (inode->is_dir()) {
assert(inode_xlist_link.get_list() == &inode->dentries);
inode_xlist_link.remove_myself();
inode.reset();
+ dir->num_null_dentries++;
+ }
+ void detach(void) {
+ assert(!inode);
+ auto p = dir->dentries.find(name);
+ assert(p != dir->dentries.end());
+ dir->dentries.erase(p);
+ dir->num_null_dentries--;
+ dir = nullptr;
}
void dump(Formatter *f) const;
friend std::ostream &operator<<(std::ostream &oss, const Dentry &Dentry);
- string name; // sort of lame
- class Dir *dir = nullptr;
+ Dir *dir;
+ const string name;
InodeRef inode;
int ref = 1; // 1 if there's a dir beneath me.
int64_t offset = 0;