From 1e889cd035b604aa248b1aba1f11035d30b9e300 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Mon, 7 Oct 2019 15:50:50 +0800 Subject: [PATCH] mds: add 'path_locked' flag to MDCache::find_ino_peers() MDS now relies on snaplocks to ensure that paths for slave request are stable. MDCache::handle_find_ino_reply() may encounter xlocked dentry during path traverse. Signed-off-by: "Yan, Zheng" --- src/mds/MDCache.cc | 11 ++++++++--- src/mds/MDCache.h | 4 +++- src/mds/Server.cc | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 194226156aa..6b782bdb25d 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -9157,7 +9157,8 @@ void MDCache::open_ino(inodeno_t ino, int64_t pool, MDSContext* fin, - traverse path */ -void MDCache::find_ino_peers(inodeno_t ino, MDSContext *c, mds_rank_t hint) +void MDCache::find_ino_peers(inodeno_t ino, MDSContext *c, + mds_rank_t hint, bool path_locked) { dout(5) << "find_ino_peers " << ino << " hint " << hint << dendl; CInode *in = get_inode(ino); @@ -9172,6 +9173,7 @@ void MDCache::find_ino_peers(inodeno_t ino, MDSContext *c, mds_rank_t hint) fip.ino = ino; fip.tid = tid; fip.fin = c; + fip.path_locked = path_locked; fip.hint = hint; _do_find_ino_peer(fip); } @@ -9233,7 +9235,7 @@ void MDCache::handle_find_ino(const cref_t &m) void MDCache::handle_find_ino_reply(const cref_t &m) { - map::iterator p = find_ino_peer.find(m->tid); + auto p = find_ino_peer.find(m->tid); if (p != find_ino_peer.end()) { dout(10) << "handle_find_ino_reply " << *m << dendl; find_ino_peer_info_t& fip = p->second; @@ -9256,7 +9258,10 @@ void MDCache::handle_find_ino_reply(const cref_t &m) vector trace; CF_MDS_RetryMessageFactory cf(mds, m); MDRequestRef null_ref; - int r = path_traverse(null_ref, cf, m->path, MDS_TRAVERSE_DISCOVER, &trace); + int flags = MDS_TRAVERSE_DISCOVER; + if (fip.path_locked) + flags |= MDS_TRAVERSE_PATH_LOCKED; + int r = path_traverse(null_ref, cf, m->path, flags, &trace); if (r > 0) return; dout(0) << "handle_find_ino_reply failed with " << r << " on " << m->path diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index a8ab7f6bedf..b781642de99 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -173,6 +173,7 @@ class MDCache { inodeno_t ino; ceph_tid_t tid = 0; MDSContext *fin = nullptr; + bool path_locked = false; mds_rank_t hint = MDS_RANK_NONE; mds_rank_t checking = MDS_RANK_NONE; set checked; @@ -822,7 +823,8 @@ class MDCache { void open_ino(inodeno_t ino, int64_t pool, MDSContext *fin, bool want_replica=true, bool want_xlocked=false); - void find_ino_peers(inodeno_t ino, MDSContext *c, mds_rank_t hint=MDS_RANK_NONE); + void find_ino_peers(inodeno_t ino, MDSContext *c, + mds_rank_t hint=MDS_RANK_NONE, bool path_locked=false); void _do_find_ino_peer(find_ino_peer_info_t& fip); void handle_find_ino(const cref_t &m); void handle_find_ino_reply(const cref_t &m); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 9066158f94d..fc825995628 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -7072,7 +7072,7 @@ void Server::handle_slave_rmdir_prep(MDRequestRef& mdr) if (r > 0) return; if (r == -ESTALE) { mdcache->find_ino_peers(srcpath.get_ino(), new C_MDS_RetryRequest(mdcache, mdr), - mdr->slave_to_mds); + mdr->slave_to_mds, true); return; } ceph_assert(r == 0); @@ -8593,7 +8593,7 @@ void Server::handle_slave_rename_prep(MDRequestRef& mdr) if (r > 0) return; if (r == -ESTALE) { mdcache->find_ino_peers(destpath.get_ino(), new C_MDS_RetryRequest(mdcache, mdr), - mdr->slave_to_mds); + mdr->slave_to_mds, true); return; } ceph_assert(r == 0); // we shouldn't get an error here! -- 2.39.5