From c675f0f7396e5b045e99eba4d187b68208d4ee80 Mon Sep 17 00:00:00 2001 From: jhonxue Date: Tue, 27 Jul 2021 12:18:20 +0800 Subject: [PATCH] client:make sure only to update dir dist from auth mds Fixes: https://tracker.ceph.com/issues/51857 Signed-off-by: Xue Yantao (cherry picked from commit 1cafa0868797d67583031de63c10150a87fd05a4) --- src/client/Client.cc | 19 +++++++++++-------- src/client/Client.h | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 7d052bad879d5..5400400598c1b 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -1123,7 +1123,7 @@ void Client::update_dentry_lease(Dentry *dn, LeaseStat *dlease, utime_t from, Me /* * update MDS location cache for a single inode */ -void Client::update_dir_dist(Inode *in, DirStat *dst) +void Client::update_dir_dist(Inode *in, DirStat *dst, mds_rank_t from) { // auth ldout(cct, 20) << "got dirfrag map for " << in->ino << " frag " << dst->frag << " to mds " << dst->auth << dendl; @@ -1137,12 +1137,14 @@ void Client::update_dir_dist(Inode *in, DirStat *dst) _fragmap_remove_non_leaves(in); } - // replicated - in->dir_replicated = !dst->dist.empty(); - if (!dst->dist.empty()) - in->frag_repmap[dst->frag].assign(dst->dist.begin(), dst->dist.end()) ; - else - in->frag_repmap.erase(dst->frag); + // replicated, only update from auth mds reply + if (from == dst->auth) { + in->dir_replicated = !dst->dist.empty(); + if (!dst->dist.empty()) + in->frag_repmap[dst->frag].assign(dst->dist.begin(), dst->dist.end()) ; + else + in->frag_repmap.erase(dst->frag); + } } void Client::clear_dir_complete_and_ordered(Inode *diri, bool complete) @@ -1432,7 +1434,8 @@ Inode* Client::insert_trace(MetaRequest *request, MetaSession *session) if (reply->head.is_dentry) { diri = add_update_inode(&dirst, request->sent_stamp, session, request->perms); - update_dir_dist(diri, &dst); // dir stat info is attached to .. + mds_rank_t from_mds = mds_rank_t(reply->get_source().num()); + update_dir_dist(diri, &dst, from_mds); // dir stat info is attached to .. if (in) { Dir *dir = diri->open_dir(); diff --git a/src/client/Client.h b/src/client/Client.h index 88e8f4429a6d4..f24301f0b2aaf 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -776,7 +776,7 @@ public: void unlock_fh_pos(Fh *f); // metadata cache - void update_dir_dist(Inode *in, DirStat *st); + void update_dir_dist(Inode *in, DirStat *st, mds_rank_t from); void clear_dir_complete_and_ordered(Inode *diri, bool complete); void insert_readdir_results(MetaRequest *request, MetaSession *session, Inode *diri); -- 2.39.5