]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: optimize get_projected_{xattrs,srnode}
authorYan, Zheng <zyan@redhat.com>
Sat, 24 Jan 2015 03:10:38 +0000 (11:10 +0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 25 Feb 2015 12:51:19 +0000 (20:51 +0800)
these two functions traverse the whole projected_nodes list if there
is no projected xatts/srnode. busy directory inode can have large
projected_nodes list.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/CInode.cc
src/mds/CInode.h

index d87c11d0df3f3f6cd38e6099185ab0f45f4ef506..ce7a229563c43ee7f8f5a5d10e4522a17e6c648c 100644 (file)
@@ -347,7 +347,10 @@ inode_t *CInode::project_inode(map<string,bufferptr> *px)
     if (px)
       *px = *get_projected_xattrs();
   }
-  projected_nodes.back()->xattrs = px;
+  if (px) {
+    projected_nodes.back()->xattrs = px;
+    ++num_projected_xattrs;
+  }
   dout(15) << "project_inode " << projected_nodes.back()->inode << dendl;
   return projected_nodes.back()->inode;
 }
@@ -367,12 +370,15 @@ void CInode::pop_and_dirty_projected_inode(LogSegment *ls)
 
   map<string,bufferptr> *px = projected_nodes.front()->xattrs;
   if (px) {
+    --num_projected_xattrs;
     xattrs = *px;
     delete px;
   }
 
-  if (projected_nodes.front()->snapnode)
+  if (projected_nodes.front()->snapnode) {
     pop_projected_snaprealm(projected_nodes.front()->snapnode);
+    --num_projected_srnodes;
+  }
 
   delete projected_nodes.front()->inode;
   delete projected_nodes.front();
@@ -394,6 +400,7 @@ sr_t *CInode::project_snaprealm(snapid_t snapid)
   }
   dout(10) << "project_snaprealm " << new_srnode << dendl;
   projected_nodes.back()->snapnode = new_srnode;
+  ++num_projected_srnodes;
   return new_srnode;
 }
 
index 1dfa26f3cedee5493f623504221f18270f477caf..e13e80e075c0b73d3cbe6b3f1d73e8dfb43b5149 100644 (file)
@@ -287,6 +287,8 @@ public:
       : inode(in), xattrs(xp), snapnode(sn) {}
   };
   std::list<projected_inode_t*> projected_nodes;   // projected values (only defined while dirty)
+  int num_projected_xattrs;
+  int num_projected_srnodes;
   
   inode_t *project_inode(std::map<std::string,bufferptr> *px=0);
   void pop_and_dirty_projected_inode(LogSegment *ls);
@@ -331,11 +333,13 @@ public:
   }
 
   std::map<std::string,bufferptr> *get_projected_xattrs() {
-    for (std::list<projected_inode_t*>::reverse_iterator p = projected_nodes.rbegin();
-        p != projected_nodes.rend();
-        ++p)
-      if ((*p)->xattrs)
-       return (*p)->xattrs;
+    if (num_projected_xattrs > 0) {
+      for (std::list<projected_inode_t*>::reverse_iterator p = projected_nodes.rbegin();
+          p != projected_nodes.rend();
+          ++p)
+       if ((*p)->xattrs)
+         return (*p)->xattrs;
+    }
     return &xattrs;
   }
   std::map<std::string,bufferptr> *get_previous_projected_xattrs() {
@@ -350,34 +354,30 @@ public:
 
   sr_t *project_snaprealm(snapid_t snapid=0);
   const sr_t *get_projected_srnode() const {
-    if (projected_nodes.empty()) {
-      if (snaprealm)
-       return &snaprealm->srnode;
-      else
-       return NULL;
-    } else {
+    if (num_projected_srnodes > 0) {
       for (std::list<projected_inode_t*>::const_reverse_iterator p = projected_nodes.rbegin();
-          p != projected_nodes.rend();
-          ++p)
-        if ((*p)->snapnode)
-          return (*p)->snapnode;
+         p != projected_nodes.rend();
+         ++p)
+       if ((*p)->snapnode)
+         return (*p)->snapnode;
     }
-    return &snaprealm->srnode;
+    if (snaprealm)
+      return &snaprealm->srnode;
+    else
+      return NULL;
   }
   sr_t *get_projected_srnode() {
-    if (projected_nodes.empty()) {
-      if (snaprealm)
-       return &snaprealm->srnode;
-      else
-       return NULL;
-    } else {
+    if (num_projected_srnodes > 0) {
       for (std::list<projected_inode_t*>::reverse_iterator p = projected_nodes.rbegin();
-          p != projected_nodes.rend();
-          ++p)
-        if ((*p)->snapnode)
-          return (*p)->snapnode;
+          p != projected_nodes.rend();
+          ++p)
+       if ((*p)->snapnode)
+         return (*p)->snapnode;
     }
-    return &snaprealm->srnode;
+    if (snaprealm)
+      return &snaprealm->srnode;
+    else
+      return NULL;
   }
   void project_past_snaprealm_parent(SnapRealm *newparent);
 
@@ -538,6 +538,8 @@ public:
     first(f), last(l),
     last_journaled(0), //last_open_journaled(0), 
     //hack_accessed(true),
+    num_projected_xattrs(0),
+    num_projected_srnodes(0),
     stickydir_ref(0),
     parent(0),
     inode_auth(CDIR_AUTH_DEFAULT),
@@ -573,6 +575,8 @@ public:
     close_dirfrags();
     close_snaprealm();
     clear_file_locks();
+    assert(num_projected_xattrs == 0);
+    assert(num_projected_srnodes == 0);
   }