]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mds: trim non-auth snap dentry during cache rejoin
authorYan, Zheng <zyan@redhat.com>
Tue, 8 Aug 2017 12:35:51 +0000 (20:35 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 4 Dec 2017 04:02:54 +0000 (12:02 +0800)
Because corresponding dentry in auth mds may have been pruned (snap deleted)

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/CInode.cc
src/mds/MDCache.cc

index 4ba7a6f12f840a6dc06af2e018d9b62ba356f1f8..f4a20105caf00933420f924a5025559f8609720f 100644 (file)
@@ -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)
index 20aaae2395c9909b6f48ea142be9d5ee0c836aac..1e4f89e26389194fe9509ce8b22edd3d0453c80b 100644 (file)
@@ -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<CDentry*>::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),