]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: do not purge strays with snapped references/past parents
authorSage Weil <sage@newdream.net>
Thu, 7 Aug 2008 18:20:08 +0000 (11:20 -0700)
committerSage Weil <sage@newdream.net>
Thu, 7 Aug 2008 18:20:08 +0000 (11:20 -0700)
src/mds/MDCache.cc
src/mds/snap.cc
src/mds/snap.h

index 0d98830981ffabcc458d9a7db3ede0c6b8563973..fec86014db488fe972686263def9ffaffc7f85bb 100644 (file)
@@ -6235,6 +6235,15 @@ void MDCache::_snaprealm_create_finish(MDRequest *mdr, Mutation *mut, CInode *in
 // -------------------------------------------------------------------------------
 // STRAYS
 
+struct C_MDC_EvalStray : public Context {
+  MDCache *mdcache;
+  CDentry *dn;
+  C_MDC_EvalStray(MDCache *c, CDentry *d) : mdcache(c), dn(d) {}
+  void finish(int r) {
+    mdcache->eval_stray(dn);
+  }
+};
+
 void MDCache::eval_stray(CDentry *dn)
 {
   dout(10) << "eval_stray " << *dn << dendl;
@@ -6247,6 +6256,14 @@ void MDCache::eval_stray(CDentry *dn)
 
   // purge?
   if (in->inode.nlink == 0) {
+    // past snaprealm parents imply snapped dentry remote links
+    if (in->snaprealm && in->snaprealm->has_past_parents()) {
+      if (!in->snaprealm->have_past_parents_open() &&
+         !in->snaprealm->open_parents(new C_MDC_EvalStray(this, dn)))
+       return;
+      in->snaprealm->prune_past_parents();
+      if (in->snaprealm->has_past_parents()) return;  // not until some snaps are deleted.
+    }
     if (dn->is_replicated() || in->is_any_caps()) return;  // wait
     if (!in->dirfrags.empty()) return;  // wait for dirs to close/trim
     _purge_stray(dn);
index ff9a1006966d741b2dca9bb60b33896deb162b2c..856027ed22bb26925664f2fc56ed7b7b80afb777 100644 (file)
@@ -480,3 +480,25 @@ void SnapRealm::add_past_parent(SnapRealm *oldparent)
 
   invalidate_cached_snaps();
 }
+
+void SnapRealm::prune_past_parents()
+{
+  dout(10) << "prune_past_parents" << dendl;
+  check_cache();
+  assert(open);
+
+  map<snapid_t, snaplink_t>::iterator p = past_parents.begin();
+  while (p != past_parents.end()) {
+    set<snapid_t>::iterator q = cached_snaps.lower_bound(p->second.first);
+    if (q == cached_snaps.end() ||
+       *q > p->first) {
+      dout(10) << "prune_past_parents pruning [" << p->second.first << "," << p->first 
+              << "] " << p->second.ino << dendl;
+      past_parents.erase(p++);
+    } else {
+      dout(10) << "prune_past_parents keeping [" << p->second.first << "," << p->first 
+              << "] " << p->second.ino << dendl;
+      p++;
+    }
+  }
+}
index b37349b92f466d03ba6d632da6280c07415b69e0..2e701b412598ba75ca64404bc3fdad3f45649b96 100644 (file)
@@ -157,6 +157,8 @@ struct SnapRealm {
 
   void project_past_parent(SnapRealm *newparent, bufferlist& snapbl);
   void add_past_parent(SnapRealm *oldparent);
+  void prune_past_parents();
+  bool has_past_parents() { return !past_parents.empty(); }
 
   void build_snap_set(set<snapid_t>& s, 
                      snapid_t& max_seq, snapid_t& max_last_created, snapid_t& max_last_destroyed,