]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: replace FINDINODE with LOOKUPHASH
authorSage Weil <sage@newdream.net>
Wed, 1 Apr 2009 21:52:13 +0000 (14:52 -0700)
committerSage Weil <sage@newdream.net>
Wed, 1 Apr 2009 22:21:46 +0000 (15:21 -0700)
The nfs export code still needs to be fixed.

src/TODO
src/include/ceph_fs.h
src/kernel/debugfs.c
src/kernel/export.c
src/kernel/mds_client.c
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/Server.cc
src/mds/Server.h
src/messages/MClientRequest.h

index b486cce23309bd428e5641f6d6f574499100bfa8..c4574011eb71e69ddb49f5afd92196edd85f5a25 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -52,7 +52,7 @@ kclient caps
 /- size limit on readdir result, partial dirfrag readdir
 /- revisit unmount
 /- make request paths relative to a non-snapshotted inode.
-
+- fix nfs exportin
 
 - ENOSPC
 - flock
index 9193f25dbf0eeb1e0e56ca61bfbd6f6ae0641705..2cbfc1fcc59491234cf104998f2f61c8de7ce1b6 100644 (file)
@@ -693,12 +693,10 @@ struct ceph_mds_session_head {
  */
 #define CEPH_MDS_OP_WRITE        0x001000
 #define CEPH_MDS_OP_FOLLOW_LINK  0x010000
-#define CEPH_MDS_OP_INO_PATH     0x100000
 enum {
-       CEPH_MDS_OP_FINDINODE  = 0x100100,
-
        CEPH_MDS_OP_LOOKUP     = 0x00100,
        CEPH_MDS_OP_GETATTR    = 0x00101,
+       CEPH_MDS_OP_LOOKUPHASH = 0x00102,
        CEPH_MDS_OP_SETXATTR   = 0x01105,
        CEPH_MDS_OP_RMXATTR    = 0x01106,
        CEPH_MDS_OP_SETLAYOUT  = 0x01107,
@@ -723,8 +721,8 @@ enum {
 static inline const char *ceph_mds_op_name(int op)
 {
        switch (op) {
-       case CEPH_MDS_OP_FINDINODE: return "findinode";
        case CEPH_MDS_OP_LOOKUP:  return "lookup";
+       case CEPH_MDS_OP_LOOKUPHASH:  return "lookuphash";
        case CEPH_MDS_OP_GETATTR:  return "getattr";
        case CEPH_MDS_OP_SETXATTR: return "setxattr";
        case CEPH_MDS_OP_SETATTR: return "setattr";
index 10a892bc39ac8897298f61c2ee6762b3373734e5..97f637e430196945d7c8df35754d2528dc15747a 100644 (file)
@@ -300,8 +300,7 @@ static int mdsc_show(struct seq_file *s, void *p)
                                seq_printf(s, " %s", path);
                                kfree(path);
                        }
-               } else if (req->r_path2 &&
-                          req->r_op != CEPH_MDS_OP_FINDINODE) {
+               } else if (req->r_path2) {
                        seq_printf(s, " %s", req->r_path2);
                }
 
index ffc06d05fd5f1bae4f0ddf191439b0d891844c29..ba09cbcbd63c1692785df61221e7bc0248dfa46d 100644 (file)
@@ -81,7 +81,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
        if (!inode) {
                struct ceph_mds_request *req;
                derr(10, "fh_to_dentry %llx.%x -- no inode\n", vino.ino, hash);
-               req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_FINDINODE,
+               req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPHASH,
                                               USE_ANY_MDS);
                if (IS_ERR(req))
                        return ERR_PTR(PTR_ERR(req));
index b9a2641894318cae101f368a347bfea5b5987e8d..fb0b8b72a7f565938c61ad5032e138466193855f 100644 (file)
@@ -1006,52 +1006,45 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
        int pathlen;
        int freepath1 = 0, freepath2 = 0;
        void *p, *end;
-       u32 fhlen = 0;
 
-       if (req->r_op == CEPH_MDS_OP_FINDINODE) {
-               fhlen = *(int *)req->r_path2;
-               path2 = NULL;
-               pathlen = sizeof(u32) + fhlen*sizeof(struct ceph_inopath_item);
-       } else {
-               if (req->r_inode) {
-                       freepath1 = build_inode_path(req->r_inode, &path1,
-                                                    &pathlen1, &ino1);
-                       dout(10, "create_request_message inode %p %llx.%llx\n",
-                            req->r_inode, ceph_ino(req->r_inode),
-                            ceph_snap(req->r_inode));
-               } else if (req->r_dentry) {
-                       freepath1 = build_dentry_path(req->r_dentry, &path1,
-                                                     &pathlen1, &ino1);
-                       dout(10, "create_request_message dentry %p %llx/%.*s\n",
-                            req->r_dentry, ino1, pathlen1, path1);
-               } else if (path1) {
-                       pathlen1 = strlen(path1);
-                       dout(10, "create_request_message path1 %.*s\n",
-                            pathlen1, path1);
-               }
-               if (freepath1 < 0) {
-                       msg = ERR_PTR(freepath1);
-                       goto out;
-               }
+       if (req->r_inode) {
+               freepath1 = build_inode_path(req->r_inode, &path1,
+                                            &pathlen1, &ino1);
+               dout(10, "create_request_message inode %p %llx.%llx\n",
+                    req->r_inode, ceph_ino(req->r_inode),
+                    ceph_snap(req->r_inode));
+       } else if (req->r_dentry) {
+               freepath1 = build_dentry_path(req->r_dentry, &path1,
+                                             &pathlen1, &ino1);
+               dout(10, "create_request_message dentry %p %llx/%.*s\n",
+                    req->r_dentry, ino1, pathlen1, path1);
+       } else if (path1) {
+               pathlen1 = strlen(path1);
+               dout(10, "create_request_message path1 %.*s\n",
+                    pathlen1, path1);
+       }
+       if (freepath1 < 0) {
+               msg = ERR_PTR(freepath1);
+               goto out;
+       }
 
-               if (req->r_old_dentry) {
-                       freepath2 = build_dentry_path(req->r_old_dentry, &path2,
-                                                     &pathlen2, &ino2);
-                       dout(10, "create_request_message dentry %p %llx/%.*s\n",
-                            req->r_old_dentry, ino2, pathlen2, path2);
-                       if (freepath2 < 0) {
-                               msg = ERR_PTR(freepath2);
-                               goto out_free1;
-                       }
-               } else if (path2) {
-                       pathlen2 = strlen(path2);
-                       dout(10, "create_request_message path2 %.*s\n",
-                            pathlen2, path2);
+       if (req->r_old_dentry) {
+               freepath2 = build_dentry_path(req->r_old_dentry, &path2,
+                                             &pathlen2, &ino2);
+               dout(10, "create_request_message dentry %p %llx/%.*s\n",
+                    req->r_old_dentry, ino2, pathlen2, path2);
+               if (freepath2 < 0) {
+                       msg = ERR_PTR(freepath2);
+                       goto out_free1;
                }
-
-               pathlen = pathlen1 + pathlen2 + 2*(sizeof(u32) + sizeof(u64));
+       } else if (path2) {
+               pathlen2 = strlen(path2);
+               dout(10, "create_request_message path2 %.*s\n",
+                    pathlen2, path2);
        }
 
+       pathlen = pathlen1 + pathlen2 + 2*(sizeof(u32) + sizeof(u64));
+
        msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, sizeof(*head) + pathlen,
                           0, 0, NULL);
        if (IS_ERR(msg))
@@ -1074,14 +1067,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
 #endif
        head->args = req->r_args;
 
-       if (req->r_op == CEPH_MDS_OP_FINDINODE) {
-               ceph_encode_32(&p, fhlen);
-               memcpy(p, path1, fhlen * sizeof(struct ceph_inopath_item));
-               p += fhlen * sizeof(struct ceph_inopath_item);
-       } else {
-               ceph_encode_filepath(&p, end, ino1, path1);
-               ceph_encode_filepath(&p, end, ino2, path2);
-       }
+       ceph_encode_filepath(&p, end, ino1, path1);
+       ceph_encode_filepath(&p, end, ino2, path2);
 
        BUG_ON(p != end);
 
index ab7b7f09b444f762727e66731fbf8af22abd8e94..1782897ba57804df74367be3994aa12e72942187 100644 (file)
@@ -5820,76 +5820,6 @@ bool MDCache::path_is_mine(filepath& path)
 
 
 
-int MDCache::inopath_traverse(MDRequest *mdr, vector<ceph_inopath_item> &inopath)
-{
-  dout(10) << "inopath_traverse mdr " << *mdr << " inopath " << inopath << dendl;
-  
-  // find first...
-  int i;
-  CInode *cur = 0;
-  for (i=0; i<(int)inopath.size(); i++) {
-    cur = get_inode(inodeno_t(inopath[i].ino));
-    if (cur) break;
-    dout(10) << " don't have " << inopath[i].ino << dendl;
-  }
-  if (!cur)
-    return -ESTALE;
-
-  if (i == 0) {
-    dout(10) << " found " << *cur << dendl;
-    mdr->pin(cur);
-    mdr->ref = cur;
-    return 0;  // yay
-  }
-
-  dout(10) << " have ancestor " << *cur << dendl;
-
-  // load up subdir
-  if (!cur->is_dir())
-    return -ENOTDIR;
-  
-  frag_t fg = cur->dirfragtree[inopath[i].dname_hash];
-  dout(10) << " hash " << inopath[i].dname_hash << " is frag " << fg << dendl;
-
-  CDir *curdir = cur->get_dirfrag(fg);
-  if (!curdir) {
-    if (cur->is_auth()) {
-      // parent dir frozen_dir?
-      if (cur->is_frozen_dir()) {
-       dout(7) << "inopath_traverse: " << *cur->get_parent_dir() << " is frozen_dir, waiting" << dendl;
-       cur->get_parent_dn()->get_dir()->add_waiter(CDir::WAIT_UNFREEZE, _get_waiter(mdr, 0));
-       return 1;
-      }
-      curdir = cur->get_or_open_dirfrag(this, fg);
-    } else {
-      open_remote_dirfrag(cur, fg, _get_waiter(mdr, 0));
-      return 1;
-    }
-  }
-  assert(curdir);
-
-  // forward to dir auth?
-  if (!curdir->is_auth()) {
-    if (curdir->is_ambiguous_auth()) {
-      // wait
-      dout(7) << "traverse: waiting for single auth in " << *curdir << dendl;
-      curdir->add_waiter(CDir::WAIT_SINGLEAUTH, _get_waiter(mdr, 0));
-      return 1;
-    } 
-    request_forward(mdr, curdir->authority().first);
-    return 2;
-  }
-
-  if (curdir->is_complete())
-    return -ESTALE;  // give up? :(  we _could_ try other frags...
-
-  touch_inode(cur);
-  curdir->fetch(_get_waiter(mdr, 0));
-  return 1;
-}
-
-
-
 /**
  * path_traverse_to_dir -- traverse to deepest dir we have
  *
index a7bd66014691a2ee610bc5fedcbe30b8769d9d23..809d86963d7a94514cee9d9ac2abca6df1c0c579 100644 (file)
@@ -897,8 +897,6 @@ public:
   }
   CDir *path_traverse_to_dir(filepath& path);
 
-  int inopath_traverse(MDRequest *mdr, vector<ceph_inopath_item>& inopath);
-  
   void open_remote_dirfrag(CInode *diri, frag_t fg, Context *fin);
   CInode *get_dentry_inode(CDentry *dn, MDRequest *mdr, bool projected=false);
   void open_remote_ino(inodeno_t ino, Context *fin, inodeno_t hadino=0, version_t hadv=0);
index 46d1662fa9f65f7e4f083b515f4d96e679dc3278..3bc6071fa008ba295d7c6b28feb48159b42e72d2 100644 (file)
@@ -852,8 +852,8 @@ void Server::dispatch_client_request(MDRequest *mdr)
   assert(mdr->more()->waiting_on_slave.empty());
   
   switch (req->get_op()) {
-  case CEPH_MDS_OP_FINDINODE:
-    handle_client_findinode(mdr);
+  case CEPH_MDS_OP_LOOKUPHASH:
+    handle_client_lookup_hash(mdr);
     break;
 
     // inodes ops.
@@ -1759,15 +1759,43 @@ void Server::handle_client_stat(MDRequest *mdr)
 }
 
 
-void Server::handle_client_findinode(MDRequest *mdr)
+void Server::handle_client_lookup_hash(MDRequest *mdr)
 {
   MClientRequest *req = mdr->client_request;
-  int r = mdcache->inopath_traverse(mdr, req->inopath);
-  if (r > 0)
-    return; // delayed
-  dout(10) << "reply to findinode on " << *mdr->ref << dendl;
-  MClientReply *reply = new MClientReply(req, r);
-  reply_request(mdr, reply);
+
+  CInode *in = mdcache->get_inode(req->get_filepath().get_ino());
+  if (!in) {
+    // try the directory
+    CInode *diri = mdcache->get_inode(req->get_filepath2().get_ino());
+    if (!diri) {
+      reply_request(mdr, -ESTALE);
+      return;
+    }
+    unsigned hash = atoi(req->get_filepath2()[0].c_str());
+    frag_t fg = diri->dirfragtree[hash];
+    CDir *dir = diri->get_or_open_dirfrag(mdcache, fg);
+    assert(dir);
+    if (!dir->is_auth()) {
+      if (dir->is_ambiguous_auth()) {
+       // wait
+       dout(7) << " waiting for single auth in " << *dir << dendl;
+       dir->add_waiter(CDir::WAIT_SINGLEAUTH, new C_MDS_RetryRequest(mdcache, mdr));
+       return;
+      } 
+      mdcache->request_forward(mdr, dir->authority().first);
+      return;
+    }
+    if (!dir->is_complete()) {
+      dir->fetch(0, new C_MDS_RetryRequest(mdcache, mdr));
+      return;
+    }
+    reply_request(mdr, -ESTALE);
+    return;
+  }
+
+  dout(10) << "reply to lookup_hash on " << *in << dendl;
+  MClientReply *reply = new MClientReply(req, 0);
+  reply_request(mdr, reply, in, in->get_parent_dn());
 }
 
 
index 6f81432bf7e8c4e30b656ea233096cffe639e74f..efe2d56ce90816279c79aa61d8c2ddb77911dd82 100644 (file)
@@ -117,7 +117,7 @@ public:
 
   // requests on existing inodes.
   void handle_client_stat(MDRequest *mdr);
-  void handle_client_findinode(MDRequest *mdr);
+  void handle_client_lookup_hash(MDRequest *mdr);
   void handle_client_readdir(MDRequest *mdr);
 
   void handle_client_setattr(MDRequest *mdr);
index 4e9705b9c495e0c41b2b192a091f7a8eccf79d49..04996da05405bf08ec424db0388ef8a20b0eaa86 100644 (file)
 
 // metadata ops.
 
-static inline ostream& operator<<(ostream &out, const ceph_inopath_item &i) {
-  return out << i.ino << "." << i.dname_hash;
-}
-
 class MClientRequest : public Message {
 public:
   struct ceph_mds_request_head head;
 
   // path arguments
   filepath path, path2;
-  vector<ceph_inopath_item> inopath;
 
  public:
   // cons
@@ -139,22 +134,14 @@ public:
   void decode_payload() {
     bufferlist::iterator p = payload.begin();
     ::decode(head, p);
-    if (head.op == CEPH_MDS_OP_FINDINODE) {
-      ::decode(inopath, p);
-    } else {
-      ::decode(path, p);
-      ::decode(path2, p);
-    }
+    ::decode(path, p);
+    ::decode(path2, p);
   }
 
   void encode_payload() {
     ::encode(head, payload);
-    if (head.op == CEPH_MDS_OP_FINDINODE) {
-      ::encode(inopath, payload);
-    } else {
-      ::encode(path, payload);
-      ::encode(path2, payload);
-    }
+    ::encode(path, payload);
+    ::encode(path2, payload);
   }
 
   const char *get_type_name() { return "creq"; }
@@ -166,8 +153,6 @@ public:
     out << " " << get_filepath();
     if (!get_filepath2().empty())
       out << " " << get_filepath2();
-    if (!inopath.empty())
-      out << " " << inopath;
     if (head.retry_attempt)
       out << " RETRY=" << head.retry_attempt;
     out << ")";