state_set(STATE_NEW);
}
+void CDentry::mark_auth()
+{
+ if (!is_auth()) {
+ state_set(STATE_AUTH);
+ dir->adjust_dentry_lru(this);
+ }
+}
+
+void CDentry::clear_auth()
+{
+ if (is_auth()) {
+ state_clear(STATE_AUTH);
+ dir->adjust_dentry_lru(this);
+ }
+}
+
void CDentry::make_path_string(string& s, bool projected) const
{
if (dir) {
void mark_new();
bool is_new() const { return state_test(STATE_NEW); }
void clear_new() { state_clear(STATE_NEW); }
+
+ void mark_auth();
+ void clear_auth();
// -- exporting
// note: this assumes the dentry already exists.
// twiddle
clear_replica_map();
replica_nonce = EXPORT_NONCE;
- state_clear(CDentry::STATE_AUTH);
+ clear_auth();
if (is_dirty())
mark_clean();
put(PIN_TEMPEXPORTING);
// twiddle
state &= MASK_STATE_IMPORT_KEPT;
- state_set(CDentry::STATE_AUTH);
+ mark_auth();
if (nstate & STATE_DIRTY)
_mark_dirty(ls);
if (is_replicated())
return p->second;
}
+void CDir::adjust_dentry_lru(CDentry *dn)
+{
+ bool bottom_lru;
+ if (dn->get_linkage()->is_primary()) {
+ bottom_lru = !is_auth() && inode->is_stray();
+ } else if (dn->get_linkage()->is_remote()) {
+ bottom_lru = false;
+ } else {
+ bottom_lru = !is_auth();
+ }
+ if (bottom_lru) {
+ if (!dn->state_test(CDentry::STATE_BOTTOMLRU)) {
+ mdcache->lru.lru_remove(dn);
+ mdcache->bottom_lru.lru_insert_mid(dn);
+ dn->state_set(CDentry::STATE_BOTTOMLRU);
+ }
+ } else {
+ if (dn->state_test(CDentry::STATE_BOTTOMLRU)) {
+ mdcache->bottom_lru.lru_remove(dn);
+ mdcache->lru.lru_insert_mid(dn);
+ dn->state_clear(CDentry::STATE_BOTTOMLRU);
+ }
+ }
+}
+
/***
* linking fun
*/
// create dentry
CDentry* dn = new CDentry(dname, inode->hash_dentry_name(dname), "", first, last);
- if (is_auth())
+ if (is_auth()) {
dn->state_set(CDentry::STATE_AUTH);
-
- mdcache->bottom_lru.lru_insert_mid(dn);
- dn->state_set(CDentry::STATE_BOTTOMLRU);
+ mdcache->lru.lru_insert_mid(dn);
+ } else {
+ mdcache->bottom_lru.lru_insert_mid(dn);
+ dn->state_set(CDentry::STATE_BOTTOMLRU);
+ }
dn->dir = this;
dn->version = get_projected_version();
unlink_inode_work(dn);
- if (adjust_lru && !dn->state_test(CDentry::STATE_BOTTOMLRU)) {
+ if (adjust_lru && !is_auth() &&
+ !dn->state_test(CDentry::STATE_BOTTOMLRU)) {
mdcache->lru.lru_remove(dn);
mdcache->bottom_lru.lru_insert_mid(dn);
dn->state_set(CDentry::STATE_BOTTOMLRU);
ceph_assert(get_num_any() == items.size());
}
-
void CDir::try_remove_unlinked_dn(CDentry *dn)
{
ceph_assert(dn->dir == this);
CDentry* lookup_exact_snap(std::string_view dname, snapid_t last);
CDentry* lookup(std::string_view n, snapid_t snap=CEPH_NOSNAP);
+ void adjust_dentry_lru(CDentry *dn);
CDentry* add_null_dentry(std::string_view dname,
snapid_t first=2, snapid_t last=CEPH_NOSNAP);
CDentry* add_primary_dentry(std::string_view dname, CInode *in, mempool::mds_co::string alternate_name,
CDentry *dn = p.second;
CDentry::linkage_t *dnl = dn->get_linkage();
if (auth) {
- dn->state_set(CDentry::STATE_AUTH);
+ dn->mark_auth();
} else {
- dn->state_clear(CDentry::STATE_AUTH);
+ dn->clear_auth();
if (!replay) {
dn->state_set(CDentry::STATE_REJOINING);
if (dn->is_dirty())
dir->remove_dentry(dn);
} else {
dout(20) << "trim_non_auth_subtree(" << dir << ") keeping inode " << in << " with dentry " << dn <<dendl;
- dn->state_clear(CDentry::STATE_AUTH);
+ dn->clear_auth();
in->state_clear(CInode::STATE_AUTH);
}
} else if (keep_dir && dnl->is_null()) { // keep null dentry for peer rollback
CDentry *dn = p.second;
// dentry
- dn->state_clear(CDentry::STATE_AUTH);
+ dn->clear_auth();
dn->clear_replica_map();
dn->set_replica_nonce(CDentry::EXPORT_NONCE);
if (dn->is_dirty())
// inode?
if (dn->get_linkage()->is_primary()) {
CInode *in = dn->get_linkage()->get_inode();
- in->state_clear(CDentry::STATE_AUTH);
+ in->state_clear(CInode::STATE_AUTH);
in->clear_replica_map();
in->set_replica_nonce(CInode::EXPORT_NONCE);
if (in->is_dirty())
bool dnp = dn->use_projected(client, mdr);
CDentry::linkage_t *dnl = dnp ? dn->get_projected_linkage() : dn->get_linkage();
- if (dnl->is_null())
+ if (dnl->is_null()) {
+ if (dn->get_num_ref() == 0 && !dn->is_projected())
+ dir->remove_dentry(dn);
continue;
+ }
if (dn->last < snapid || dn->first > snapid) {
dout(20) << "skipping non-overlapping snap " << *dn << dendl;
ceph_assert(dn->last == fb.dnlast);
}
if (lump.is_importing())
- dn->state_set(CDentry::STATE_AUTH);
+ dn->mark_auth();
CInode *in = mds->mdcache->get_inode(fb.inode->ino, fb.dnlast);
if (!in) {
ceph_assert(dn->last == rb.dnlast);
}
if (lump.is_importing())
- dn->state_set(CDentry::STATE_AUTH);
+ dn->mark_auth();
if (!(++count % 1000))
mds->heartbeat_reset();
}
olddir = dir;
if (lump.is_importing())
- dn->state_set(CDentry::STATE_AUTH);
+ dn->mark_auth();
// Make null dentries the first things we trim
dout(10) << "EMetaBlob.replay pushing to bottom of lru " << *dn << dendl;