]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds/client: pass dir hash over the wire
authorSage Weil <sage@newdream.net>
Tue, 16 Nov 2010 17:50:55 +0000 (09:50 -0800)
committerSage Weil <sage@newdream.net>
Tue, 16 Nov 2010 18:01:05 +0000 (10:01 -0800)
Add a feature bit DIRLAYOUTHASH.

Also fix client request routing for lookups (we were only hashing when
a Dentry pointer was provided, not when a relative path was).

Signed-off-by: Sage Weil <sage@newdream.net>
src/client/Client.cc
src/client/Client.h
src/include/ceph_fs.h
src/mds/CInode.cc
src/messages/MClientReply.h
src/msg/SimpleMessenger.h

index 478e5b8f728aad3cc1c6f25eacd6ac94a91f4f63..6f9c50fc2fb683fa3fe39b7bc2fe230bf291460f 100644 (file)
@@ -494,6 +494,11 @@ Inode * Client::add_update_inode(InodeStat *st, utime_t from, int mds)
     in->dirstat = st->dirstat;
     in->rstat = st->rstat;
 
+    if (in->is_dir()) {
+      in->dir_layout = st->dir_layout;
+      dout(20) << " dir hash is " << (int)in->dir_layout.dl_dir_hash << dendl;
+    }
+
     in->layout = st->layout;
     in->ctime = st->ctime;
     in->max_size = st->max_size;  // right?
@@ -651,6 +656,10 @@ Inode* Client::insert_trace(MetaRequest *request, utime_t from, int mds)
     return NULL;
   }
 
+  Connection *con = request->reply->get_connection();
+  int features = con->get_features();
+  dout(10) << " features 0x" << hex << features << dec << dendl;
+
   // snap trace
   if (reply->snapbl.length())
     update_snap_trace(reply->snapbl);
@@ -667,7 +676,7 @@ Inode* Client::insert_trace(MetaRequest *request, utime_t from, int mds)
   InodeStat ist;
 
   if (reply->head.is_dentry) {
-    dirst.decode(p);
+    dirst.decode(p, features);
     dst.decode(p);
     ::decode(dname, p);
     ::decode(dlease, p);
@@ -675,7 +684,7 @@ Inode* Client::insert_trace(MetaRequest *request, utime_t from, int mds)
 
   Inode *in = 0;
   if (reply->head.is_target) {
-    ist.decode(p);
+    ist.decode(p, features);
     in = add_update_inode(&ist, from, mds);
   }
 
@@ -759,7 +768,7 @@ Inode* Client::insert_trace(MetaRequest *request, utime_t from, int mds)
     for (unsigned i=0; i<numdn; i++) {
       ::decode(dname, p);
       ::decode(dlease, p);
-      InodeStat ist(p);
+      InodeStat ist(p, features);
       
       Inode *in = add_update_inode(&ist, from, mds);
       Dentry *dn = insert_dentry_inode(dir, dname, &dlease, in, from, mds, false);
@@ -830,13 +839,25 @@ int Client::choose_target_mds(MetaRequest *req)
 
   if (req->inode) {
     in = req->inode;
+    if (req->path.depth()) {
+      hash = ceph_str_hash(in->dir_layout.dl_dir_hash,
+                          req->path[0].data(),
+                          req->path[0].length());
+      dout(20) << " dir hash is " << (int)in->dir_layout.dl_dir_hash << " on " << req->path[0]
+              << " => " << hash << dendl;
+      is_hash = true;
+
+    }
   } else if (req->dentry) {
     if (req->dentry->inode) {
       in = req->dentry->inode;
     } else {
       in = req->dentry->dir->parent_inode;
-      hash = ceph_str_hash_linux(req->dentry->name.data(),
-                                 req->dentry->name.length());
+      hash = ceph_str_hash(in->dir_layout.dl_dir_hash,
+                          req->dentry->name.data(),
+                          req->dentry->name.length());
+      dout(20) << " dir hash is " << (int)in->dir_layout.dl_dir_hash << " on " << req->dentry->name
+              << " => " << hash << dendl;
       is_hash = true;
     }
   }
index 13aae7926a9af66a9b2d0175bf6f6f6dbec19e41..9af2439e0fa50c7094ecce19c21c0a9e639c0d7c 100644 (file)
@@ -387,6 +387,7 @@ class Inode {
   int32_t    nlink;  
 
   // file (data access)
+  ceph_dir_layout dir_layout;
   ceph_file_layout layout;
   uint64_t   size;        // on directory, # dentries
   uint32_t   truncate_seq;
index d97345b15b8fe377a25f72804eb3126ffefe9539..272dccfc705437353cd8b9647c26ff9951f00fd1 100644 (file)
@@ -470,7 +470,7 @@ struct ceph_mds_reply_inode {
        struct ceph_timespec rctime;
        struct ceph_frag_tree_head fragtree;  /* (must be at end of struct) */
 } __attribute__ ((packed));
-/* followed by frag array, then symlink string, then xattr blob */
+/* followed by frag array, symlink string, dir layout, xattr blob */
 
 /* reply_lease follows dname, and reply_inode */
 struct ceph_mds_reply_lease {
index 6909e22bc59bc0047ef10dca2b90d80879c52e1f..401530d8da1a39682344fabd1d232f7580d4ee79 100644 (file)
@@ -2084,6 +2084,8 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
 {
   int client = session->inst.name.num();
   assert(snapid);
+
+  assert(session->connection);
   
   bool valid = true;
 
@@ -2307,6 +2309,10 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
     ::encode(p->second, bl);
   }
   ::encode(symlink, bl);
+  if (session->connection->has_feature(CEPH_FEATURE_DIRLAYOUTHASH)) {
+    i = pfile ? pi : oi;
+    ::encode(i->dir_layout, bl);
+  }
   ::encode(xbl, bl);
 
   return valid;
index 4d2d444c580f9e1df93ac4cfc6cfd62f7275f027..6db029a4bf408a99a8697362e410d47450c4f87a 100644 (file)
@@ -113,15 +113,18 @@ struct InodeStat {
 
   version_t xattr_version;
   bufferlist xattrbl;
+
+  ceph_dir_layout dir_layout;
+
   //map<string, bufferptr> xattrs;
 
  public:
   InodeStat() {}
-  InodeStat(bufferlist::iterator& p) {
-    decode(p);
+  InodeStat(bufferlist::iterator& p, int features) {
+    decode(p, features);
   }
 
-  void decode(bufferlist::iterator &p) {
+  void decode(bufferlist::iterator &p, int features) {
     struct ceph_mds_reply_inode e;
     ::decode(e, p);
     vino.ino = inodeno_t(e.ino);
@@ -160,6 +163,11 @@ struct InodeStat {
     }
     ::decode(symlink, p);
     
+    if (features & CEPH_FEATURE_DIRLAYOUTHASH)
+      ::decode(dir_layout, p);
+    else
+      memset(&dir_layout, 0, sizeof(dir_layout));
+
     xattr_version = e.xattr_version;
     ::decode(xattrbl, p);
   }
index a4355003266c8f9b0d17cc9d234cfc1ee5170592..1b8c0d7e42cceb9ac8245a289099c1691ee7e1cc 100644 (file)
@@ -57,7 +57,8 @@ using namespace __gnu_cxx;
   CEPH_FEATURE_SUBSCRIBE2 |     \
   CEPH_FEATURE_MONNAMES |        \
   CEPH_FEATURE_FLOCK |           \
-  CEPH_FEATURE_RECONNECT_SEQ
+  CEPH_FEATURE_RECONNECT_SEQ |   \
+  CEPH_FEATURE_DIRLAYOUTHASH
 
 class SimpleMessenger : public Messenger {
 public: