static const int STATE_EVALSTALECAPS = (1<<16);
static const int STATE_QUEUEDEXPORTPIN = (1<<17);
static const int STATE_TRACKEDBYOFT = (1<<18); // tracked by open file table
+ static const int STATE_DELAYEDEXPORTPIN = (1<<19);
// orphan inode needs notification of releasing reference
static const int STATE_ORPHAN = STATE_NOTIFYREF;
(STATE_DIRTY|STATE_NEEDSRECOVER|STATE_DIRTYPARENT|STATE_DIRTYPOOL);
static const int MASK_STATE_EXPORT_KEPT =
(STATE_FROZEN|STATE_AMBIGUOUSAUTH|STATE_EXPORTINGCAPS|
- STATE_QUEUEDEXPORTPIN|STATE_TRACKEDBYOFT);
+ STATE_QUEUEDEXPORTPIN|STATE_TRACKEDBYOFT|STATE_DELAYEDEXPORTPIN);
// -- waiters --
static const uint64_t WAIT_DIR = (1<<0);
CInode *in = *cur;
ceph_assert(in->is_dir());
mds_rank_t export_pin = in->get_export_pin(false);
+ if (export_pin >= mds->mdsmap->get_max_mds()) {
+ dout(20) << " delay export pin on " << *in << dendl;
+ in->state_clear(CInode::STATE_QUEUEDEXPORTPIN);
+ q.erase(cur);
+
+ in->state_set(CInode::STATE_DELAYEDEXPORTPIN);
+ mds->mdcache->export_pin_delayed_queue.insert(in);
+ continue;
+ }
bool remove = true;
auto&& dfls = in->get_dirfrags();
dendl;
}
- if (export_pin >= 0 && export_pin != mds->get_nodeid()) {
+ if (export_pin >= 0 && export_pin < mds->mdsmap->get_max_mds()
+ && export_pin != mds->get_nodeid()) {
mds->mdcache->migrator->export_dir(cd, export_pin);
}
}
if (o->state_test(CInode::STATE_QUEUEDEXPORTPIN))
export_pin_queue.erase(o);
+ if (o->state_test(CInode::STATE_DELAYEDEXPORTPIN))
+ export_pin_delayed_queue.erase(o);
+
// remove from inode map
if (o->last == CEPH_NOSNAP) {
inode_map.erase(o->ino());
f->close_section();
return true;
}
+
+void MDCache::handle_mdsmap(const MDSMap &mdsmap) {
+ // process export_pin_delayed_queue whenever a new MDSMap received
+ auto &q = export_pin_delayed_queue;
+ for (auto it = q.begin(); it != q.end(); ) {
+ auto *in = *it;
+ mds_rank_t export_pin = in->get_export_pin(false);
+ dout(10) << " delayed export_pin=" << export_pin << " on " << *in
+ << " max_mds=" << mdsmap.get_max_mds() << dendl;
+ if (export_pin >= mdsmap.get_max_mds()) {
+ it++;
+ continue;
+ }
+
+ in->state_clear(CInode::STATE_DELAYEDEXPORTPIN);
+ it = q.erase(it);
+ in->maybe_export_pin();
+ }
+}
+
void process_delayed_expire(CDir *dir);
void discard_delayed_expire(CDir *dir);
+ // -- mdsmap --
+ void handle_mdsmap(const MDSMap &mdsmap);
+
protected:
int dump_cache(std::string_view fn, Formatter *f);
public:
public:
/* Because exports may fail, this set lets us keep track of inodes that need exporting. */
std::set<CInode *> export_pin_queue;
+ std::set<CInode *> export_pin_delayed_queue;
OpenFileTable open_file_table;
};
if (oldmap.get_max_mds() != mdsmap->get_max_mds()) {
purge_queue.update_op_limit(*mdsmap);
}
+
+ mdcache->handle_mdsmap(*mdsmap);
}
void MDSRank::handle_mds_recovery(mds_rank_t who)