]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: Refactor CINode encoding into CInodeStore
authorJohn Spray <john.spray@inktank.com>
Fri, 2 May 2014 15:09:29 +0000 (16:09 +0100)
committerJohn Spray <john.spray@inktank.com>
Sun, 18 May 2014 10:21:29 +0000 (11:21 +0100)
CInode itself combined the on-disk format and
encode/decode logic with lots of other complex
behaviours.  This separates the simple parts
out so that they can be used by other tools that
are interested in looking at inodes outside of
a running MDS.

There is a small overhead because CInodeStore
can't decode a SnapRealm inline, so it keeps
a temporary copy of the encoded bufferlist.

Signed-off-by: John Spray <john.spray@inktank.com>
src/mds/CInode.cc
src/mds/CInode.h
src/test/encoding/types.h

index a3d6d5eea5a7f0a50fa7cbdfcd2bec59dc5ed21c..a28748fd08dabaa607c9ec00352c1f790872fd19 100644 (file)
@@ -896,7 +896,7 @@ struct C_Inode_Stored : public Context {
   }
 };
 
-object_t CInode::get_object_name(inodeno_t ino, frag_t fg, const char *suffix)
+object_t InodeStore::get_object_name(inodeno_t ino, frag_t fg, const char *suffix)
 {
   char n[60];
   snprintf(n, sizeof(n), "%llx.%08llx%s", (long long unsigned)ino, (long long unsigned)fg, suffix ? suffix : "");
@@ -1126,31 +1126,40 @@ void CInode::clear_dirty_parent()
 // ------------------
 // parent dir
 
-void CInode::encode_store(bufferlist& bl)
+
+void InodeStore::encode_bare(bufferlist &bl) const
 {
-  ENCODE_START(4, 4, bl);
   ::encode(inode, bl);
   if (is_symlink())
     ::encode(symlink, bl);
   ::encode(dirfragtree, bl);
   ::encode(xattrs, bl);
-  bufferlist snapbl;
-  encode_snap_blob(snapbl);
-  ::encode(snapbl, bl);
+  ::encode(snap_blob, bl);
   ::encode(old_inodes, bl);
+}
+
+void InodeStore::encode(bufferlist &bl) const
+{
+  ENCODE_START(4, 4, bl);
+  encode_bare(bl);
   ENCODE_FINISH(bl);
 }
 
-void CInode::decode_store(bufferlist::iterator& bl) {
-  DECODE_START_LEGACY_COMPAT_LEN(4, 4, 4, bl);
+void CInode::encode_store(bufferlist& bl)
+{
+  encode_snap_blob(snap_blob);
+  InodeStore::encode(bl);
+  snap_blob.clear();
+}
+
+void InodeStore::decode_bare(bufferlist::iterator &bl, __u8 struct_v)
+{
   ::decode(inode, bl);
   if (is_symlink())
     ::decode(symlink, bl);
   ::decode(dirfragtree, bl);
   ::decode(xattrs, bl);
-  bufferlist snapbl;
-  ::decode(snapbl, bl);
-  decode_snap_blob(snapbl);
+  ::decode(snap_blob, bl);
   ::decode(old_inodes, bl);
   if (struct_v == 2 && inode.is_dir()) {
     bool default_layout_exists;
@@ -1160,9 +1169,23 @@ void CInode::decode_store(bufferlist::iterator& bl) {
       ::decode(inode.layout, bl); // but we only care about the layout portion
     }
   }
+}
+
+
+void InodeStore::decode(bufferlist::iterator &bl)
+{
+  DECODE_START_LEGACY_COMPAT_LEN(4, 4, 4, bl);
+  decode_bare(bl, struct_v);
   DECODE_FINISH(bl);
 }
 
+void CInode::decode_store(bufferlist::iterator& bl)
+{
+  InodeStore::decode(bl);
+  decode_snap_blob(snap_blob);
+  snap_blob.clear();
+}
+
 // ------------------
 // locking
 
@@ -2364,7 +2387,7 @@ void CInode::encode_snap_blob(bufferlist &snapbl)
     dout(20) << "encode_snap_blob " << *snaprealm << dendl;
   }
 }
-void CInode::decode_snap_blob(bufferlist& snapbl) 
+void CInode::decode_snap_blob(bufferlist& snapbl)
 {
   if (snapbl.length()) {
     open_snaprealm();
@@ -3351,3 +3374,37 @@ void CInode::decode_import(bufferlist::iterator& p,
 
   DECODE_FINISH(p);
 }
+
+
+void InodeStore::dump(Formatter *f) const
+{
+  f->open_object_section("inode_store");
+  {
+    inode.dump(f);
+    f->dump_string("symlink", symlink);
+    // FIXME: dirfragtree: dump methods for fragtree_t
+    // FIXME: xattrs: JSON-safe versions of binary xattrs
+    f->open_array_section("old_inodes");
+    for (std::map<snapid_t, old_inode_t>::const_iterator i = old_inodes.begin(); i != old_inodes.end(); ++i) {
+      f->open_object_section("old_inode");
+      {
+        // The key is the last snapid, the first is in the old_inode_t
+        f->dump_int("last", i->first);
+        i->second.dump(f);
+      }
+      f->close_section();  // old_inode
+    }
+    f->close_section();  // old_inodes
+  }
+  f->close_section();  // inode_store
+}
+
+
+void InodeStore::generate_test_instances(list<InodeStore*> &ls)
+{
+  InodeStore *populated = new InodeStore;
+  populated->inode.ino = 0xdeadbeef;
+  populated->symlink = "rhubarb";
+  ls.push_back(populated);
+}
+
index adc0bf7d364a3b155d3ba5fc63302d02750c1eb6..697e603dfc4c234ba7aaa8f43f43f6f7a342d32f 100644 (file)
@@ -63,8 +63,44 @@ struct cinode_lock_info_t {
 extern cinode_lock_info_t cinode_lock_info[];
 extern int num_cinode_locks;
 
+
+/**
+ * Base class for CInode, containing the backing store data and
+ * serialization methods.  This exists so that we can read and
+ * handle CInodes from the backing store without hitting all
+ * the business logic in CInode proper.
+ */
+class InodeStore {
+public:
+  inode_t                    inode;        // the inode itself
+  string                     symlink;      // symlink dest, if symlink
+  map<string, bufferptr>     xattrs;
+  fragtree_t                 dirfragtree;  // dir frag tree, if any.  always consistent with our dirfrag map.
+  map<snapid_t, old_inode_t> old_inodes;   // key = last, value.first = first
+  bufferlist                snap_blob;    // Encoded copy of SnapRealm, because we can't
+                                           // rehydrate it without full MDCache
+
+  /* Helpers */
+  bool is_file() const    { return inode.is_file(); }
+  bool is_symlink() const { return inode.is_symlink(); }
+  bool is_dir() const     { return inode.is_dir(); }
+  static object_t get_object_name(inodeno_t ino, frag_t fg, const char *suffix);
+
+  /* Full serialization for use in ".inode" root inode objects */
+  void encode(bufferlist &bl) const;
+  void decode(bufferlist::iterator &bl);
+
+  /* Serialization without ENCODE_START/FINISH blocks for use embedded in dentry */
+  void encode_bare(bufferlist &bl) const;
+  void decode_bare(bufferlist::iterator &bl, __u8 struct_v=4);
+
+  /* For use in debug and ceph-dencoder */
+  void dump(Formatter *f) const;
+  static void generate_test_instances(list<InodeStore*>& ls);
+};
+
 // cached inode wrapper
-class CInode : public MDSCacheObject {
+class CInode : public MDSCacheObject, public InodeStore {
   /*
    * This class uses a boost::pool to handle allocation. This is *not*
    * thread-safe, so don't do allocations from multiple threads!
@@ -176,16 +212,9 @@ public:
  public:
   MDCache *mdcache;
 
-  // inode contents proper
-  inode_t          inode;        // the inode itself
-  string           symlink;      // symlink dest, if symlink
-  map<string, bufferptr> xattrs;
-  fragtree_t       dirfragtree;  // dir frag tree, if any.  always consistent with our dirfrag map.
   SnapRealm        *snaprealm;
-
   SnapRealm        *containing_realm;
   snapid_t          first, last;
-  map<snapid_t, old_inode_t> old_inodes;  // key = last, value.first = first
   set<snapid_t> dirty_old_rstats;
 
   bool is_multiversion() {
@@ -462,10 +491,6 @@ public:
   
 
   // -- accessors --
-  bool is_file()    { return inode.is_file(); }
-  bool is_symlink() { return inode.is_symlink(); }
-  bool is_dir()     { return inode.is_dir(); }
-
   bool is_root() { return inode.ino == MDS_INO_ROOT; }
   bool is_stray() { return MDS_INO_IS_STRAY(inode.ino); }
   bool is_mdsdir() { return MDS_INO_IS_MDSDIR(inode.ino); }
@@ -508,10 +533,6 @@ public:
   void make_path_string_projected(string& s);  
   void make_path(filepath& s);
   void name_stray_dentry(string& dname);
-
-
-  static object_t get_object_name(inodeno_t ino, frag_t fg, const char *suffix);
-
   
   // -- dirtyness --
   version_t get_version() { return inode.version; }
@@ -534,6 +555,8 @@ public:
   bool is_dirty_parent() { return state_test(STATE_DIRTYPARENT); }
   bool is_dirty_pool() { return state_test(STATE_DIRTYPOOL); }
 
+  void encode_snap_blob(bufferlist &bl);
+  void decode_snap_blob(bufferlist &bl);
   void encode_store(bufferlist& bl);
   void decode_store(bufferlist::iterator& bl);
 
@@ -660,8 +683,6 @@ public:
   void open_snaprealm(bool no_split=false);
   void close_snaprealm(bool no_join=false);
   SnapRealm *find_snaprealm();
-  void encode_snap_blob(bufferlist &bl);
-  void decode_snap_blob(bufferlist &bl);
   void encode_snap(bufferlist& bl);
   void decode_snap(bufferlist::iterator& p);
 
index 03337dd6c1e07b14eedbd088167529df76962e2d..679482a756f50b01cafbadcf5b2b02fbe8343ab8 100644 (file)
@@ -156,6 +156,9 @@ TYPE(cap_reconnect_t)
 TYPE(inode_backtrace_t)
 TYPE(inode_backpointer_t)
 
+#include "mds/CInode.h"
+TYPE(InodeStore)
+
 #include "mds/MDSMap.h"
 TYPE_FEATUREFUL(MDSMap)
 TYPE_FEATUREFUL(MDSMap::mds_info_t)