mirror of
https://github.com/ceph/ceph
synced 2025-01-03 09:32:43 +00:00
mds: clear objects' dirty flags after log segment is expired
When standby-replay MDS detects a log segment is expired, it should check the expired segment's dirty lists and clear corresponding objects' dirty bits. Otherwise these objects will be pinned in the standby-replay MDS's cache forever. Fixes: #8648 Signed-off-by: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
parent
3215c520e1
commit
eae88dad4c
@ -6142,7 +6142,7 @@ bool MDCache::trim(int max, int count)
|
||||
while (lru.lru_get_size() + unexpirable > (unsigned)max) {
|
||||
CDentry *dn = static_cast<CDentry*>(lru.lru_expire());
|
||||
if (!dn) break;
|
||||
if ((is_standby_replay && dn->get_linkage() &&
|
||||
if ((is_standby_replay && dn->get_linkage()->inode &&
|
||||
dn->get_linkage()->inode->item_open_file.is_on_list()) ||
|
||||
trim_dentry(dn, expiremap)) {
|
||||
unexpirables.push_back(dn);
|
||||
@ -6368,7 +6368,7 @@ bool MDCache::trim_inode(CDentry *dn, CInode *in, CDir *con, map<int, MCacheExpi
|
||||
// INODE
|
||||
if (in->is_auth()) {
|
||||
// eval stray after closing dirfrags
|
||||
if (dn) {
|
||||
if (dn && !mds->is_standby_replay()) {
|
||||
maybe_eval_stray(in);
|
||||
if (dn->get_num_ref() > 0)
|
||||
return true;
|
||||
@ -6687,6 +6687,40 @@ void MDCache::try_trim_non_auth_subtree(CDir *dir)
|
||||
show_subtrees();
|
||||
}
|
||||
|
||||
void MDCache::standby_trim_segment(LogSegment *ls)
|
||||
{
|
||||
ls->new_dirfrags.clear_list();
|
||||
ls->open_files.clear_list();
|
||||
|
||||
while (!ls->dirty_dirfrags.empty()) {
|
||||
CDir *dir = ls->dirty_dirfrags.front();
|
||||
dir->mark_clean();
|
||||
}
|
||||
while (!ls->dirty_inodes.empty()) {
|
||||
CInode *in = ls->dirty_inodes.front();
|
||||
in->mark_clean();
|
||||
}
|
||||
while (!ls->dirty_dentries.empty()) {
|
||||
CDentry *dn = ls->dirty_dentries.front();
|
||||
dn->mark_clean();
|
||||
}
|
||||
while (!ls->dirty_parent_inodes.empty()) {
|
||||
CInode *in = ls->dirty_parent_inodes.front();
|
||||
in->clear_dirty_parent();
|
||||
}
|
||||
while (!ls->dirty_dirfrag_dir.empty()) {
|
||||
CInode *in = ls->dirty_dirfrag_dir.front();
|
||||
in->filelock.remove_dirty();
|
||||
}
|
||||
while (!ls->dirty_dirfrag_nest.empty()) {
|
||||
CInode *in = ls->dirty_dirfrag_nest.front();
|
||||
in->nestlock.remove_dirty();
|
||||
}
|
||||
while (!ls->dirty_dirfrag_dirfragtree.empty()) {
|
||||
CInode *in = ls->dirty_dirfrag_dirfragtree.front();
|
||||
in->dirfragtreelock.remove_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
/* This function DOES put the passed message before returning */
|
||||
void MDCache::handle_cache_expire(MCacheExpire *m)
|
||||
|
@ -566,6 +566,7 @@ public:
|
||||
void send_expire_messages(map<int, MCacheExpire*>& expiremap);
|
||||
void trim_non_auth(); // trim out trimmable non-auth items
|
||||
bool trim_non_auth_subtree(CDir *directory);
|
||||
void standby_trim_segment(LogSegment *ls);
|
||||
void try_trim_non_auth_subtree(CDir *dir);
|
||||
bool can_trim_non_auth_dirfrag(CDir *dir) {
|
||||
return my_ambiguous_imports.count((dir)->dirfrag()) == 0 &&
|
||||
|
@ -1114,15 +1114,7 @@ void MDLog::standby_trim_segments()
|
||||
if (seg->end > expire_pos)
|
||||
break;
|
||||
dout(10) << " removing segment " << seg->seq << "/" << seg->offset << dendl;
|
||||
seg->dirty_dirfrags.clear_list();
|
||||
seg->new_dirfrags.clear_list();
|
||||
seg->dirty_inodes.clear_list();
|
||||
seg->dirty_dentries.clear_list();
|
||||
seg->open_files.clear_list();
|
||||
seg->dirty_parent_inodes.clear_list();
|
||||
seg->dirty_dirfrag_dir.clear_list();
|
||||
seg->dirty_dirfrag_nest.clear_list();
|
||||
seg->dirty_dirfrag_dirfragtree.clear_list();
|
||||
mds->mdcache->standby_trim_segment(seg);
|
||||
remove_oldest_segment();
|
||||
removed_segment = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user