set<int> SimpleLock::empty_gather_set;
-MDCache::MDCache(MDS *m)
+MDCache::MDCache(MDS *m) :
+ delayed_eval_stray(member_offset(CDentry, item_stray))
{
mds = m;
migrator = new Migrator(mds, this);
}
dout(7) << "trim max=" << max << " cur=" << lru.lru_get_size() << dendl;
- map<int, MCacheExpire*> expiremap;
+ // process delayed eval_stray()
+ for (elist<CDentry*>::iterator p = delayed_eval_stray.begin(); !p.end(); ) {
+ CDentry *dn = *p;
+ ++p;
+ dn->item_stray.remove_myself();
+ eval_stray(dn);
+ }
+ map<int, MCacheExpire*> expiremap;
bool is_standby_replay = mds->is_standby_replay();
int unexpirable = 0;
list<CDentry*> unexpirables;
}
};
-void MDCache::eval_stray(CDentry *dn)
+void MDCache::eval_stray(CDentry *dn, bool delay)
{
dout(10) << "eval_stray " << *dn << dendl;
CDentry::linkage_t *dnl = dn->get_projected_linkage();
dout(20) << " too many dn refs" << dendl;
return;
}
- purge_stray(dn);
+ if (delay) {
+ if (!dn->item_stray.is_on_list())
+ delayed_eval_stray.push_back(&dn->item_stray);
+ } else
+ purge_stray(dn);
}
else if (in->inode.nlink >= 1) {
// trivial reintegrate?
dn->get(CDentry::PIN_PURGING);
in->state_set(CInode::STATE_PURGING);
-
+ if (dn->item_stray.is_on_list())
+ dn->item_stray.remove_myself();
+
// CHEAT. there's no real need to journal our intent to purge, since
// that is implicit in the dentry's presence and non-use in the stray
// dir. on recovery, we'll need to re-eval all strays anyway.
#include "include/types.h"
#include "include/filepath.h"
+#include "include/elist.h"
#include "CInode.h"
#include "CDentry.h"
// -- stray --
public:
+ elist<CDentry*> delayed_eval_stray;
+
void scan_stray_dir();
- void eval_stray(CDentry *dn);
+ void eval_stray(CDentry *dn, bool delay=false);
void eval_remote(CDentry *dn);
- void maybe_eval_stray(CInode *in) {
+ void maybe_eval_stray(CInode *in, bool delay=false) {
if (in->inode.nlink > 0 || in->is_base())
return;
CDentry *dn = in->get_projected_parent_dn();
- if (dn->get_projected_linkage()->is_primary() &&
- dn->get_dir()->get_inode()->is_stray() &&
- !dn->is_replicated())
- eval_stray(dn);
+ if (!dn->state_test(CDentry::STATE_PURGING) &&
+ dn->get_projected_linkage()->is_primary() &&
+ dn->get_dir()->get_inode()->is_stray())
+ eval_stray(dn, delay);
}
protected:
void fetch_backtrace(inodeno_t ino, int64_t pool, bufferlist& bl, Context *fin);