}
};
-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 : "");
// ------------------
// 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;
::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
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();
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);
+}
+
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!
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() {
// -- 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); }
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; }
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);
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);