]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: skip purge_stray when stray pins are present
authorSage Weil <sage@newdream.net>
Fri, 26 Mar 2010 18:56:34 +0000 (11:56 -0700)
committerSage Weil <sage@newdream.net>
Fri, 26 Mar 2010 19:32:01 +0000 (12:32 -0700)
Otherwise we can get into a loop:

 eval_stray
 purge_stray
 _purge_stray_purged
  journal truncate
 eval_stray
 ...

This doesn't explain what the stray pin was that I saw, but it at least
avoids the looping.

src/mds/MDCache.cc

index b83ef5fc028c8ab7090b52fc93bcb16d7bb4236f..26401a594f663015fced20b2426df6081d8660ae 100644 (file)
@@ -6886,6 +6886,9 @@ void MDCache::eval_stray(CDentry *dn)
     if (dn->state_test(CDentry::STATE_PURGING)) return;  // already purging
     if (in->state_test(CInode::STATE_NEEDSRECOVER) ||
        in->state_test(CInode::STATE_RECOVERING)) return;  // don't mess with file size probing
+    if (in->get_num_ref() > (int)in->is_dirty() ||
+       dn->get_num_ref() > (int)dn->is_dirty())
+      return;                                            // stray dn or inode pins
     purge_stray(dn);
   }
   else if (in->inode.nlink == 1) {
@@ -7012,7 +7015,8 @@ void MDCache::_purge_stray_purged(CDentry *dn)
   CInode *in = dn->get_projected_linkage()->get_inode();
   dout(10) << "_purge_stray_purged " << *dn << " " << *in << dendl;
 
-  if (in->get_num_ref() == (int)in->is_dirty()) {
+  if (in->get_num_ref() == (int)in->is_dirty() &&
+      dn->get_num_ref() == (int)dn->is_dirty()) {
     // kill dentry.
     version_t pdv = dn->pre_dirty();