#undef dout_prefix
#define dout_prefix _prefix(mds)
static ostream& _prefix(MDS *mds) {
- return *_dout << dbeginl << " mds" << mds->get_nodeid() << ".cache ";
+ return *_dout << dbeginl << "mds" << mds->get_nodeid() << ".cache ";
}
waiting_for_purge.erase(in);
finish_contexts(ls, 0);
}
-
- // done with inode?
- if (in->get_num_ref() == 0)
- remove_inode(in);
}
void MDCache::add_recovered_purge(CInode *in, loff_t newsize, loff_t oldsize, LogSegment *ls)
void MDCache::_purge_stray_purged(CDentry *dn)
{
dout(10) << "_purge_stray_purged " << *dn << dendl;
- assert(dn->is_null());
+
+ CInode *in = dn->inode;
+ assert(in->get_num_ref() == 0);
// kill dentry.
version_t pdv = dn->pre_dirty();
EUpdate *le = new EUpdate(mds->mdlog, "purge_stray");
le->metablob.add_dir_context(dn->dir);
le->metablob.add_null_dentry(dn, true);
+ le->metablob.add_destroyed_inode(in->ino());
mds->mdlog->submit_entry(le, new C_MDC_PurgeStrayLogged(this, dn, pdv, mds->mdlog->get_current_segment()));
}
void MDCache::_purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *ls)
{
- dout(10) << "_purge_stray_logged " << *dn << dendl;
- assert(dn->is_null());
+ dout(10) << "_purge_stray_logged " << *dn << " " << *dn->inode << dendl;
- // dirty+unlink dentry
dn->state_clear(CDentry::STATE_PURGING);
dn->put(CDentry::PIN_PURGING);
+
+ // unlink and remove dentry
+ dn->mark_clean();
+ remove_inode(dn->inode);
+ assert(dn->is_null());
+
dn->dir->mark_dirty(pdv, ls);
- dn->dir->remove_dentry(dn);
+ touch_dentry_bottom(dn); // drop as quickly as possible.
}
else
lru.lru_midtouch(dn);
}
+ void touch_dentry_bottom(CDentry *dn) {
+ lru.lru_bottouch(dn);
+ }
void inode_remove_replica(CInode *in, int rep);
void dentry_remove_replica(CDentry *dn, int rep);
list<inodeno_t> allocated_inos;
version_t inotablev;
- // inodes i've destroyed.
+ // inodes i've truncated
list< triple<inodeno_t,uint64_t,uint64_t> > truncated_inodes;
+ vector<inodeno_t> destroyed_inodes;
// idempotent op(s)
list<metareqid_t> client_reqs;
if (!allocated_inos.empty())
::encode(inotablev, bl);
::encode(truncated_inodes, bl);
+ ::encode(destroyed_inodes, bl);
::encode(client_reqs, bl);
}
void decode(bufferlist::iterator &bl) {
if (!allocated_inos.empty())
::decode(inotablev, bl);
::decode(truncated_inodes, bl);
+ ::decode(destroyed_inodes, bl);
::decode(client_reqs, bl);
}
void add_inode_truncate(inodeno_t ino, uint64_t newsize, uint64_t oldsize) {
truncated_inodes.push_back(triple<inodeno_t,uint64_t,uint64_t>(ino, newsize, oldsize));
}
+ void add_destroyed_inode(inodeno_t ino) {
+ destroyed_inodes.push_back(ino);
+ }
void add_null_dentry(CDentry *dn, bool dirty) {
add_null_dentry(add_dir(dn->get_dir(), false), dn, dirty);
mds->mdcache->add_recovered_purge(in, p->second, p->third, logseg);
}
+ // destroyed inodes
+ for (vector<inodeno_t>::iterator p = destroyed_inodes.begin();
+ p != destroyed_inodes.end();
+ p++) {
+ CInode *in = mds->mdcache->get_inode(*p);
+ if (in) {
+ dout(10) << "EMetaBlob.replay destroyed " << *p << ", dropping " << *in << dendl;
+ mds->mdcache->remove_inode(in);
+ } else {
+ dout(10) << "EMetaBlob.replay destroyed " << *p << ", not in cache" << dendl;
+ }
+ }
+
// client requests
for (list<metareqid_t>::iterator p = client_reqs.begin();
p != client_reqs.end();