]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: adjust purge_stray sequence; include explicit ino destroy
authorSage Weil <sage@newdream.net>
Fri, 14 Nov 2008 23:31:07 +0000 (15:31 -0800)
committerSage Weil <sage@newdream.net>
Fri, 14 Nov 2008 23:31:07 +0000 (15:31 -0800)
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
src/mds/MDCache.h
src/mds/events/EMetaBlob.h
src/mds/journal.cc

index be8c4399279d2776ed22308e72aecf1f9b40ba14..d35526cace8b07c7a8853a7c6b7a2b3777e0aa60 100644 (file)
@@ -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.
 }
 
 
index 02f289869efd9b20ee8567aa7fe489b9299cfa93..17bd319ea6a5a0c581844b030e716d69fc1f289d 100644 (file)
@@ -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);
index cb1427ab847b7df6da36472153c43f0d98a0acc5..201be8ba930eb99024582ead4cd67f6bec8d23ea 100644 (file)
@@ -274,8 +274,9 @@ private:
   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;
@@ -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<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);
index 0e2b450d309e141abdd623d0dd76ee250f0796e9..02f0a54a9f2085f07ea2eb8a1f6b353aa45e2a3b 100644 (file)
@@ -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<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();