From d46c1e8029b0cdffd77c1cf39034ada3c11ba1c6 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 14 Nov 2008 15:31:07 -0800 Subject: [PATCH] mds: adjust purge_stray sequence; include explicit ino destroy First purge the inode content. Don't bother journaling our intent, as that's implied by the fact that it's an unused stray. Once purged, journal an event that destroys the inode and unlinks the dentry. Don't remove null dentry itself, as we still need to update the stray dir... it will get removed when that is committed. --- src/mds/MDCache.cc | 23 +++++++++++++---------- src/mds/MDCache.h | 3 +++ src/mds/events/EMetaBlob.h | 8 +++++++- src/mds/journal.cc | 13 +++++++++++++ 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index be8c4399279d2..d35526cace8b0 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -91,7 +91,7 @@ using namespace std; #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 "; } @@ -4149,10 +4149,6 @@ void MDCache::purge_inode_finish_2(CInode *in, loff_t newsize, loff_t oldsize) 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) @@ -6414,7 +6410,9 @@ public: 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(); @@ -6422,20 +6420,25 @@ void MDCache::_purge_stray_purged(CDentry *dn) 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. } diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 02f289869efd9..17bd319ea6a5a 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -797,6 +797,9 @@ public: 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); diff --git a/src/mds/events/EMetaBlob.h b/src/mds/events/EMetaBlob.h index cb1427ab847b7..201be8ba930eb 100644 --- a/src/mds/events/EMetaBlob.h +++ b/src/mds/events/EMetaBlob.h @@ -274,8 +274,9 @@ private: list allocated_inos; version_t inotablev; - // inodes i've destroyed. + // inodes i've truncated list< triple > truncated_inodes; + vector destroyed_inodes; // idempotent op(s) list client_reqs; @@ -289,6 +290,7 @@ private: if (!allocated_inos.empty()) ::encode(inotablev, bl); ::encode(truncated_inodes, bl); + ::encode(destroyed_inodes, bl); ::encode(client_reqs, bl); } void decode(bufferlist::iterator &bl) { @@ -299,6 +301,7 @@ private: if (!allocated_inos.empty()) ::decode(inotablev, bl); ::decode(truncated_inodes, bl); + ::decode(destroyed_inodes, bl); ::decode(client_reqs, bl); } @@ -337,6 +340,9 @@ private: void add_inode_truncate(inodeno_t ino, uint64_t newsize, uint64_t oldsize) { truncated_inodes.push_back(triple(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); diff --git a/src/mds/journal.cc b/src/mds/journal.cc index 0e2b450d309e1..02f0a54a9f208 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -517,6 +517,19 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg) mds->mdcache->add_recovered_purge(in, p->second, p->third, logseg); } + // destroyed inodes + for (vector::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::iterator p = client_reqs.begin(); p != client_reqs.end(); -- 2.39.5