mds: journal remote inode's projected parent

Server::_rename_prepare() adds remote inode's parent instead of
projected parent to the journal. So during journal replay, the
journal entry for the rename operation will wrongly revert the
remote inode's projected rename. This issue can be reproduced by:

 touch file1
 ln file1 file2
 rm file1
 mv file2 file3

After journal replay, file1 reappears and directory's fragstat
gets corrupted.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
This commit is contained in:
Yan, Zheng 2012-12-04 16:09:48 +08:00 committed by Sage Weil
parent 3f69f7290d
commit 727c37a712

View File

@ -5681,9 +5681,10 @@ void Server::_rename_prepare(MDRequest *mdr,
} else if (destdnl->is_remote()) {
if (oldin->is_auth()) {
// auth for targeti
metablob->add_dir_context(oldin->get_parent_dir());
mdcache->journal_cow_dentry(mdr, metablob, oldin->parent, CEPH_NOSNAP, 0, destdnl);
metablob->add_primary_dentry(oldin->parent, true, oldin);
metablob->add_dir_context(oldin->get_projected_parent_dir());
mdcache->journal_cow_dentry(mdr, metablob, oldin->get_projected_parent_dn(),
CEPH_NOSNAP, 0, destdnl);
metablob->add_primary_dentry(oldin->get_projected_parent_dn(), true, oldin);
}
if (destdn->is_auth()) {
// auth for dn, not targeti
@ -5702,10 +5703,10 @@ void Server::_rename_prepare(MDRequest *mdr,
if (destdn->is_auth())
metablob->add_remote_dentry(destdn, true, srcdnl->get_remote_ino(), srcdnl->get_remote_d_type());
if (srci->get_parent_dn()->is_auth()) { // it's remote
metablob->add_dir_context(srci->get_parent_dir());
mdcache->journal_cow_dentry(mdr, metablob, srci->get_parent_dn(), CEPH_NOSNAP, 0, srcdnl);
metablob->add_primary_dentry(srci->get_parent_dn(), true, srci);
if (srci->get_projected_parent_dn()->is_auth()) { // it's remote
metablob->add_dir_context(srci->get_projected_parent_dir());
mdcache->journal_cow_dentry(mdr, metablob, srci->get_projected_parent_dn(), CEPH_NOSNAP, 0, srcdnl);
metablob->add_primary_dentry(srci->get_projected_parent_dn(), true, srci);
}
} else {
if (destdn->is_auth() && !destdnl->is_null())