]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: sort dentries in CDir in hash order
authorYan, Zheng <zyan@redhat.com>
Sat, 23 Apr 2016 08:03:48 +0000 (16:03 +0800)
committerGreg Farnum <gfarnum@redhat.com>
Sun, 12 Jun 2016 21:10:04 +0000 (14:10 -0700)
This gives us stable ordering of dentries. (Previously ordering of
dentries changes after directory gets fragmented)

Signed-off-by: Yan, Zheng <zyan@redhat.com>
(cherry picked from commit f483224a0bc70b9eb5f62cd6cbb8b97df5b65953)

Signed-off-by: Greg Farnum <gfarnum@redhat.com
src/mds/CDentry.h
src/mds/CDir.cc
src/mds/CDir.h
src/mds/MDCache.cc
src/mds/Server.cc
src/mds/mdstypes.h

index 7861b4d97242df8c623686603ae7fe7c36f7f1b3..0198d5bda69fa3dbe7e9f4cc4de9357a74281413 100644 (file)
@@ -110,7 +110,7 @@ public:
   snapid_t first, last;
 
   dentry_key_t key() { 
-    return dentry_key_t(last, name.c_str()); 
+    return dentry_key_t(last, name.c_str(), hash);
   }
 
 public:
index 9119582de7b628d2b3b9338e4b5f6fba9b0ec254..d99c896f795270a912f36a088fb7f5f4b8e29c08 100644 (file)
@@ -295,10 +295,11 @@ bool CDir::check_rstats(bool scrub)
   return good;
 }
 
-CDentry *CDir::lookup(const char *name, snapid_t snap)
+CDentry *CDir::lookup(const string& name, snapid_t snap)
 { 
   dout(20) << "lookup (" << snap << ", '" << name << "')" << dendl;
-  map_t::iterator iter = items.lower_bound(dentry_key_t(snap, name));
+  map_t::iterator iter = items.lower_bound(dentry_key_t(snap, name.c_str(),
+                                                       inode->hash_dentry_name(name)));
   if (iter == items.end())
     return 0;
   if (iter->second->name == name &&
@@ -310,9 +311,13 @@ CDentry *CDir::lookup(const char *name, snapid_t snap)
   return 0;
 }
 
-
-
-
+CDentry *CDir::lookup_exact_snap(const string& name, snapid_t last) {
+  map_t::iterator p = items.find(dentry_key_t(last, name.c_str(),
+                                             inode->hash_dentry_name(name)));
+  if (p == items.end())
+    return NULL;
+  return p->second;
+}
 
 /***
  * linking fun
index 2748526125f79bf14bae430080c8706cfb27301b..7b6d4888f867f33ce6222b4820ff8adb84ed044b 100644 (file)
@@ -448,16 +448,11 @@ protected:
 
   // -- dentries and inodes --
  public:
-  CDentry* lookup_exact_snap(const std::string& dname, snapid_t last) {
-    map_t::iterator p = items.find(dentry_key_t(last, dname.c_str()));
-    if (p == items.end())
-      return NULL;
-    return p->second;
+  CDentry* lookup_exact_snap(const std::string& dname, snapid_t last);
+  CDentry* lookup(const std::string& n, snapid_t snap=CEPH_NOSNAP);
+  CDentry* lookup(const char *n, snapid_t snap=CEPH_NOSNAP) {
+    return lookup(std::string(n), snap);
   }
-  CDentry* lookup(const std::string& n, snapid_t snap=CEPH_NOSNAP) {
-    return lookup(n.c_str(), snap);
-  }
-  CDentry* lookup(const char *n, snapid_t snap=CEPH_NOSNAP);
 
   CDentry* add_null_dentry(const std::string& dname, 
                           snapid_t first=2, snapid_t last=CEPH_NOSNAP);
index 152b47b85ae4afd6ba19ef3c69c32cae234ea5dc..ddf46842276fba923b33118a2f5e117142552d3c 100644 (file)
@@ -4558,6 +4558,7 @@ CDir *MDCache::rejoin_invent_dirfrag(dirfrag_t df)
   if (!in->is_dir()) {
     assert(in->state_test(CInode::STATE_REJOINUNDEF));
     in->inode.mode = S_IFDIR;
+    in->inode.dir_layout.dl_dir_hash = g_conf->mds_default_dir_hash;
   }
   CDir *dir = in->get_or_open_dirfrag(this, df.frag);
   dir->state_set(CDir::STATE_REJOINUNDEF);
@@ -5753,6 +5754,8 @@ void MDCache::opened_undef_inode(CInode *in) {
   dout(10) << "opened_undef_inode " << *in << dendl;
   rejoin_undef_inodes.erase(in);
   if (in->is_dir()) {
+    // FIXME: re-hash dentries if necessary
+    assert(in->inode.dir_layout.dl_dir_hash == g_conf->mds_default_dir_hash);
     if (in->has_dirfrags() && !in->dirfragtree.is_leaf(frag_t())) {
       CDir *dir = in->get_dirfrag(frag_t());
       assert(dir);
index 750fb418cef48086229e5beccf5622ee8f9d2270..d303b531f280de5df2b05ccd0e65442f60101f59 100644 (file)
@@ -3277,6 +3277,10 @@ void Server::handle_client_readdir(MDRequestRef& mdr)
   string offset_str = req->get_path2();
   dout(10) << " frag " << fg << " offset '" << offset_str << "'" << dendl;
 
+  __u32 offset_hash = 0;
+  if (!offset_str.empty())
+    offset_hash = ceph_frag_value(diri->hash_dentry_name(offset_str));
+
   // does the frag exist?
   if (diri->dirfragtree[fg.value()] != fg) {
     frag_t newfg = diri->dirfragtree[fg.value()];
@@ -3359,8 +3363,11 @@ void Server::handle_client_readdir(MDRequestRef& mdr)
       continue;
     }
 
-    if (!offset_str.empty() && dn->get_name().compare(offset_str) <= 0)
-      continue;
+    if (!offset_str.empty()) {
+      dentry_key_t offset_key(dn->last, offset_str.c_str(), offset_hash);
+      if (!(offset_key < dn->key()))
+       continue;
+    }
 
     CInode *in = dnl->get_inode();
 
index e789856b36d7cb70e1ddb401383fdaf0021f3109..991712d4de772e839190cba13939d30bfba08144 100644 (file)
@@ -721,8 +721,10 @@ WRITE_CLASS_ENCODER(session_info_t)
 struct dentry_key_t {
   snapid_t snapid;
   const char *name;
-  dentry_key_t() : snapid(0), name(0) {}
-  dentry_key_t(snapid_t s, const char *n) : snapid(s), name(n) {}
+  __u32 hash;
+  dentry_key_t() : snapid(0), name(0), hash(0) {}
+  dentry_key_t(snapid_t s, const char *n, __u32 h=0) :
+    snapid(s), name(n), hash(h) {}
 
   bool is_valid() { return name || snapid; }
 
@@ -774,11 +776,15 @@ inline std::ostream& operator<<(std::ostream& out, const dentry_key_t &k)
 inline bool operator<(const dentry_key_t& k1, const dentry_key_t& k2)
 {
   /*
-   * order by name, then snap
+   * order by hash, name, snap
    */
-  int c = strcmp(k1.name, k2.name);
-  return 
-    c < 0 || (c == 0 && k1.snapid < k2.snapid);
+  int c = ceph_frag_value(k1.hash) - ceph_frag_value(k2.hash);
+  if (c)
+    return c < 0;
+  c = strcmp(k1.name, k2.name);
+  if (c)
+    return c < 0;
+  return k1.snapid < k2.snapid;
 }