]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
client: choose a random replica mds to send the request
authorYanhu Cao <gmayyyha@gmail.com>
Tue, 11 Aug 2020 08:10:26 +0000 (16:10 +0800)
committerYanhu Cao <gmayyyha@gmail.com>
Tue, 18 Aug 2020 03:39:20 +0000 (11:39 +0800)
Fixes: https://tracker.ceph.com/issues/46894
Signed-off-by: Yanhu Cao <gmayyyha@gmail.com>
src/client/Client.cc
src/client/Inode.h

index e7eb2c23ef76d9c2a4960054cb757b2f164d5e56..bf414edbfda92791c889f91b9b1aca4b65774ee8 100755 (executable)
@@ -84,6 +84,7 @@
 #include "include/lru.h"
 #include "include/compat.h"
 #include "include/stringify.h"
+#include "include/random.h"
 
 #include "Client.h"
 #include "Inode.h"
@@ -1073,7 +1074,11 @@ void Client::update_dir_dist(Inode *in, DirStat *dst)
   }
 
   // replicated
-  in->dir_replicated = !dst->dist.empty();  // FIXME that's just one frag!
+  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)
@@ -1498,9 +1503,16 @@ mds_rank_t Client::choose_target_mds(MetaRequest *req, Inode** phash_diri)
     ldout(cct, 20) << __func__ << " " << *in << " is_hash=" << is_hash
              << " hash=" << hash << dendl;
   
-    if (is_hash && S_ISDIR(in->mode) && !in->fragmap.empty()) {
+    if (is_hash && S_ISDIR(in->mode) && (!in->fragmap.empty() || !in->frag_repmap.empty())) {
       frag_t fg = in->dirfragtree[hash];
-      if (in->fragmap.count(fg)) {
+      if (!req->auth_is_best()) {
+        auto repmapit = in->frag_repmap.find(fg);
+        if (repmapit != in->frag_repmap.end()) {
+          auto& repmap = repmapit->second;
+          auto r = ceph::util::generate_random_number<uint64_t>(0, repmap.size()-1);
+          mds = repmap.at(r);
+        }
+      } else if (in->fragmap.count(fg)) {
        mds = in->fragmap[fg];
        if (phash_diri)
          *phash_diri = in;
index afaf64e0515ce36811abdf72cd068d11b9a1982e..dce9be845690bbb030e55220712fe9da84090a3c 100644 (file)
@@ -227,6 +227,7 @@ struct Inode {
   string    symlink;  // symlink content, if it's a symlink
   map<string,bufferptr> xattrs;
   map<frag_t,int> fragmap;  // known frag -> mds mappings
+  map<frag_t, std::vector<mds_rank_t>> frag_repmap; // non-auth mds mappings
 
   std::list<ceph::condition_variable*> waitfor_caps;
   std::list<ceph::condition_variable*> waitfor_commit;