diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2012-12-04 16:09:48 +0800 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2012-12-04 05:35:03 -0800 |
commit | 2ba9c870b0a4ed0b801ddf6c332426d3e2ab50b2 (patch) | |
tree | 34a0439f64a80c5b30abd0012e03e8d66bb07a99 | |
parent | 8cd8f2504a1182448373ee77d16653f0bc17b257 (diff) | |
download | ceph-2ba9c870b0a4ed0b801ddf6c332426d3e2ab50b2.tar.gz |
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>
-rw-r--r-- | src/mds/Server.cc | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 72fd7da2305..ba436566dec 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -5704,9 +5704,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 @@ -5725,10 +5726,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()) |