]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: optimize memory usage of class InodeStore
authorYan, Zheng <zyan@redhat.com>
Fri, 6 Feb 2015 12:53:49 +0000 (20:53 +0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 25 Feb 2015 12:12:13 +0000 (20:12 +0800)
InodeStore::old_inodes and InodeStore::snap_blob are for snapshotted
inode only. their size are 48 bytes and 80 bytes respectively. Defining
InodeStore::old_inodes can save 40 bytes, allocating bufferlist for
snap_blob dynamiclly can save 72 bytes.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/CDir.cc
src/mds/CInode.cc
src/mds/CInode.h
src/mds/MDCache.cc
src/mds/events/EMetaBlob.h
src/mds/journal.cc

index 9943add99f164b03dbb1b48e897c9fd01e182522..903b1916c450930bded1e230237e0fb8292b446b 100644 (file)
@@ -1707,8 +1707,8 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
          in->dirfragtree.swap(inode_data.dirfragtree);
          in->xattrs.swap(inode_data.xattrs);
          in->old_inodes.swap(inode_data.old_inodes);
-         in->decode_snap_blob(inode_data.snap_blob);
          in->oldest_snap = inode_data.oldest_snap;
+         in->decode_snap_blob(inode_data.snap_blob);
          if (snaps && !in->snaprealm)
            in->purge_stale_snap_data(*snaps);
 
@@ -2012,9 +2012,9 @@ void CDir::_encode_dentry(CDentry *dn, bufferlist& bl,
     if (in->is_multiversion() && snaps && !in->snaprealm)
       in->purge_stale_snap_data(*snaps);
 
-    in->encode_snap_blob(in->snap_blob);
-    in->encode_bare(bl);
-    in->snap_blob.clear();
+    bufferlist snap_blob;
+    in->encode_snap_blob(snap_blob);
+    in->encode_bare(bl, &snap_blob);
   }
 }
 
index e98c74af08b72b9468da7d86968a2c2dd8c5c513..cdeb23bb13e40b1c85b66d5a70359f206105ede0 100644 (file)
@@ -926,7 +926,7 @@ struct C_IO_Inode_Stored : public CInodeIOContext {
   }
 };
 
-object_t InodeStore::get_object_name(inodeno_t ino, frag_t fg, const char *suffix)
+object_t InodeStoreBase::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 : "");
@@ -1240,33 +1240,37 @@ void CInode::verify_diri_backtrace(bufferlist &bl, int err)
 // parent dir
 
 
-void InodeStore::encode_bare(bufferlist &bl) const
+void InodeStoreBase::encode_bare(bufferlist &bl, const bufferlist *snap_blob) const
 {
   ::encode(inode, bl);
   if (is_symlink())
     ::encode(symlink, bl);
   ::encode(dirfragtree, bl);
   ::encode(xattrs, bl);
-  ::encode(snap_blob, bl);
+  if (snap_blob)
+    ::encode(*snap_blob, bl);
+  else
+    ::encode(bufferlist(), bl);
   ::encode(old_inodes, bl);
   ::encode(oldest_snap, bl);
 }
 
-void InodeStore::encode(bufferlist &bl) const
+void InodeStoreBase::encode(bufferlist &bl, const bufferlist *snap_blob) const
 {
   ENCODE_START(5, 4, bl);
-  encode_bare(bl);
+  encode_bare(bl, snap_blob);
   ENCODE_FINISH(bl);
 }
 
 void CInode::encode_store(bufferlist& bl)
 {
+  bufferlist snap_blob;
   encode_snap_blob(snap_blob);
-  InodeStore::encode(bl);
-  snap_blob.clear();
+  InodeStoreBase::encode(bl, &snap_blob);
 }
 
-void InodeStore::decode_bare(bufferlist::iterator &bl, __u8 struct_v)
+void InodeStoreBase::decode_bare(bufferlist::iterator &bl,
+                             bufferlist& snap_blob, __u8 struct_v)
 {
   ::decode(inode, bl);
   if (is_symlink())
@@ -1274,6 +1278,7 @@ void InodeStore::decode_bare(bufferlist::iterator &bl, __u8 struct_v)
   ::decode(dirfragtree, bl);
   ::decode(xattrs, bl);
   ::decode(snap_blob, bl);
+
   ::decode(old_inodes, bl);
   if (struct_v == 2 && inode.is_dir()) {
     bool default_layout_exists;
@@ -1288,18 +1293,18 @@ void InodeStore::decode_bare(bufferlist::iterator &bl, __u8 struct_v)
 }
 
 
-void InodeStore::decode(bufferlist::iterator &bl)
+void InodeStoreBase::decode(bufferlist::iterator &bl, bufferlist& snap_blob)
 {
   DECODE_START_LEGACY_COMPAT_LEN(5, 4, 4, bl);
-  decode_bare(bl, struct_v);
+  decode_bare(bl, snap_blob, struct_v);
   DECODE_FINISH(bl);
 }
 
 void CInode::decode_store(bufferlist::iterator& bl)
 {
-  InodeStore::decode(bl);
+  bufferlist snap_blob;
+  InodeStoreBase::decode(bl, snap_blob);
   decode_snap_blob(snap_blob);
-  snap_blob.clear();
 }
 
 // ------------------
@@ -2424,7 +2429,7 @@ old_inode_t& CInode::cow_old_inode(snapid_t follows, bool cow_head)
 
 void CInode::split_old_inode(snapid_t snap)
 {
-  map<snapid_t, old_inode_t>::iterator p = old_inodes.lower_bound(snap);
+  compact_map<snapid_t, old_inode_t>::iterator p = old_inodes.lower_bound(snap);
   assert(p != old_inodes.end() && p->second.first < snap);
 
   old_inode_t &old = old_inodes[snap - 1];
@@ -2449,7 +2454,7 @@ void CInode::purge_stale_snap_data(const set<snapid_t>& snaps)
   if (old_inodes.empty())
     return;
 
-  map<snapid_t,old_inode_t>::iterator p = old_inodes.begin();
+  compact_map<snapid_t,old_inode_t>::iterator p = old_inodes.begin();
   while (p != old_inodes.end()) {
     set<snapid_t>::const_iterator q = snaps.lower_bound(p->second.first);
     if (q == snaps.end() || *q > p->first) {
@@ -2465,7 +2470,7 @@ void CInode::purge_stale_snap_data(const set<snapid_t>& snaps)
  */
 old_inode_t * CInode::pick_old_inode(snapid_t snap)
 {
-  map<snapid_t, old_inode_t>::iterator p = old_inodes.lower_bound(snap);  // p is first key >= to snap
+  compact_map<snapid_t, old_inode_t>::iterator p = old_inodes.lower_bound(snap);  // p is first key >= to snap
   if (p != old_inodes.end() && p->second.first <= snap) {
     dout(10) << "pick_old_inode snap " << snap << " -> [" << p->second.first << "," << p->first << "]" << dendl;
     return &p->second;
@@ -2979,7 +2984,7 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
     if (!is_auth())
       valid = false;
 
-    map<snapid_t,old_inode_t>::iterator p = old_inodes.lower_bound(snapid);
+    compact_map<snapid_t,old_inode_t>::iterator p = old_inodes.lower_bound(snapid);
     if (p != old_inodes.end()) {
       if (p->second.first > snapid) {
         if  (p != old_inodes.begin())
@@ -3538,7 +3543,9 @@ void InodeStore::dump(Formatter *f) const
     // 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) {
+    for (compact_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
index f73144bc1c3a221a5a6f2fc1ed51fc0346c8bf1d..aff95e9bffb9714c3ffe7e7bf2383d3b8b48c6a3 100644 (file)
@@ -70,18 +70,16 @@ extern int num_cinode_locks;
  * handle CInodes from the backing store without hitting all
  * the business logic in CInode proper.
  */
-class InodeStore {
+class InodeStoreBase {
 public:
   inode_t                    inode;        // the inode itself
   std::string                symlink;      // symlink dest, if symlink
   std::map<std::string, bufferptr> xattrs;
   fragtree_t                 dirfragtree;  // dir frag tree, if any.  always consistent with our dirfrag map.
-  std::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
+  compact_map<snapid_t, old_inode_t> old_inodes;   // key = last, value.first = first
   snapid_t                  oldest_snap;
 
-  InodeStore() : oldest_snap(CEPH_NOSNAP) { }
+  InodeStoreBase() : oldest_snap(CEPH_NOSNAP) { }
 
   /* Helpers */
   bool is_file() const    { return inode.is_file(); }
@@ -90,20 +88,37 @@ public:
   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);
+  void encode(bufferlist &bl, const bufferlist *snap_blob=NULL) const;
+  void decode(bufferlist::iterator &bl, bufferlist& snap_blob);
 
   /* 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=5);
+  void encode_bare(bufferlist &bl, const bufferlist *snap_blob=NULL) const;
+  void decode_bare(bufferlist::iterator &bl, bufferlist &snap_blob, __u8 struct_v=5);
+};
 
+class InodeStore : public InodeStoreBase {
+public:
+  bufferlist snap_blob;  // Encoded copy of SnapRealm, because we can't
+                        // rehydrate it without full MDCache
+  void encode(bufferlist &bl) const {
+    InodeStoreBase::encode(bl, &snap_blob);
+  }
+  void decode(bufferlist::iterator &bl) {
+    InodeStoreBase::decode(bl, snap_blob);
+  }
+  void encode_bare(bufferlist &bl) const {
+    InodeStoreBase::encode_bare(bl, &snap_blob);
+  }
+  void decode_bare(bufferlist::iterator &bl) {
+    InodeStoreBase::decode_bare(bl, snap_blob);
+  }
   /* For use in debug and ceph-dencoder */
   void dump(Formatter *f) const;
   static void generate_test_instances(std::list<InodeStore*>& ls);
 };
 
 // cached inode wrapper
-class CInode : public MDSCacheObject, public InodeStore {
+class CInode : public MDSCacheObject, public InodeStoreBase {
   /*
    * This class uses a boost::pool to handle allocation. This is *not*
    * thread-safe, so don't do allocations from multiple threads!
index a1a3c2217eaa28b0a90abf8d8edc234f821e8e78..385c0f9fc458552282a7453be7ac7bbe95f66989 100644 (file)
@@ -1873,7 +1873,7 @@ void MDCache::project_rstat_frag_to_inode(nest_info_t& rstat, nest_info_t& accou
       } else {
        // our life is easier here because old_inodes is not sparse
        // (although it may not begin at snapid 1)
-       map<snapid_t,old_inode_t>::iterator p = pin->old_inodes.lower_bound(last);
+       compact_map<snapid_t,old_inode_t>::iterator p = pin->old_inodes.lower_bound(last);
        if (p == pin->old_inodes.end()) {
          dout(10) << " no old_inode <= " << last << ", done." << dendl;
          break;
index 60f64f859dbe44e4e09a876ed5edd8c230cbe244..1fa3afe0d4506c23ca263b17c2e88fff9077e2bf 100644 (file)
@@ -62,6 +62,7 @@ public:
     static const int STATE_DIRTY =      (1<<0);
     static const int STATE_DIRTYPARENT = (1<<1);
     static const int STATE_DIRTYPOOL   = (1<<2);
+    typedef compact_map<snapid_t, old_inode_t> old_inodes_t;
     string  dn;         // dentry
     snapid_t dnfirst, dnlast;
     version_t dnv;
@@ -72,7 +73,6 @@ public:
     snapid_t oldest_snap;
     bufferlist snapbl;
     __u8 state;
-    typedef map<snapid_t, old_inode_t> old_inodes_t;
     old_inodes_t old_inodes;
 
     fullbit(const fullbit& o);
index 1870ec70832d3aa24bbdc14125cdc1a517f93431..bd43ad2da949820ec8a49eed8d746ff27514c13d 100644 (file)
@@ -505,7 +505,8 @@ void EMetaBlob::fullbit::dump(Formatter *f) const
   if (!old_inodes.empty()) {
     f->open_array_section("old inodes");
     for (old_inodes_t::const_iterator iter = old_inodes.begin();
-       iter != old_inodes.end(); ++iter) {
+        iter != old_inodes.end();
+        ++iter) {
       f->open_object_section("inode");
       f->dump_int("snapid", iter->first);
       iter->second.dump(f);