From: Yan, Zheng Date: Thu, 9 Feb 2017 03:43:57 +0000 (+0800) Subject: mds: note subtree bounds when rolling back rename X-Git-Tag: v12.0.1~266^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f25f054cc8f79f4e9900a43b63846a2479c115d9;p=ceph.git mds: note subtree bounds when rolling back rename mds can do a slave rename that moves directory inode (whoes dirfrags are all non-auth) to new auth. Then rolls back the slave rename. If There is a ESubtreeMap event between log event of slave rename and log event of rollback. The ESubtreeMap does not have information about the inode's non-auth dirfrags. Later when mds replays the log, the log event of slave rename can be missing. So mds need to re-create subtree bounds when replaying the log event of rename rollback Signed-off-by: "Yan, Zheng" --- diff --git a/src/mds/Server.cc b/src/mds/Server.cc index a8e1ec63e783..9b9e730e2c09 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -7817,12 +7817,22 @@ void Server::do_rename_rollback(bufferlist &rbl, mds_rank_t master, MDRequestRef le->commit.add_primary_dentry(target->get_projected_parent_dn(), target, true); } - if (force_journal_dest) { - dout(10) << " noting rename target ino " << target->ino() << " in metablob" << dendl; - le->commit.renamed_dirino = target->ino(); - } else if (force_journal_src || (in && in->is_dir() && srcdn->authority().first == whoami)) { + if (in && in->is_dir() && (srcdn->authority().first == whoami || force_journal_src)) { dout(10) << " noting renamed dir ino " << in->ino() << " in metablob" << dendl; le->commit.renamed_dirino = in->ino(); + if (srcdn->authority().first == whoami) { + list ls; + in->get_dirfrags(ls); + for (list::iterator p = ls.begin(); p != ls.end(); ++p) { + CDir *dir = *p; + if (!dir->is_auth()) + le->commit.renamed_dir_frags.push_back(dir->get_frag()); + } + dout(10) << " noting renamed dir open frags " << le->commit.renamed_dir_frags << dendl; + } + } else if (force_journal_dest) { + dout(10) << " noting rename target ino " << target->ino() << " in metablob" << dendl; + le->commit.renamed_dirino = target->ino(); } if (target && target->is_dir()) {