From 2282739b745e5a2f76044a4b963f57eaab01cdb5 Mon Sep 17 00:00:00 2001 From: John Spray Date: Fri, 2 May 2014 16:09:29 +0100 Subject: [PATCH] mds: Refactor CINode encoding into CInodeStore 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 --- src/mds/CInode.cc | 81 +++++++++++++++++++++++++++++++++------ src/mds/CInode.h | 57 ++++++++++++++++++--------- src/test/encoding/types.h | 3 ++ 3 files changed, 111 insertions(+), 30 deletions(-) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index a3d6d5eea5a7f..a28748fd08dab 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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::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 &ls) +{ + InodeStore *populated = new InodeStore; + populated->inode.ino = 0xdeadbeef; + populated->symlink = "rhubarb"; + ls.push_back(populated); +} + diff --git a/src/mds/CInode.h b/src/mds/CInode.h index adc0bf7d364a3..697e603dfc4c2 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -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 xattrs; + fragtree_t dirfragtree; // dir frag tree, if any. always consistent with our dirfrag map. + map 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& 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 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 old_inodes; // key = last, value.first = first set 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); diff --git a/src/test/encoding/types.h b/src/test/encoding/types.h index 03337dd6c1e07..679482a756f50 100644 --- a/src/test/encoding/types.h +++ b/src/test/encoding/types.h @@ -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) -- 2.39.5