]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: maintain auth bits during replay
authorYan, Zheng <zheng.z.yan@intel.com>
Fri, 28 Mar 2014 05:30:07 +0000 (13:30 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Tue, 6 May 2014 23:10:16 +0000 (07:10 +0800)
Objects' STATE_AUTH bits are set when replaying EImportStart event.
MDCache::trim_non_auth_subtree() clear objects' STATE_AUTH bits when
replaying EExport event.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/CInode.cc
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/Migrator.cc
src/mds/Server.cc
src/mds/journal.cc

index 19f16014138ae5e270ea54afb5add3ef10adec97..3252037740470dfd07a9254f0d1a7c8f25256865 100644 (file)
@@ -572,8 +572,8 @@ CDir *CInode::get_or_open_dirfrag(MDCache *mdcache, frag_t fg)
   CDir *dir = get_dirfrag(fg);
   if (!dir) {
     // create it.
-    assert(is_auth());
-    dir = new CDir(this, fg, mdcache, true);
+    assert(is_auth() || mdcache->mds->is_any_replay());
+    dir = new CDir(this, fg, mdcache, is_auth());
     add_dirfrag(dir);
   }
   return dir;
index ba57b0e4bdd549e782c93355aa7d5c9e32e87fc3..cc2f2be3bbb94acfdd2a2f320869ee5909d6665b 100644 (file)
@@ -3045,7 +3045,7 @@ void MDCache::maybe_resolve_finish()
   finish_committed_masters();
   if (mds->is_resolve()) {
     trim_unlinked_inodes();
-    recalc_auth_bits();
+    recalc_auth_bits(false);
     mds->resolve_done();
   } else {
     maybe_send_pending_rejoins();
@@ -3409,15 +3409,19 @@ void MDCache::trim_unlinked_inodes()
  * once subtree auth is disambiguated, we need to adjust all the 
  * auth and dirty bits in our cache before moving on.
  */
-void MDCache::recalc_auth_bits()
+void MDCache::recalc_auth_bits(bool replay)
 {
-  dout(7) << "recalc_auth_bits" << dendl;
+  dout(7) << "recalc_auth_bits " << (replay ? "(replay)" : "") <<  dendl;
 
   if (root) {
     root->inode_auth.first = mds->mdsmap->get_root();
-    if (mds->whoami != root->inode_auth.first) {
+    bool auth = mds->whoami == root->inode_auth.first;
+    if (auth) {
+      root->state_set(CInode::STATE_AUTH);
+    } else {
       root->state_clear(CInode::STATE_AUTH);
-      root->state_set(CInode::STATE_REJOINING);
+      if (!replay)
+       root->state_set(CInode::STATE_REJOINING);
     }
   }
 
@@ -3432,11 +3436,16 @@ void MDCache::recalc_auth_bits()
   for (map<CDir*,set<CDir*> >::iterator p = subtrees.begin();
        p != subtrees.end();
        ++p) {
-
-    CInode *inode = p->first->get_inode();
-    if (inode->is_mdsdir() && inode->ino() != MDS_INO_MDSDIR(mds->get_nodeid())) {
-      inode->state_clear(CInode::STATE_AUTH);
-      inode->state_set(CInode::STATE_REJOINING);
+    if (p->first->inode->is_mdsdir()) {
+      CInode *in = p->first->inode;
+      bool auth = in->ino() == MDS_INO_MDSDIR(mds->get_nodeid());
+      if (auth) {
+       in->state_set(CInode::STATE_AUTH);
+      } else {
+       in->state_clear(CInode::STATE_AUTH);
+       if (!replay)
+         in->state_set(CInode::STATE_REJOINING);
+      }
     }
 
     list<CDir*> dfq;  // dirfrag queue
@@ -3453,16 +3462,18 @@ void MDCache::recalc_auth_bits()
       if (auth) {
        dir->state_set(CDir::STATE_AUTH);
       } else {
-       // close empty non-auth dirfrag
-       if (!dir->is_subtree_root() && dir->get_num_any() == 0) {
-         dir->inode->close_dirfrag(dir->get_frag());
-         continue;
-       }
-       dir->state_set(CDir::STATE_REJOINING);
        dir->state_clear(CDir::STATE_AUTH);
-       dir->state_clear(CDir::STATE_COMPLETE);
-       if (dir->is_dirty()) 
-         dir->mark_clean();
+       if (!replay) {
+         // close empty non-auth dirfrag
+         if (!dir->is_subtree_root() && dir->get_num_any() == 0) {
+           dir->inode->close_dirfrag(dir->get_frag());
+           continue;
+         }
+         dir->state_set(CDir::STATE_REJOINING);
+         dir->state_clear(CDir::STATE_COMPLETE);
+         if (dir->is_dirty())
+           dir->mark_clean();
+       }
       }
 
       // dentries in this dir
@@ -3472,34 +3483,38 @@ void MDCache::recalc_auth_bits()
        // dn
        CDentry *dn = q->second;
        CDentry::linkage_t *dnl = dn->get_linkage();
-       if (auth)
+       if (auth) {
          dn->state_set(CDentry::STATE_AUTH);
-       else {
-         dn->state_set(CDentry::STATE_REJOINING);
+       } else {
          dn->state_clear(CDentry::STATE_AUTH);
-         if (dn->is_dirty()) 
-           dn->mark_clean();
+         if (!replay) {
+           dn->state_set(CDentry::STATE_REJOINING);
+           if (dn->is_dirty())
+             dn->mark_clean();
+         }
        }
 
        if (dnl->is_primary()) {
          // inode
-         if (auth) 
-           dnl->get_inode()->state_set(CInode::STATE_AUTH);
-         else {
-           dnl->get_inode()->state_set(CInode::STATE_REJOINING);
-           dnl->get_inode()->state_clear(CInode::STATE_AUTH);
-           if (dnl->get_inode()->is_dirty())
-             dnl->get_inode()->mark_clean();
-           if (dnl->get_inode()->is_dirty_parent())
-             dnl->get_inode()->clear_dirty_parent();
-           // avoid touching scatterlocks for our subtree roots!
-           if (subtree_inodes.count(dnl->get_inode()) == 0)
-             dnl->get_inode()->clear_scatter_dirty();
+         CInode *in = dnl->get_inode();
+         if (auth) {
+           in->state_set(CInode::STATE_AUTH);
+         } else {
+           in->state_clear(CInode::STATE_AUTH);
+           if (!replay) {
+             in->state_set(CInode::STATE_REJOINING);
+             if (in->is_dirty())
+               in->mark_clean();
+             if (in->is_dirty_parent())
+               in->clear_dirty_parent();
+             // avoid touching scatterlocks for our subtree roots!
+             if (subtree_inodes.count(in) == 0)
+               in->clear_scatter_dirty();
+           }
          }
-
          // recurse?
-         if (dnl->get_inode()->is_dir()) 
-           dnl->get_inode()->get_nested_dirfrags(dfq);
+         if (in->is_dir())
+           in->get_nested_dirfrags(dfq);
        }
       }
     }
@@ -6738,6 +6753,8 @@ bool MDCache::trim_non_auth_subtree(CDir *dir)
         dir->remove_dentry(dn);
       } else {
         dout(20) << "trim_non_auth_subtree(" << dir << ") keeping inode " << in << " with dentry " << dn <<dendl;
+       dn->state_clear(CDentry::STATE_AUTH);
+       in->state_clear(CInode::STATE_AUTH);
       }
     } else if (keep_dir && dnl->is_null()) { // keep null dentry for slave rollback
       dout(20) << "trim_non_auth_subtree(" << dir << ") keeping dentry " << dn <<dendl;
@@ -6748,6 +6765,7 @@ bool MDCache::trim_non_auth_subtree(CDir *dir)
       dir->remove_dentry(dn);
     }
   }
+  dir->state_clear(CDir::STATE_AUTH);
   /**
    * We've now checked all our children and deleted those that need it.
    * Now return to caller, and tell them if *we're* a keeper.
index 8edeaa37d15c345f02774caaed451cb69b3dfb03..c72c7ab15b4655cce7c8f4e663cb11c1f5fb4907 100644 (file)
@@ -347,12 +347,12 @@ protected:
   void discard_delayed_resolve(int who);
   void maybe_resolve_finish();
   void disambiguate_imports();
-  void recalc_auth_bits();
   void trim_unlinked_inodes();
   void add_uncommitted_slave_update(metareqid_t reqid, int master, MDSlaveUpdate*);
   void finish_uncommitted_slave_update(metareqid_t reqid, int master);
   MDSlaveUpdate* get_uncommitted_slave_update(metareqid_t reqid, int master);
 public:
+  void recalc_auth_bits(bool replay);
   void remove_inode_recursive(CInode *in);
 
   bool is_ambiguous_slave_update(metareqid_t reqid, int master) {
index cde0f704c9244455833abb025223db1b2cae89c9..323a16afb103c37e41d41eb343f5fd4a84166b30 100644 (file)
@@ -2225,11 +2225,15 @@ void Migrator::handle_export_dir(MExportDir *m)
   
   // include bounds in EImportStart
   set<CDir*> import_bounds;
-  cache->get_subtree_bounds(dir, import_bounds);
-  for (set<CDir*>::iterator it = import_bounds.begin();
-       it != import_bounds.end();
-       ++it) 
-    le->metablob.add_dir(*it, false);  // note that parent metadata is already in the event
+  for (vector<dirfrag_t>::iterator p = m->bounds.begin();
+       p != m->bounds.end();
+       ++p) {
+    CDir *bd = cache->get_dirfrag(*p);
+    assert(bd);
+    le->metablob.add_dir(bd, false);  // note that parent metadata is already in the event
+    import_bounds.insert(bd);
+  }
+  cache->verify_subtree_bounds(dir, import_bounds);
 
   // adjust popularity
   mds->balancer->add_import(dir, now);
index c8a3ebc50cfea041fb463481824353f807a19f31..bbfdc50d9c970488a1206c85f724de030891ffcd 100644 (file)
@@ -7016,8 +7016,10 @@ void Server::_rename_rollback_finish(MutationRef& mut, MDRequestRef& mdr, CDentr
 
   mut->apply();
 
-  if (srcdn) {
+  if (srcdn && srcdn->get_linkage()->is_primary()) {
     CInode *in = srcdn->get_linkage()->get_inode();
+    if (srcdn->authority().first == mds->get_nodeid())
+      in->state_set(CInode::STATE_AUTH);
     // update subtree map?
     if (in && in->is_dir()) {
       assert(destdn);
index aad0e0e4fa3ac7f238187269327f1dd8ea6c5529..323d52699d3ddc99fdb7c91d192dad9c97e89a7a 100644 (file)
@@ -947,7 +947,7 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
     CInode *in = mds->mdcache->get_inode((*p)->inode.ino);
     bool isnew = in ? false:true;
     if (!in)
-      in = new CInode(mds->mdcache, true);
+      in = new CInode(mds->mdcache, false);
     (*p)->update_inode(mds, in);
 
     if (isnew)
@@ -993,8 +993,10 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
       // hmm.  do i have the inode?
       CInode *diri = mds->mdcache->get_inode((*lp).ino);
       if (!diri) {
-       if (MDS_INO_IS_BASE(lp->ino)) {
+       if (MDS_INO_IS_MDSDIR(lp->ino)) {
+         assert(MDS_INO_MDSDIR(mds->get_nodeid()) != lp->ino);
          diri = mds->mdcache->create_system_inode(lp->ino, S_IFDIR|0755);
+         diri->state_clear(CInode::STATE_AUTH);
          dout(10) << "EMetaBlob.replay created base " << *diri << dendl;
        } else {
          dout(0) << "EMetaBlob.replay missing dir ino  " << (*lp).ino << dendl;
@@ -1006,13 +1008,17 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
       dir = diri->get_or_open_dirfrag(mds->mdcache, (*lp).frag);
 
       if (MDS_INO_IS_BASE(lp->ino))
-       mds->mdcache->adjust_subtree_auth(dir, CDIR_AUTH_UNKNOWN);
+       mds->mdcache->adjust_subtree_auth(dir, CDIR_AUTH_UNDEF);
 
       dout(10) << "EMetaBlob.replay added dir " << *dir << dendl;  
     }
     dir->set_version( lump.fnode.version );
     dir->fnode = lump.fnode;
 
+    if (lump.is_importing()) {
+      dir->state_set(CDir::STATE_AUTH);
+      dir->state_clear(CDir::STATE_COMPLETE);
+    }
     if (lump.is_dirty()) {
       dir->_mark_dirty(logseg);
 
@@ -1041,8 +1047,6 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
       dir->mark_new(logseg);
     if (lump.is_complete())
       dir->mark_complete();
-    else if (lump.is_importing())
-      dir->state_clear(CDir::STATE_COMPLETE);
     
     dout(10) << "EMetaBlob.replay updated dir " << *dir << dendl;  
 
@@ -1067,10 +1071,12 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
        dn->first = p->dnfirst;
        assert(dn->last == p->dnlast);
       }
+      if (lump.is_importing())
+       dn->state_set(CDentry::STATE_AUTH);
 
       CInode *in = mds->mdcache->get_inode(p->inode.ino, p->dnlast);
       if (!in) {
-       in = new CInode(mds->mdcache, true, p->dnfirst, p->dnlast);
+       in = new CInode(mds->mdcache, dn->is_auth(), p->dnfirst, p->dnlast);
        p->update_inode(mds, in);
        mds->mdcache->add_inode(in);
        if (!dn->get_linkage()->is_null()) {
@@ -1087,7 +1093,6 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
        if (unlinked.count(in))
          linked.insert(in);
        dir->link_primary_inode(dn, in);
-       if (p->is_dirty()) in->_mark_dirty(logseg);
        dout(10) << "EMetaBlob.replay added " << *in << dendl;
       } else {
        p->update_inode(mds, in);
@@ -1115,12 +1120,17 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
        } else {
          dout(10) << "EMetaBlob.replay for [" << p->dnfirst << "," << p->dnlast << "] had " << *in << dendl;
        }
-       if (p->is_dirty()) in->_mark_dirty(logseg);
        assert(in->first == p->dnfirst ||
               (in->is_multiversion() && in->first > p->dnfirst));
       }
+      if (p->is_dirty())
+       in->_mark_dirty(logseg);
       if (p->is_dirty_parent())
        in->_mark_dirty_parent(logseg, p->is_dirty_pool());
+      if (dn->is_auth())
+       in->state_set(CInode::STATE_AUTH);
+      else
+       in->state_clear(CInode::STATE_AUTH);
       assert(g_conf->mds_kill_journal_replay_at != 2);
     }
 
@@ -1153,6 +1163,8 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
        dn->first = p->dnfirst;
        assert(dn->last == p->dnlast);
       }
+      if (lump.is_importing())
+       dn->state_set(CDentry::STATE_AUTH);
     }
 
     // null dentries
@@ -1185,6 +1197,8 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
        assert(dn->last == p->dnlast);
       }
       olddir = dir;
+      if (lump.is_importing())
+       dn->state_set(CDentry::STATE_AUTH);
     }
   }
 
@@ -1210,9 +1224,11 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
        for (list<frag_t>::iterator p = leaves.begin(); p != leaves.end(); ++p) {
          CDir *dir = renamed_diri->get_dirfrag(*p);
          assert(dir);
-         // preserve subtree bound until slave commit
          if (dir->get_dir_auth() == CDIR_AUTH_UNDEF)
+           // preserve subtree bound until slave commit
            slaveup->olddirs.insert(dir->inode);
+         else
+           dir->state_set(CDir::STATE_AUTH);
        }
       }
 
@@ -1240,6 +1256,7 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
        }
        dir = renamed_diri->get_or_open_dirfrag(mds->mdcache, *p);
        dout(10) << " creating new rename import bound " << *dir << dendl;
+       dir->state_clear(CDir::STATE_AUTH);
        mds->mdcache->adjust_subtree_auth(dir, CDIR_AUTH_UNDEF, false);
       }
     }
@@ -2405,7 +2422,9 @@ void ESubtreeMap::replay(MDS *mds)
       mds->mdcache->adjust_bounded_subtree_auth(dir, p->second, mds->get_nodeid());
     }
   }
-  
+
+  mds->mdcache->recalc_auth_bits(true);
+
   mds->mdcache->show_subtrees();
 }
 
@@ -2623,7 +2642,20 @@ void EImportStart::replay(MDS *mds)
   // set auth partially to us so we don't trim it
   CDir *dir = mds->mdcache->get_dirfrag(base);
   assert(dir);
-  mds->mdcache->adjust_bounded_subtree_auth(dir, bounds, pair<int,int>(mds->get_nodeid(), mds->get_nodeid()));
+
+  set<CDir*> realbounds;
+  for (vector<dirfrag_t>::iterator p = bounds.begin();
+       p != bounds.end();
+       ++p) {
+    CDir *bd = mds->mdcache->get_dirfrag(*p);
+    assert(bd);
+    if (!bd->is_subtree_root())
+      bd->state_clear(CDir::STATE_AUTH);
+    realbounds.insert(bd);
+  }
+
+  mds->mdcache->adjust_bounded_subtree_auth(dir, realbounds,
+                                           pair<int,int>(mds->get_nodeid(), mds->get_nodeid()));
 
   // open client sessions?
   if (mds->sessionmap.version >= cmapv) {
@@ -2781,6 +2813,8 @@ void EResetJournal::replay(MDS *mds)
   CDir *mydir = mds->mdcache->get_myin()->get_or_open_dirfrag(mds->mdcache, frag_t());
   mds->mdcache->adjust_subtree_auth(mydir, mds->whoami);   
 
+  mds->mdcache->recalc_auth_bits(true);
+
   mds->mdcache->show_subtrees();
 }