// -- state --
static const int STATE_NEW = 1;
static const int STATE_FRAGMENTING = 2;
+ static const int STATE_PURGING = 3;
// -- pins --
static const int PIN_INODEPIN = 1; // linked inode is pinned
static const int PIN_FRAGMENTING = -2; // containing dir is refragmenting
+ static const int PIN_PURGING = 3;
const char *pin_name(int p) {
switch (p) {
case PIN_INODEPIN: return "inodepin";
case PIN_FRAGMENTING: return "fragmenting";
+ case PIN_PURGING: return "purging";
default: return generic_pin_name(p);
}
};
}
if (dn->is_replicated() || in->is_any_caps()) return; // wait
if (!in->dirfrags.empty()) return; // wait for dirs to close/trim
+ if (dn->state_test(CDentry::STATE_PURGING)) return; // already purging
_purge_stray(dn);
}
else if (in->inode.nlink == 1) {
le->metablob.add_null_dentry(dn, true);
le->metablob.add_inode_truncate(dn->inode->ino(), 0, dn->inode->inode.size);
+ dn->state_set(CDentry::STATE_PURGING);
+ dn->get(CDentry::PIN_PURGING);
mds->mdlog->submit_entry(le, new C_MDC_PurgeStray(this, dn, pdv, mds->mdlog->get_current_segment()));
-
-
}
void MDCache::_purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *ls)
CInode *in = dn->inode;
// dirty+unlink dentry
+ dn->state_clear(CDentry::STATE_PURGING);
+ dn->put(CDentry::PIN_PURGING);
dn->dir->mark_dirty(pdv, ls);
dn->dir->unlink_inode(dn);
dn->dir->remove_dentry(dn);