mirror of
https://github.com/ceph/ceph
synced 2025-01-09 20:52:09 +00:00
mds: don't create bloom filter for incomplete dir
Creating bloom filter for incomplete dir that was added by log replay will confuse subsequent dir lookup and can create null dentry for existing file. The erroneous null dentry confuses the fragstat accounting and causes undeletable empty directory. The fix is check if the dir is complete before creating the bloom filter. For the MDCache::trim_non_auth{,_subtree} cases, just do not call CDir::add_to_bloom because bloom filter is useless for replica. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
This commit is contained in:
parent
8c2526a770
commit
8cd8f2504a
@ -615,8 +615,12 @@ void CDir::unlink_inode_work( CDentry *dn )
|
||||
|
||||
void CDir::add_to_bloom(CDentry *dn)
|
||||
{
|
||||
if (!bloom)
|
||||
if (!bloom) {
|
||||
/* not create bloom filter for incomplete dir that was added by log replay */
|
||||
if (!is_complete())
|
||||
return;
|
||||
bloom = new bloom_filter(100, 0.05, 0);
|
||||
}
|
||||
/* This size and false positive probability is completely random.*/
|
||||
bloom->insert(dn->name.c_str(), dn->name.size());
|
||||
}
|
||||
|
@ -5498,9 +5498,10 @@ void MDCache::trim_dentry(CDentry *dn, map<int, MCacheExpire*>& expiremap)
|
||||
// adjust the dir state
|
||||
// NOTE: we can safely remove a clean, null dentry without effecting
|
||||
// directory completeness.
|
||||
// (do this _before_ we unlink the inode, below!)
|
||||
// (check this _before_ we unlink the inode, below!)
|
||||
bool clear_complete = false;
|
||||
if (!(dnl->is_null() && dn->is_clean()))
|
||||
dir->state_clear(CDir::STATE_COMPLETE);
|
||||
clear_complete = true;
|
||||
|
||||
// unlink the dentry
|
||||
if (dnl->is_remote()) {
|
||||
@ -5520,6 +5521,9 @@ void MDCache::trim_dentry(CDentry *dn, map<int, MCacheExpire*>& expiremap)
|
||||
// remove dentry
|
||||
dir->add_to_bloom(dn);
|
||||
dir->remove_dentry(dn);
|
||||
|
||||
if (clear_complete)
|
||||
dir->state_clear(CDir::STATE_COMPLETE);
|
||||
|
||||
// reexport?
|
||||
if (dir->get_num_head_items() == 0 && dir->is_subtree_root())
|
||||
@ -5708,9 +5712,8 @@ void MDCache::trim_non_auth()
|
||||
else {
|
||||
assert(dnl->is_null());
|
||||
}
|
||||
dir->add_to_bloom(dn);
|
||||
|
||||
dir->remove_dentry(dn);
|
||||
|
||||
// adjust the dir state
|
||||
dir->state_clear(CDir::STATE_COMPLETE); // dir incomplete!
|
||||
}
|
||||
@ -5811,7 +5814,6 @@ bool MDCache::trim_non_auth_subtree(CDir *dir)
|
||||
dout(20) << "trim_non_auth_subtree(" << dir << ") removing inode " << in << " with dentry" << dn << dendl;
|
||||
dir->unlink_inode(dn);
|
||||
remove_inode(in);
|
||||
dir->add_to_bloom(dn);
|
||||
dir->remove_dentry(dn);
|
||||
} else {
|
||||
dout(20) << "trim_non_auth_subtree(" << dir << ") keeping inode " << in << " with dentry " << dn <<dendl;
|
||||
|
Loading…
Reference in New Issue
Block a user