Track layout information of select dirs to debug its loss

From: Alexandre Oliva <oliva@gnu.org>


---
 src/mds/CDir.cc            |    3 ++-
 src/mds/CInode.cc          |    6 ++++++
 src/mds/CInode.h           |   39 +++++++++++++++++++++++++++++++++++++--
 src/mds/MDCache.cc         |   21 +++++++++++++++------
 src/mds/Migrator.cc        |    4 +++-
 src/mds/Server.cc          |    3 ++-
 src/mds/events/EMetaBlob.h |    6 ++++--
 src/mds/journal.cc         |   11 +++++++----
 8 files changed, 76 insertions(+), 17 deletions(-)

diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc
index 4b1d3ef..e1c03eb 100644
--- a/src/mds/CDir.cc
+++ b/src/mds/CDir.cc
@@ -1560,7 +1560,7 @@ void CDir::_fetched(bufferlist &bl, const string& want_dn)
 	  continue;
 	} else {
 	  // inode
-	  in = new CInode(cache, true, first, last);
+	  in = new CInode(inode.ino, cache, true, first, last);
 	  in->inode = inode;
 	  
 	  // symlink?
@@ -1576,6 +1576,7 @@ void CDir::_fetched(bufferlist &bl, const string& want_dn)
 
 	  // add 
 	  cache->add_inode( in );
+	  in->check_layout("CDir::fetched");
 	
 	  // link
 	  dn = add_primary_dentry(dname, in, first, last);
diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc
index e72d419..ddbabc4 100644
--- a/src/mds/CInode.cc
+++ b/src/mds/CInode.cc
@@ -324,6 +324,7 @@ inode_t *CInode::project_inode(map<string,bufferptr> *px)
   }
   projected_nodes.back()->xattrs = px;
   dout(15) << "project_inode " << projected_nodes.back()->inode << dendl;
+  check_layout("project_inode", projected_nodes.back()->dir_layout);
   return projected_nodes.back()->inode;
 }
 
@@ -343,7 +344,9 @@ void CInode::pop_and_dirty_projected_inode(LogSegment *ls)
 
   if (projected_nodes.front()->dir_layout != default_layout) {
     delete default_layout;
+    check_layout("will pop projected_inode");
     default_layout = projected_nodes.front()->dir_layout;
+    check_layout("popped projected_inode");
   }
 
   if (projected_nodes.front()->snapnode)
@@ -1198,6 +1201,7 @@ void CInode::encode_lock_state(int type, bufferlist& bl)
 
   case CEPH_LOCK_IPOLICY:
     if (inode.is_dir()) {
+      check_layout("encode lock ipolicy");
       ::encode((default_layout ? true : false), bl);
       if (default_layout)
         encode(*default_layout, bl);
@@ -1448,6 +1452,7 @@ void CInode::decode_lock_state(int type, bufferlist& bl)
         default_layout = new default_file_layout;
         decode(*default_layout, p);
       }
+      check_layout("decode lock ipolicy");
     }
     break;
 
@@ -2665,6 +2670,7 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
     e.layout = i->layout;
   } else if (is_dir()) {
     ceph_file_layout *l = ppolicy ? get_projected_dir_layout() : ( default_layout ? &default_layout->layout : NULL );
+    check_layout("encode inode_stat");
     if (l)
       e.layout = *l;
     else
diff --git a/src/mds/CInode.h b/src/mds/CInode.h
index ceb5510..70dc0d4 100644
--- a/src/mds/CInode.h
+++ b/src/mds/CInode.h
@@ -238,7 +238,10 @@ public:
   //bool hack_accessed;
   //utime_t hack_load_stamp;
 
+private:
   default_file_layout *default_layout;
+public:
+  default_file_layout *&default_layout_() { return default_layout; }
 
   /**
    * Projection methods, used to store inode changes until they have been journaled,
@@ -278,19 +281,42 @@ public:
       return projected_nodes.back();
   }
 
+  bool check_layout(const char *s,
+		    default_file_layout *layout = (default_file_layout*)-1) {
+    if (inode.ino.val > 1099511627788
+	|| inode.ino.val < 1099511627776
+	|| inode.ino.val == 1099511627777)
+      return true;
+
+    if (layout == (default_file_layout*)-1)
+      layout = default_layout;
+
+    generic_dout(0) << s << " dir " << inode.ino.val - 1099511627776
+		    << " layout pool "
+		    << (!layout ? 0 : int(layout->layout.fl_pg_pool))
+		    << " inode pool " << int(inode.layout.fl_pg_pool)
+		    << dendl;
+
+    return layout && int(layout->layout.fl_pg_pool);
+  }
+
   ceph_file_layout *get_projected_dir_layout() {
     if (!inode.is_dir())
       return NULL;
     if (projected_nodes.empty()) {
+      check_layout("get not projected");
       if (default_layout)
         return &default_layout->layout;
       else
         return NULL;
     }
-    else if (projected_nodes.back()->dir_layout)
+    else {
+      check_layout("get projected", projected_nodes.back()->dir_layout);
+    if (projected_nodes.back()->dir_layout)
       return &projected_nodes.back()->dir_layout->layout;
     else
       return NULL;
+    }
   }
 
   version_t get_projected_version() {
@@ -461,7 +487,8 @@ private:
 
  public:
   // ---------------------------
-  CInode(MDCache *c, bool auth=true, snapid_t f=2, snapid_t l=CEPH_NOSNAP) : 
+  CInode(inodeno_t i,
+	 MDCache *c, bool auth=true, snapid_t f=2, snapid_t l=CEPH_NOSNAP) : 
     mdcache(c),
     snaprealm(0), containing_realm(0),
     first(f), last(l),
@@ -496,8 +523,12 @@ private:
     g_num_inoa++;
     state = 0;  
     if (auth) state_set(STATE_AUTH);
+    inode.ino = i;
+    check_layout("CInode ctor");
+    inode.ino = 0;
   };
   ~CInode() {
+    check_layout(" CInode dtor");
     g_num_ino--;
     g_num_inos++;
     close_dirfrags();
@@ -590,6 +621,7 @@ private:
     ::encode(snapbl, bl);
     ::encode(old_inodes, bl);
     if (inode.is_dir()) {
+      check_layout("encode store");
       ::encode((default_layout ? true : false), bl);
       if (default_layout)
         ::encode(*default_layout, bl);
@@ -615,6 +647,7 @@ private:
         default_layout = new default_file_layout;
         ::decode(*default_layout, bl);
       }
+      check_layout("decode store");
     }
   }
 
@@ -631,6 +664,7 @@ private:
     _encode_base(bl);
     _encode_locks_state_for_replica(bl);
     if (inode.is_dir()) {
+      check_layout("encode replica");
       ::encode((default_layout ? true : false), bl);
       if (default_layout)
         ::encode(*default_layout, bl);
@@ -651,6 +685,7 @@ private:
         default_layout = new default_file_layout;
         ::decode(*default_layout, p);
       }
+      check_layout("decode replica");
     }
   }
 
diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc
index 32faf396..c0b99f1 100644
--- a/src/mds/MDCache.cc
+++ b/src/mds/MDCache.cc
@@ -275,7 +275,7 @@ void MDCache::init_layouts()
 CInode *MDCache::create_system_inode(inodeno_t ino, int mode)
 {
   dout(0) << "creating system inode with ino:" << ino << dendl;
-  CInode *in = new CInode(this);
+  CInode *in = new CInode(ino, this);
   in->inode.ino = ino;
   in->inode.version = 1;
   in->inode.mode = 0500 | mode;
@@ -306,13 +306,14 @@ CInode *MDCache::create_system_inode(inodeno_t ino, int mode)
   }
   
   add_inode(in);
+  in->check_layout("create_system_inode");
   return in;
 }
 
 CInode *MDCache::create_root_inode()
 {
   CInode *i = create_system_inode(MDS_INO_ROOT, S_IFDIR|0755);
-  i->default_layout = new struct default_file_layout;
+  i->default_layout_() = new struct default_file_layout;
   i->default_layout->layout = default_file_layout;
   i->default_layout->layout.fl_pg_pool = mds->mdsmap->get_data_pg_pool();
   return i;
@@ -1417,7 +1418,8 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last)
 {
   assert(last >= in->first);
 
-  CInode *oldin = new CInode(this, true, in->first, last);
+  CInode *oldin = new CInode(in->get_previous_projected_inode()->ino,
+			     this, true, in->first, last);
   oldin->inode = *in->get_previous_projected_inode();
   oldin->symlink = in->symlink;
   oldin->xattrs = *in->get_previous_projected_xattrs();
@@ -1428,6 +1430,8 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last)
 
   dout(10) << "cow_inode " << *in << " to " << *oldin << dendl;
   add_inode(oldin);
+  oldin->check_layout("cow_inode oldin");
+  in->check_layout("cow_inode in");
   
   SnapRealm *realm = in->find_snaprealm();
   const set<snapid_t>& snaps = realm->get_snaps();
@@ -3943,12 +3947,13 @@ void MDCache::rejoin_scour_survivor_replicas(int from, MMDSCacheRejoin *ack, set
 
 CInode *MDCache::rejoin_invent_inode(inodeno_t ino, snapid_t last)
 {
-  CInode *in = new CInode(this, true, 1, last);
+  CInode *in = new CInode(ino, this, true, 1, last);
   in->inode.ino = ino;
   in->state_set(CInode::STATE_REJOINUNDEF);
   add_inode(in);
   rejoin_undef_inodes.insert(in);
   dout(10) << " invented " << *in << dendl;
+  in->check_layout(" rejoin_invent_inode");
   return in;
 }
 
@@ -4231,9 +4236,11 @@ void MDCache::handle_cache_rejoin_ack(MMDSCacheRejoin *ack)
 	  CInode *in = get_inode(q->second.ino, q->first.snapid);
 	  assert(in == 0);  // a rename would have been caught be the resolve stage.
 	  // barebones inode; the full inode loop below will clean up.
-	  in = new CInode(this, false, q->second.first, q->first.snapid);
+	  in = new CInode(q->second.ino,
+			  this, false, q->second.first, q->first.snapid);
 	  in->inode.ino = q->second.ino;
 	  add_inode(in);
+	  in->check_layout("handle_cache_rejoin_ack init");
 	  dn->dir->link_primary_inode(dn, in);
 	}
       }
@@ -4293,6 +4300,7 @@ void MDCache::handle_cache_rejoin_ack(MMDSCacheRejoin *ack)
     in->_decode_locks_rejoin(q, rejoin_waiters);
     in->state_clear(CInode::STATE_REJOINING);
     dout(10) << " got inode locks " << *in << dendl;
+    in->check_layout("handle_cache_rejoin_ack fini");
   }
 
   // done?
@@ -9107,9 +9115,10 @@ CInode *MDCache::add_replica_inode(bufferlist::iterator& p, CDentry *dn, list<Co
   ::decode(last, p);
   CInode *in = get_inode(ino, last);
   if (!in) {
-    in = new CInode(this, false, 1, last);
+    in = new CInode(ino, this, false, 1, last);
     in->decode_replica(p, true);
     add_inode(in);
+    in->check_layout("add_replica_inode");
     if (in->ino() == MDS_INO_ROOT)
       in->inode_auth.first = 0;
     else if (in->is_mdsdir())
diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc
index a804eab..d82a607 100644
--- a/src/mds/Migrator.cc
+++ b/src/mds/Migrator.cc
@@ -2261,7 +2261,7 @@ void Migrator::decode_import_inode(CDentry *dn, bufferlist::iterator& blp, int o
   bool added = false;
   CInode *in = cache->get_inode(ino, last);
   if (!in) {
-    in = new CInode(mds->mdcache, true, 1, last);
+    in = new CInode(ino, mds->mdcache, true, 1, last);
     added = true;
   } else {
     in->state_set(CInode::STATE_AUTH);
@@ -2290,6 +2290,8 @@ void Migrator::decode_import_inode(CDentry *dn, bufferlist::iterator& blp, int o
     dout(10) << "  had " << *in << dendl;
   }
 
+  in->check_layout("decode_import_node");
+
   if (in->inode.is_dirty_rstat())
     in->mark_dirty_rstat();
   
diff --git a/src/mds/Server.cc b/src/mds/Server.cc
index c17fc8d0..22b34ae 100644
--- a/src/mds/Server.cc
+++ b/src/mds/Server.cc
@@ -1715,7 +1715,7 @@ CDentry* Server::prepare_null_dentry(MDRequest *mdr, CDir *dir, const string& dn
 CInode* Server::prepare_new_inode(MDRequest *mdr, CDir *dir, inodeno_t useino, unsigned mode,
 				  ceph_file_layout *layout) 
 {
-  CInode *in = new CInode(mdcache);
+  CInode *in = new CInode(useino, mdcache);
   
   // assign ino
   if (mdr->session->prealloc_inos.size()) {
@@ -1801,6 +1801,7 @@ CInode* Server::prepare_new_inode(MDRequest *mdr, CDir *dir, inodeno_t useino, u
 
   mdcache->add_inode(in);  // add
   dout(10) << "prepare_new_inode " << *in << dendl;
+  in->check_layout("prepare_new_inode");
   return in;
 }
 
diff --git a/src/mds/events/EMetaBlob.h b/src/mds/events/EMetaBlob.h
index 116b704..8042a82 100644
--- a/src/mds/events/EMetaBlob.h
+++ b/src/mds/events/EMetaBlob.h
@@ -563,7 +563,8 @@ private:
     if (in->is_dir())
       default_layout = (in->get_projected_node() ?
                            in->get_projected_node()->dir_layout :
-                           in->default_layout);
+                           in->default_layout_());
+    in->check_layout("add primary dentry", default_layout);
 
     bufferlist snapbl;
     sr_t *sr = in->get_projected_srnode();
@@ -612,7 +613,8 @@ private:
     if (in->is_dir())
       default_layout = (in->get_projected_node() ?
                            in->get_projected_node()->dir_layout :
-                           in->default_layout);
+                           in->default_layout_());
+    in->check_layout("add root", default_layout);
 
     bufferlist snapbl;
     if (psnapbl)
diff --git a/src/mds/journal.cc b/src/mds/journal.cc
index 46adbf2..beabece 100644
--- a/src/mds/journal.cc
+++ b/src/mds/journal.cc
@@ -401,8 +401,9 @@ void EMetaBlob::fullbit::update_inode(MDS *mds, CInode *in)
       in->force_dirfrags();
     }
 
-    delete in->default_layout;
-    in->default_layout = dir_layout;
+    delete in->default_layout_();
+    in->default_layout_() = dir_layout;
+    in->check_layout("update inode");
     dir_layout = NULL;
     /*
      * we can do this before linking hte inode bc the split_at would
@@ -426,12 +427,13 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
     CInode *in = mds->mdcache->get_inode(root->inode.ino);
     bool isnew = in ? false:true;
     if (!in)
-      in = new CInode(mds->mdcache, true);
+      in = new CInode(root->inode.ino, mds->mdcache, true);
     root->update_inode(mds, in);
     if (isnew)
       mds->mdcache->add_inode(in);
     if (root->dirty) in->_mark_dirty(logseg);
     dout(10) << "EMetaBlob.replay " << (isnew ? " added root ":" updated root ") << *in << dendl;    
+    in->check_layout("EMetaBlob.replay root");
   }
 
   CInode *renamed_diri = 0;
@@ -531,9 +533,10 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
 
       CInode *in = mds->mdcache->get_inode(p->inode.ino, p->dnlast);
       if (!in) {
-	in = new CInode(mds->mdcache, true, p->dnfirst, p->dnlast);
+	in = new CInode(p->inode.ino, mds->mdcache, true, p->dnfirst, p->dnlast);
 	p->update_inode(mds, in);
 	mds->mdcache->add_inode(in);
+	in->check_layout("EMetaBlob.replay dentry");
 	if (!dn->get_linkage()->is_null()) {
 	  if (dn->get_linkage()->is_primary()) {
 	    CInode *old_in = dn->get_linkage()->get_inode();
