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