summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-01-18 10:47:21 +0800
committerYan, Zheng <zheng.z.yan@intel.com>2013-01-29 10:17:34 +0800
commitc9ff21a9e60e6420840daa2f969cd1e2a54cf81c (patch)
tree59154cb9fbeccbc7724bbfcc609decf1c9cf0d20
parentcd8d91078c65b1e029354f0fdddbd0574f03d26b (diff)
downloadceph-c9ff21a9e60e6420840daa2f969cd1e2a54cf81c.tar.gz
mds: fix "had dentry linked to wrong inode" warning
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>
-rw-r--r--src/mds/Server.cc7
-rw-r--r--src/mds/journal.cc30
2 files changed, 26 insertions, 11 deletions
diff --git a/src/mds/Server.cc b/src/mds/Server.cc
index 92062f74f59..2fff8f3aae8 100644
--- a/src/mds/Server.cc
+++ b/src/mds/Server.cc
@@ -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(),
diff --git a/src/mds/journal.cc b/src/mds/journal.cc
index 4bd6f89b98f..ae380f36cc8 100644
--- a/src/mds/journal.cc
+++ b/src/mds/journal.cc
@@ -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);