]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: update Dir::num_null_dentries in Dentry::{link,unlink} 19271/head
authorYan, Zheng <zyan@redhat.com>
Thu, 7 Dec 2017 06:33:59 +0000 (14:33 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 7 Dec 2017 06:52:33 +0000 (14:52 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/client/Client.cc
src/client/Dentry.h

index 0e7c45a5783765b9fc0e645f159ff60c0acb1f65..1c2d66002eab9cae54558fdf7aaff549c9239576 100644 (file)
@@ -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);
   }
 }
 
index 4401078a56c2d22c2035f2f50843953227323b60..1583267d6f565fc43dbbd1f9ba59e7b8d1a29f09 100644 (file)
@@ -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;