From fd041a1920accc0e7f2f2bc152c7fd1a0a3d8dfc Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 7 Dec 2017 14:33:59 +0800 Subject: [PATCH] client: update Dir::num_null_dentries in Dentry::{link,unlink} Signed-off-by: "Yan, Zheng" --- src/client/Client.cc | 22 ++++++---------------- src/client/Dentry.h | 25 +++++++++++++++++++++---- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 0e7c45a578376..1c2d66002eab9 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -2958,21 +2958,14 @@ Dentry* Client::link(Dir *dir, const string& name, Inode *in, Dentry *dn) { 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; } @@ -3009,22 +3002,19 @@ void Client::unlink(Dentry *dn, bool keepdir, bool keepdentry) 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); } } diff --git a/src/client/Dentry.h b/src/client/Dentry.h index 4401078a56c2d..1583267d6f565 100644 --- a/src/client/Dentry.h +++ b/src/client/Dentry.h @@ -7,13 +7,20 @@ #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); } /* @@ -43,6 +50,7 @@ public: if (inode->ll_ref) get(); // ll_ref -> dn pin } + dir->num_null_dentries--; } void unlink(void) { if (inode->is_dir()) { @@ -54,13 +62,22 @@ public: 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; -- 2.39.5