]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: remove null clean stray dentries after dir commit
authorSage Weil <sage@newdream.net>
Tue, 6 Apr 2010 19:29:10 +0000 (12:29 -0700)
committerSage Weil <sage@newdream.net>
Tue, 6 Apr 2010 19:32:07 +0000 (12:32 -0700)
src/mds/CDir.cc

index ca8d74e20c7d0c92e80878761bfba186d6733e7d..88d6d20571f34b60b67eff82a96afc64b910a748 100644 (file)
@@ -1641,6 +1641,8 @@ void CDir::_committed(version_t v, version_t lrv)
   dout(10) << "_committed v " << v << " (last renamed " << lrv << ") on " << *this << dendl;
   assert(is_auth());
 
+  bool stray = inode->is_stray();
+
   // did we update the parent pointer too?
   if (get_frag() == frag_t() &&     // only counts on first frag
       inode->state_test(CInode::STATE_DIRTYPARENT) &&
@@ -1672,16 +1674,6 @@ void CDir::_committed(version_t v, version_t lrv)
     CDentry *dn = it->second;
     it++;
     
-    // dentry
-    if (committed_version >= dn->get_version()) {
-      if (dn->is_dirty()) {
-       dout(15) << " dir " << committed_version << " >= dn " << dn->get_version() << " now clean " << *dn << dendl;
-       dn->mark_clean();
-      } 
-    } else {
-      dout(15) << " dir " << committed_version << " < dn " << dn->get_version() << " still dirty " << *dn << dendl;
-    }
-
     // inode?
     if (dn->linkage.is_primary()) {
       CInode *in = dn->linkage.get_inode();
@@ -1698,6 +1690,22 @@ void CDir::_committed(version_t v, version_t lrv)
        assert(in->is_dirty() || in->last < CEPH_NOSNAP);  // special case for cow snap items (not predirtied)
       }
     }
+
+    // dentry
+    if (committed_version >= dn->get_version()) {
+      if (dn->is_dirty()) {
+       dout(15) << " dir " << committed_version << " >= dn " << dn->get_version() << " now clean " << *dn << dendl;
+       dn->mark_clean();
+
+       // drop clean null stray dentries immediately
+       if (stray && 
+           dn->get_num_ref() == 0 &&
+           dn->get_linkage()->is_null())
+         remove_dentry(dn);
+      } 
+    } else {
+      dout(15) << " dir " << committed_version << " < dn " << dn->get_version() << " still dirty " << *dn << dendl;
+    }
   }
 
   // finishers?