]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: only parse readdir result once
authorSage Weil <sage@newdream.net>
Mon, 13 Sep 2010 16:47:51 +0000 (09:47 -0700)
committerSage Weil <sage@newdream.net>
Mon, 13 Sep 2010 16:47:51 +0000 (09:47 -0700)
..when inserting into the cache.  Set up our result cache at the same time.

src/client/Client.cc
src/client/Client.h

index 7ad0dd401454b177ee86df1b8e22d3925b98867e..aaea7ae65609a462120d6edc12970b217779bbd3 100644 (file)
@@ -698,6 +698,7 @@ Inode* Client::insert_trace(MetaRequest *request, utime_t from, int mds)
   }
 
   // insert readdir results too
+  request->readdir_result.clear();
 
   // the rest?
   p = reply->get_extra_bl().begin();
@@ -714,6 +715,11 @@ Inode* Client::insert_trace(MetaRequest *request, utime_t from, int mds)
     ::decode(end, p);
     ::decode(complete, p);
     
+    dout(10) << " " << numdn << " items end=" << end << dendl;
+
+    request->readdir_end = end;
+    request->readdir_num = numdn;
+
     string dname;
     LeaseStat dlease;
     while (numdn) {
@@ -724,8 +730,16 @@ Inode* Client::insert_trace(MetaRequest *request, utime_t from, int mds)
       Inode *in = add_update_inode(&ist, from, mds);
       insert_dentry_inode(dir, dname, &dlease, in, from, mds);
       
+      // add to cached result list
+      struct stat st;
+      int stmask = fill_stat(in, &st);  
+      request->readdir_result.push_back(DirEntry(dname, st, stmask));
+
+      dout(15) << "  '" << dname << "' -> " << in->ino << dendl;
+
       numdn--;
     }
+    request->readdir_last_name = dname;
     
     if (dir->is_empty())
       close_dir(dir);
@@ -3935,47 +3949,20 @@ int Client::_readdir_get_frag(DirResult *dirp)
 
     delete dirp->buffer;
     dirp->buffer = new vector<DirEntry>;
+    dirp->buffer->swap(req->readdir_result);
     dirp->buffer_frag = fg;
 
-    // the rest?
-    bufferlist::iterator p = dirbl.begin();
-    assert(!p.end());
-
-    // dirstat
-    DirStat dst(p);
-    __u32 numdn;
-    __u8 complete, end;
-    ::decode(numdn, p);
-    ::decode(end, p);
-    ::decode(complete, p);
-
-    string dname;
-    LeaseStat dlease;
-    for (unsigned i=0; i<numdn; i++) {
-      ::decode(dname, p);
-      ::decode(dlease, p);
-      InodeStat ist(p);
-      
-      Inode *in = _ll_get_inode(ist.vino);
-      dout(15) << "_readdir_get_frag " << dirp << "    " << dname << " to " << in->ino << dendl;
-
-      // add to cached result list
-      struct stat st;
-      int stmask = fill_stat(in, &st);  
-      dirp->buffer->push_back(DirEntry(dname, st, stmask));
-    }
-
     dirp->this_offset = dirp->next_offset;
     dout(10) << "_readdir_get_frag " << dirp << " got frag " << dirp->buffer_frag
             << " this_offset " << dirp->this_offset
             << " size " << dirp->buffer->size() << dendl;
 
-    if (end) {
+    if (req->readdir_end) {
       dirp->last_name.clear();
       dirp->next_offset = 2;
     } else {
-      dirp->last_name = dname;
-      dirp->next_offset += numdn;
+      dirp->last_name = req->readdir_last_name;
+      dirp->next_offset += req->readdir_num;
     }
   } else {
     dout(10) << "_readdir_get_frag got error " << res << ", setting end flag" << dendl;
index 8495b82ffd3c7feba267aab8e9673fa12f636770..3f2dade9884aca74ae245a8ea3a7d28a88acb6fc 100644 (file)
@@ -94,6 +94,15 @@ struct InodeCap;
 class Inode;
 class Dentry;
 
+/* getdir result */
+struct DirEntry {
+  string d_name;
+  struct stat st;
+  int stmask;
+  DirEntry(const string &s) : d_name(s), stmask(0) {}
+  DirEntry(const string &n, struct stat& s, int stm) : d_name(n), st(s), stmask(stm) {}
+};
+
 struct MetaRequest {
   uint64_t tid;
   ceph_mds_request_head head;
@@ -122,6 +131,12 @@ struct MetaRequest {
   MClientReply *reply;         // the reply
   bool kick;
   
+  // readdir result
+  vector<DirEntry> readdir_result;
+  bool readdir_end;
+  int readdir_num;
+  string readdir_last_name;
+
   //possible responses
   bool got_safe;
   bool got_unsafe;
@@ -673,15 +688,6 @@ struct Fh {
 class Client : public Dispatcher {
  public:
   
-  /* getdir result */
-  struct DirEntry {
-    string d_name;
-    struct stat st;
-    int stmask;
-    DirEntry(const string &s) : d_name(s), stmask(0) {}
-    DirEntry(const string &n, struct stat& s, int stm) : d_name(n), st(s), stmask(stm) {}
-  };
-
   struct DirResult {
     static const int SHIFT = 28;
     static const int64_t MASK = (1 << SHIFT) - 1;