From 28d2b20df3981b10d62c8c1f905e937b5ab7dc57 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Tue, 8 Aug 2017 20:35:51 +0800 Subject: [PATCH] mds: trim non-auth snap dentry during cache rejoin Because corresponding dentry in auth mds may have been pruned (snap deleted) Signed-off-by: "Yan, Zheng" --- src/mds/CInode.cc | 1 + src/mds/MDCache.cc | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 4ba7a6f12f840..f4a20105caf00 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -2833,6 +2833,7 @@ void CInode::choose_lock_states(int dirty_caps) Capability *CInode::add_client_cap(client_t client, Session *session, SnapRealm *conrealm) { + assert(last == CEPH_NOSNAP); if (client_caps.empty()) { get(PIN_CAPS); if (conrealm) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 20aaae2395c99..1e4f89e263891 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -4169,6 +4169,7 @@ void MDCache::rejoin_walk(CDir *dir, MMDSCacheRejoin *rejoin) p != dir->items.end(); ++p) { CDentry *dn = p->second; + assert(dn->last == CEPH_NOSNAP); CDentry::linkage_t *dnl = dn->get_linkage(); dout(15) << " add_weak_primary_dentry " << *dn << dendl; assert(dnl->is_primary()); @@ -4188,10 +4189,39 @@ void MDCache::rejoin_walk(CDir *dir, MMDSCacheRejoin *rejoin) dir->state_set(CDir::STATE_REJOINING); for (CDir::map_t::iterator p = dir->items.begin(); - p != dir->items.end(); - ++p) { + p != dir->items.end(); ) { CDentry *dn = p->second; + ++p; + dn->state_set(CDentry::STATE_REJOINING); CDentry::linkage_t *dnl = dn->get_linkage(); + CInode *in = dnl->is_primary() ? dnl->get_inode() : NULL; + + // trim snap dentries. because they may have been pruned by + // their auth mds (snap deleted) + if (dn->last != CEPH_NOSNAP) { + if (in && !in->remote_parents.empty()) { + // unlink any stale remote snap dentry. + for (compact_set::iterator q = in->remote_parents.begin(); + q != in->remote_parents.end(); ) { + CDentry *remote_dn = *q; + ++q; + assert(remote_dn->last != CEPH_NOSNAP); + remote_dn->unlink_remote(remote_dn->get_linkage()); + } + } + if (dn->lru_is_expireable()) { + if (!dnl->is_null()) + dir->unlink_inode(dn, false); + if (in) + remove_inode(in); + dir->remove_dentry(dn); + continue; + } else { + // Inventing null/remote dentry shouldn't cause problem + assert(!dnl->is_primary()); + } + } + dout(15) << " add_strong_dentry " << *dn << dendl; rejoin->add_strong_dentry(dir->dirfrag(), dn->name, dn->first, dn->last, dnl->is_primary() ? dnl->get_inode()->ino():inodeno_t(0), -- 2.39.5