#include "include/lru.h"
#include "include/compat.h"
#include "include/stringify.h"
+#include "include/random.h"
#include "Client.h"
#include "Inode.h"
}
// 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)
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;
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;