]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix "had dentry linked to wrong inode" warning
authorYan, Zheng <zheng.z.yan@intel.com>
Fri, 18 Jan 2013 02:47:21 +0000 (10:47 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Tue, 29 Jan 2013 02:17:34 +0000 (10:17 +0800)
The reason of "had dentry linked to wrong inode" warning is that
Server::_rename_prepare() adds the destdir to the EMetaBlob before
adding the straydir. So during MDS recovers, the destdir is first
replayed. The old inode is directly replaced by the source inode.
We can void the warning by adding the straydir first.

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

index 92062f74f597bf0128ff98e62c5d6bd975730d49..2fff8f3aae8ab8d5aa70d847d44886e027a2594d 100644 (file)
@@ -5800,6 +5800,13 @@ void Server::_rename_prepare(MDRequest *mdr,
   // prepare nesting, mtime updates
   int predirty_dir = silent ? 0:PREDIRTY_DIR;
   
+  // guarantee stray dir is processed first during journal replay. unlink the old inode,
+  // then link the source inode to destdn
+  if (destdnl->is_primary() && straydn->is_auth()) {
+    metablob->add_dir_context(straydn->get_dir());
+    metablob->add_dir(straydn->get_dir(), true);
+  }
+
   // sub off target
   if (destdn->is_auth() && !destdnl->is_null()) {
     mdcache->predirty_journal_parents(mdr, metablob, oldin, destdn->get_dir(),
index 4bd6f89b98fb23122c83d3088669895da2249ae9..ae380f36cc8a88df4cf4978660568f1cbb75c60a 100644 (file)
@@ -545,18 +545,14 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
        mds->mdcache->add_inode(in);
        if (!dn->get_linkage()->is_null()) {
          if (dn->get_linkage()->is_primary()) {
-           CInode *old_in = dn->get_linkage()->get_inode();
+           unlinked.insert(dn->get_linkage()->get_inode());
            stringstream ss;
            ss << "EMetaBlob.replay FIXME had dentry linked to wrong inode " << *dn
-               << " " << *old_in
-               << " should be " << p->inode.ino;
+              << " " << *dn->get_linkage()->get_inode() << " should be " << p->inode.ino;
            dout(0) << ss.str() << dendl;
            mds->clog.warn(ss);
-           dir->unlink_inode(dn);
-           mds->mdcache->remove_inode_recursive(old_in);
-
-           //assert(0); // hrm!  fallout from sloppy unlink?  or?  hmmm FIXME investigate further
          }
+         dir->unlink_inode(dn);
        }
        unlinked.erase(in);
        dir->link_primary_inode(dn, in);
@@ -574,8 +570,17 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
        p->update_inode(mds, in);
        if (p->dirty) in->_mark_dirty(logseg);
        if (dn->get_linkage()->get_inode() != in) {
-         if (!dn->get_linkage()->is_null())  // note: might be remote.  as with stray reintegration.
+         if (!dn->get_linkage()->is_null()) { // note: might be remote.  as with stray reintegration.
+           if (dn->get_linkage()->is_primary()) {
+             unlinked.insert(dn->get_linkage()->get_inode());
+             stringstream ss;
+             ss << "EMetaBlob.replay FIXME had dentry linked to wrong inode " << *dn
+                << " " << *dn->get_linkage()->get_inode() << " should be " << p->inode.ino;
+             dout(0) << ss.str() << dendl;
+             mds->clog.warn(ss);
+           }
            dir->unlink_inode(dn);
+         }
          unlinked.erase(in);
          dir->link_primary_inode(dn, in);
          dout(10) << "EMetaBlob.replay linked " << *in << dendl;
@@ -600,10 +605,13 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
       } else {
        if (!dn->get_linkage()->is_null()) {
          dout(10) << "EMetaBlob.replay unlinking " << *dn << dendl;
-         if (dn->get_linkage()->is_primary())
+         if (dn->get_linkage()->is_primary()) {
            unlinked.insert(dn->get_linkage()->get_inode());
-         if (dn->get_linkage()->get_inode() == renamed_diri)
-           olddir = dir;
+           stringstream ss;
+           ss << "EMetaBlob.replay FIXME had dentry linked to wrong inode " << *dn
+              << " " << *dn->get_linkage()->get_inode() << " should be remote " << p->ino;
+           dout(0) << ss.str() << dendl;
+         }
          dir->unlink_inode(dn);
        }
        dir->link_remote_inode(dn, p->ino, p->d_type);