From e54851f3d1c2affb323f5d5d6ec6b73f62e5bd13 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 7 Aug 2008 11:20:08 -0700 Subject: [PATCH] mds: do not purge strays with snapped references/past parents --- src/mds/MDCache.cc | 17 +++++++++++++++++ src/mds/snap.cc | 22 ++++++++++++++++++++++ src/mds/snap.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 0d98830981ffa..fec86014db488 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -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); diff --git a/src/mds/snap.cc b/src/mds/snap.cc index ff9a1006966d7..856027ed22bb2 100644 --- a/src/mds/snap.cc +++ b/src/mds/snap.cc @@ -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::iterator p = past_parents.begin(); + while (p != past_parents.end()) { + set::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++; + } + } +} diff --git a/src/mds/snap.h b/src/mds/snap.h index b37349b92f466..2e701b412598b 100644 --- a/src/mds/snap.h +++ b/src/mds/snap.h @@ -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& s, snapid_t& max_seq, snapid_t& max_last_created, snapid_t& max_last_destroyed, -- 2.39.5