From e6b8f0a65946b0281cf15770ada46a72a04c7836 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Sat, 8 Dec 2012 13:59:38 +0800 Subject: [PATCH] mds: set want_base_dir to false for MDCache::discover_ino() When frozen inode is encountered, MDCache::handle_discover() sends reply immediately if the reply message is not empty. When handling "discover ino" requests, the reply message always contains the base directory fragment. But requestor already has the base directory fragment, the only effect of the reply message is wake the requestor and make it send same "discover ino" request again. So the requestor keeps sending "discover ino" requests but can't make any progress. The fix is set want_base_dir to false for MDCache::discover_ino(). After set want_base_dir to false, also need update the code that handles "discover ino" error. This patch also remove unused error handling code for flag_error_dn Signed-off-by: Yan, Zheng --- src/mds/MDCache.cc | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 3d5417a00a737..01e58454d633d 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -8547,7 +8547,7 @@ void MDCache::discover_ino(CDir *base, d.ino = base->ino(); d.frag = base->get_frag(); d.want_ino = want_ino; - d.want_base_dir = true; + d.want_base_dir = false; d.want_xlocked = want_xlocked; _send_discover(d); } @@ -8890,6 +8890,18 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) } } + // discover ino error + if (p.end() && m->is_flag_error_ino()) { + assert(cur->is_dir()); + CDir *dir = cur->get_dirfrag(m->get_base_dir_frag()); + if (dir) { + dout(7) << " flag_error on ino " << m->get_wanted_ino() + << ", triggering ino" << dendl; + dir->take_ino_waiting(m->get_wanted_ino(), error); + } else + assert(0); + } + // discover may start with an inode if (!p.end() && next == MDiscoverReply::INODE) { cur = add_replica_inode(p, NULL, finished); @@ -8925,30 +8937,6 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) curdir = cur->get_dirfrag(m->get_base_dir_frag()); } - // dentry error? - if (p.end() && (m->is_flag_error_dn() || m->is_flag_error_ino())) { - // error! - assert(cur->is_dir()); - if (curdir) { - if (m->get_error_dentry().length()) { - dout(7) << " flag_error on dentry " << m->get_error_dentry() - << ", triggering dentry" << dendl; - curdir->take_dentry_waiting(m->get_error_dentry(), - m->get_wanted_snapid(), m->get_wanted_snapid(), error); - } else { - dout(7) << " flag_error on ino " << m->get_wanted_ino() - << ", triggering ino" << dendl; - curdir->take_ino_waiting(m->get_wanted_ino(), error); - } - } else { - dout(7) << " flag_error on dentry " << m->get_error_dentry() - << ", triggering dir?" << dendl; - cur->take_waiting(CInode::WAIT_DIR, error); - } - break; - } - assert(curdir); - if (p.end()) break; -- 2.39.5