]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: mark and pin dentries while purging, so they don't get trimmed out from under us
authorSage Weil <sage@newdream.net>
Fri, 14 Nov 2008 22:31:24 +0000 (14:31 -0800)
committerSage Weil <sage@newdream.net>
Fri, 14 Nov 2008 22:31:24 +0000 (14:31 -0800)
Aslo avoid purging more than once.

Previously it was possible to drop the dentry from the cache while
it was being purged.

src/mds/CDentry.h
src/mds/MDCache.cc

index 9bda79ddc7aeaac386cb08cbd29b9f4e588f6263..274651f028bfd80dedf90cde957cfe3742d5d82f 100644 (file)
@@ -51,14 +51,17 @@ class CDentry : public MDSCacheObject, public LRUObject {
   // -- state --
   static const int STATE_NEW = 1;
   static const int STATE_FRAGMENTING = 2;
+  static const int STATE_PURGING = 3;
 
   // -- pins --
   static const int PIN_INODEPIN =     1;  // linked inode is pinned
   static const int PIN_FRAGMENTING = -2;  // containing dir is refragmenting
+  static const int PIN_PURGING =      3;
   const char *pin_name(int p) {
     switch (p) {
     case PIN_INODEPIN: return "inodepin";
     case PIN_FRAGMENTING: return "fragmenting";
+    case PIN_PURGING: return "purging";
     default: return generic_pin_name(p);
     }
   };
index 3326b5e4808e165a28ee0cc346e99eccbce7273e..d267290a3c73c64a389abd20226cb79695f29923 100644 (file)
@@ -6334,6 +6334,7 @@ void MDCache::eval_stray(CDentry *dn)
     }
     if (dn->is_replicated() || in->is_any_caps()) return;  // wait
     if (!in->dirfrags.empty()) return;  // wait for dirs to close/trim
+    if (dn->state_test(CDentry::STATE_PURGING)) return;  // already purging
     _purge_stray(dn);
   }
   else if (in->inode.nlink == 1) {
@@ -6394,9 +6395,9 @@ void MDCache::_purge_stray(CDentry *dn)
   le->metablob.add_null_dentry(dn, true);
   le->metablob.add_inode_truncate(dn->inode->ino(), 0, dn->inode->inode.size);
 
+  dn->state_set(CDentry::STATE_PURGING);
+  dn->get(CDentry::PIN_PURGING);
   mds->mdlog->submit_entry(le, new C_MDC_PurgeStray(this, dn, pdv, mds->mdlog->get_current_segment()));
-
-
 }
 
 void MDCache::_purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *ls)
@@ -6405,6 +6406,8 @@ void MDCache::_purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *ls)
   CInode *in = dn->inode;
   
   // dirty+unlink dentry
+  dn->state_clear(CDentry::STATE_PURGING);
+  dn->put(CDentry::PIN_PURGING);
   dn->dir->mark_dirty(pdv, ls);
   dn->dir->unlink_inode(dn);
   dn->dir->remove_dentry(dn);