mirror of
https://github.com/ceph/ceph
synced 2025-02-22 10:37:15 +00:00
mds: remove unlinked metadata from cache on replay
If we replay a metablob that unlinks something, throw it out immediately. Recursively. This comes up when: - we rename a file from one mds to another, and we replay the event on the source mds. the inode gets thrown out. - we rename a directory from one mds to another, and when journaled, the source mds had no nested metadata. same thing: we throw it out. we may have something in our cache nested beneath that, though, that was since committed and such, but the fact that we didn't journal it being reattached elsewhere implies that it was clean and gone when our event was journaled, and we can throw it all out. recursively. Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
This commit is contained in:
parent
a1a71471c2
commit
811dcae71a
@ -473,6 +473,9 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
|
||||
dout(10) << "EMetaBlob.replay don't have renamed ino " << renamed_dirino << dendl;
|
||||
}
|
||||
|
||||
// keep track of any inodes we unlink and don't relink elsewhere
|
||||
set<CInode*> unlinked;
|
||||
|
||||
// walk through my dirs (in order!)
|
||||
for (list<dirfrag_t>::iterator lp = lump_order.begin();
|
||||
lp != lump_order.end();
|
||||
@ -568,6 +571,7 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
|
||||
//assert(0); // hrm! fallout from sloppy unlink? or? hmmm FIXME investigate further
|
||||
}
|
||||
}
|
||||
unlinked.erase(in);
|
||||
dir->link_primary_inode(dn, in);
|
||||
if (p->dirty) in->_mark_dirty(logseg);
|
||||
dout(10) << "EMetaBlob.replay added " << *in << dendl;
|
||||
@ -585,6 +589,7 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
|
||||
if (dn->get_linkage()->get_inode() != in) {
|
||||
if (!dn->get_linkage()->is_null()) // note: might be remote. as with stray reintegration.
|
||||
dir->unlink_inode(dn);
|
||||
unlinked.erase(in);
|
||||
dir->link_primary_inode(dn, in);
|
||||
dout(10) << "EMetaBlob.replay linked " << *in << dendl;
|
||||
} else {
|
||||
@ -607,6 +612,8 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
|
||||
} else {
|
||||
if (!dn->get_linkage()->is_null()) {
|
||||
dout(10) << "EMetaBlob.replay unlinking " << *dn << dendl;
|
||||
if (dn->get_linkage()->is_primary())
|
||||
unlinked.insert(dn->get_linkage()->get_inode());
|
||||
if (dn->get_linkage()->get_inode() == renamed_diri)
|
||||
olddir = dir;
|
||||
dir->unlink_inode(dn);
|
||||
@ -634,6 +641,8 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
|
||||
dn->first = p->dnfirst;
|
||||
if (!dn->get_linkage()->is_null()) {
|
||||
dout(10) << "EMetaBlob.replay unlinking " << *dn << dendl;
|
||||
if (dn->get_linkage()->is_primary())
|
||||
unlinked.insert(dn->get_linkage()->get_inode());
|
||||
if (dn->get_linkage()->get_inode() == renamed_diri)
|
||||
olddir = dir;
|
||||
dir->unlink_inode(dn);
|
||||
@ -672,6 +681,12 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
|
||||
}
|
||||
}
|
||||
|
||||
if (!unlinked.empty()) {
|
||||
dout(10) << " unlinked set contains " << unlinked << dendl;
|
||||
for (set<CInode*>::iterator p = unlinked.begin(); p != unlinked.end(); ++p)
|
||||
mds->mdcache->remove_inode_recursive(*p);
|
||||
}
|
||||
|
||||
// table client transactions
|
||||
for (list<pair<__u8,version_t> >::iterator p = table_tids.begin();
|
||||
p != table_tids.end();
|
||||
|
Loading…
Reference in New Issue
Block a user