#ifndef CEPH_MDS_EMETABLOB_H
#define CEPH_MDS_EMETABLOB_H
+#include <string_view>
+
#include <stdlib.h>
#include "../CInode.h"
*
* - make sure you adjust the inode.version for any modified inode you
* journal. CDir and CDentry maintain a projected_version, but CInode
- * doesn't, since the journaled inode usually has to be modifed
+ * doesn't, since the journaled inode usually has to be modified
* manually anyway (to delay the change in the MDS's cache until after
* it is journaled).
*
static const int STATE_DIRTYPARENT = (1<<1);
static const int STATE_DIRTYPOOL = (1<<2);
static const int STATE_NEED_SNAPFLUSH = (1<<3);
- typedef compact_map<snapid_t, old_inode_t> old_inodes_t;
- string dn; // dentry
+ static const int STATE_EPHEMERAL_RANDOM = (1<<4);
+ std::string dn; // dentry
snapid_t dnfirst, dnlast;
version_t dnv{0};
- inode_t inode; // if it's not
+ CInode::mempool_inode inode; // if it's not XXX should not be part of mempool; wait for std::pmr to simplify
fragtree_t dirfragtree;
- map<string,bufferptr> xattrs;
- string symlink;
+ CInode::mempool_xattr_map xattrs;
+ std::string symlink;
snapid_t oldest_snap;
bufferlist snapbl;
__u8 state{0};
- old_inodes_t old_inodes;
-
- fullbit(const fullbit& o);
- const fullbit& operator=(const fullbit& o);
+ CInode::mempool_old_inode_map old_inodes; // XXX should not be part of mempool; wait for std::pmr to simplify
- fullbit(const string& d, snapid_t df, snapid_t dl,
- version_t v, const inode_t& i, const fragtree_t &dft,
- const map<string,bufferptr> &xa, const string& sym,
+ fullbit(std::string_view d, snapid_t df, snapid_t dl,
+ version_t v, const CInode::mempool_inode& i, const fragtree_t &dft,
+ const CInode::mempool_xattr_map &xa, std::string_view sym,
snapid_t os, const bufferlist &sbl, __u8 st,
- const old_inodes_t *oi = NULL) :
+ const CInode::mempool_old_inode_map *oi = NULL) :
dn(d), dnfirst(df), dnlast(dl), dnv(v), inode(i), xattrs(xa),
oldest_snap(os), state(st)
{
old_inodes = *oi;
snapbl = sbl;
}
- explicit fullbit(bufferlist::iterator &p) {
+ explicit fullbit(bufferlist::const_iterator &p) {
decode(p);
}
fullbit() {}
+ fullbit(const fullbit&) = delete;
~fullbit() {}
+ fullbit& operator=(const fullbit&) = delete;
void encode(bufferlist& bl, uint64_t features) const;
- void decode(bufferlist::iterator &bl);
+ void decode(bufferlist::const_iterator &bl);
void dump(Formatter *f) const;
- static void generate_test_instances(list<EMetaBlob::fullbit*>& ls);
+ static void generate_test_instances(std::list<EMetaBlob::fullbit*>& ls);
void update_inode(MDSRank *mds, CInode *in);
bool is_dirty() const { return (state & STATE_DIRTY); }
bool is_dirty_parent() const { return (state & STATE_DIRTYPARENT); }
bool is_dirty_pool() const { return (state & STATE_DIRTYPOOL); }
bool need_snapflush() const { return (state & STATE_NEED_SNAPFLUSH); }
+ bool is_export_ephemeral_random() const { return (state & STATE_EPHEMERAL_RANDOM); }
void print(ostream& out) const {
out << " fullbit dn " << dn << " [" << dnfirst << "," << dnlast << "] dnv " << dnv
/* remotebit - a dentry + remote inode link (i.e. just an ino)
*/
struct remotebit {
- string dn;
+ std::string dn;
snapid_t dnfirst, dnlast;
version_t dnv;
inodeno_t ino;
unsigned char d_type;
bool dirty;
- remotebit(const string& d, snapid_t df, snapid_t dl, version_t v, inodeno_t i, unsigned char dt, bool dr) :
+ remotebit(std::string_view d, snapid_t df, snapid_t dl, version_t v, inodeno_t i, unsigned char dt, bool dr) :
dn(d), dnfirst(df), dnlast(dl), dnv(v), ino(i), d_type(dt), dirty(dr) { }
- explicit remotebit(bufferlist::iterator &p) { decode(p); }
+ explicit remotebit(bufferlist::const_iterator &p) { decode(p); }
remotebit(): dnfirst(0), dnlast(0), dnv(0), ino(0),
d_type('\0'), dirty(false) {}
void encode(bufferlist& bl) const;
- void decode(bufferlist::iterator &bl);
+ void decode(bufferlist::const_iterator &bl);
void print(ostream& out) const {
out << " remotebit dn " << dn << " [" << dnfirst << "," << dnlast << "] dnv " << dnv
<< " ino " << ino
<< " dirty=" << dirty << std::endl;
}
void dump(Formatter *f) const;
- static void generate_test_instances(list<remotebit*>& ls);
+ static void generate_test_instances(std::list<remotebit*>& ls);
};
WRITE_CLASS_ENCODER(remotebit)
* nullbit - a null dentry
*/
struct nullbit {
- string dn;
+ std::string dn;
snapid_t dnfirst, dnlast;
version_t dnv;
bool dirty;
- nullbit(const string& d, snapid_t df, snapid_t dl, version_t v, bool dr) :
+ nullbit(std::string_view d, snapid_t df, snapid_t dl, version_t v, bool dr) :
dn(d), dnfirst(df), dnlast(dl), dnv(v), dirty(dr) { }
- explicit nullbit(bufferlist::iterator &p) { decode(p); }
+ explicit nullbit(bufferlist::const_iterator &p) { decode(p); }
nullbit(): dnfirst(0), dnlast(0), dnv(0), dirty(false) {}
void encode(bufferlist& bl) const;
- void decode(bufferlist::iterator &bl);
+ void decode(bufferlist::const_iterator &bl);
void dump(Formatter *f) const;
- static void generate_test_instances(list<nullbit*>& ls);
- void print(ostream& out) {
+ static void generate_test_instances(std::list<nullbit*>& ls);
+ void print(ostream& out) const {
out << " nullbit dn " << dn << " [" << dnfirst << "," << dnlast << "] dnv " << dnv
<< " dirty=" << dirty << std::endl;
}
private:
mutable bufferlist dnbl;
mutable bool dn_decoded;
- mutable list<ceph::shared_ptr<fullbit> > dfull;
- mutable list<remotebit> dremote;
- mutable list<nullbit> dnull;
+ mutable list<fullbit> dfull;
+ mutable vector<remotebit> dremote;
+ mutable vector<nullbit> dnull;
public:
dirlump() : state(0), nfull(0), nremote(0), nnull(0), dn_decoded(true) { }
+ dirlump(const dirlump&) = delete;
+ dirlump& operator=(const dirlump&) = delete;
bool is_complete() const { return state & STATE_COMPLETE; }
void mark_complete() { state |= STATE_COMPLETE; }
bool is_dirty_dft() { return state & STATE_DIRTYDFT; }
void mark_dirty_dft() { state |= STATE_DIRTYDFT; }
- const list<ceph::shared_ptr<fullbit> > &get_dfull() const { return dfull; }
- const list<remotebit> &get_dremote() const { return dremote; }
- const list<nullbit> &get_dnull() const { return dnull; }
+ const list<fullbit> &get_dfull() const { return dfull; }
+ list<fullbit> &_get_dfull() { return dfull; }
+ const vector<remotebit> &get_dremote() const { return dremote; }
+ const vector<nullbit> &get_dnull() const { return dnull; }
- void add_dnull(nullbit const &n) { dnull.push_back(n); };
- void add_dfull(ceph::shared_ptr<fullbit> const &p) { dfull.push_back(p); };
- void add_dremote(remotebit const &r) { dremote.push_back(r); };
+ template< class... Args>
+ void add_dfull(Args&&... args) {
+ dfull.emplace_back(std::forward<Args>(args)...);
+ }
+ template< class... Args>
+ void add_dremote(Args&&... args) {
+ dremote.emplace_back(std::forward<Args>(args)...);
+ }
+ template< class... Args>
+ void add_dnull(Args&&... args) {
+ dnull.emplace_back(std::forward<Args>(args)...);
+ }
- void print(dirfrag_t dirfrag, ostream& out) {
+ void print(dirfrag_t dirfrag, ostream& out) const {
out << "dirlump " << dirfrag << " v " << fnode.version
<< " state " << state
<< " num " << nfull << "/" << nremote << "/" << nnull
<< std::endl;
_decode_bits();
- for (list<ceph::shared_ptr<fullbit> >::iterator p = dfull.begin(); p != dfull.end(); ++p)
- (*p)->print(out);
- for (list<remotebit>::iterator p = dremote.begin(); p != dremote.end(); ++p)
- p->print(out);
- for (list<nullbit>::iterator p = dnull.begin(); p != dnull.end(); ++p)
- p->print(out);
+ for (const auto& p : dfull)
+ p.print(out);
+ for (const auto& p : dremote)
+ p.print(out);
+ for (const auto& p : dnull)
+ p.print(out);
}
string state_string() const {
// if this changes, update the versioning in encode for it!
void _encode_bits(uint64_t features) const {
+ using ceph::encode;
if (!dn_decoded) return;
- ::encode(dfull, dnbl, features);
- ::encode(dremote, dnbl);
- ::encode(dnull, dnbl);
+ encode(dfull, dnbl, features);
+ encode(dremote, dnbl);
+ encode(dnull, dnbl);
}
void _decode_bits() const {
+ using ceph::decode;
if (dn_decoded) return;
- bufferlist::iterator p = dnbl.begin();
- ::decode(dfull, p);
- ::decode(dremote, p);
- ::decode(dnull, p);
+ auto p = dnbl.cbegin();
+ decode(dfull, p);
+ decode(dremote, p);
+ decode(dnull, p);
dn_decoded = true;
}
void encode(bufferlist& bl, uint64_t features) const;
- void decode(bufferlist::iterator &bl);
+ void decode(bufferlist::const_iterator &bl);
void dump(Formatter *f) const;
- static void generate_test_instances(list<dirlump*>& ls);
+ static void generate_test_instances(std::list<dirlump*>& ls);
};
WRITE_CLASS_ENCODER_FEATURES(dirlump)
// my lumps. preserve the order we added them in a list.
- list<dirfrag_t> lump_order;
+ vector<dirfrag_t> lump_order;
map<dirfrag_t, dirlump> lump_map;
- list<ceph::shared_ptr<fullbit> > roots;
+ list<fullbit> roots;
public:
- list<pair<__u8,version_t> > table_tids; // tableclient transactions
+ vector<pair<__u8,version_t> > table_tids; // tableclient transactions
inodeno_t opened_ino;
public:
inodeno_t renamed_dirino;
- list<frag_t> renamed_dir_frags;
+ vector<frag_t> renamed_dir_frags;
private:
// ino (pre)allocation. may involve both inotable AND session state.
entity_name_t client_name; // session
// inodes i've truncated
- list<inodeno_t> truncate_start; // start truncate
- map<inodeno_t, log_segment_seq_t> truncate_finish; // finished truncate (started in segment blah)
+ vector<inodeno_t> truncate_start; // start truncate
+ map<inodeno_t, LogSegment::seq_t> truncate_finish; // finished truncate (started in segment blah)
public:
vector<inodeno_t> destroyed_inodes;
private:
// idempotent op(s)
- list<pair<metareqid_t,uint64_t> > client_reqs;
- list<pair<metareqid_t,uint64_t> > client_flushes;
+ vector<pair<metareqid_t,uint64_t> > client_reqs;
+ vector<pair<metareqid_t,uint64_t> > client_flushes;
public:
void encode(bufferlist& bl, uint64_t features) const;
- void decode(bufferlist::iterator& bl);
+ void decode(bufferlist::const_iterator& bl);
void get_inodes(std::set<inodeno_t> &inodes) const;
void get_paths(std::vector<std::string> &paths) const;
void get_dentries(std::map<dirfrag_t, std::set<std::string> > &dentries) const;
entity_name_t get_client_name() const {return client_name;}
void dump(Formatter *f) const;
- static void generate_test_instances(list<EMetaBlob*>& ls);
+ static void generate_test_instances(std::list<EMetaBlob*>& ls);
// soft stateadd
uint64_t last_subtree_map;
uint64_t event_seq;
// for replay, in certain cases
//LogSegment *_segment;
- explicit EMetaBlob(MDLog *mdl = 0); // defined in journal.cc
+ EMetaBlob() : opened_ino(0), renamed_dirino(0),
+ inotablev(0), sessionmapv(0), allocated_ino(0),
+ last_subtree_map(0), event_seq(0)
+ {}
+ EMetaBlob(const EMetaBlob&) = delete;
~EMetaBlob() { }
+ EMetaBlob& operator=(const EMetaBlob&) = delete;
void print(ostream& out) {
- for (list<dirfrag_t>::iterator p = lump_order.begin();
- p != lump_order.end();
- ++p) {
- lump_map[*p].print(*p, out);
- }
+ for (const auto &p : lump_order)
+ lump_map[p].print(p, out);
}
void add_client_req(metareqid_t r, uint64_t tid=0) {
}
void add_opened_ino(inodeno_t ino) {
- assert(!opened_ino);
+ ceph_assert(!opened_ino);
opened_ino = ino;
}
void add_null_dentry(dirlump& lump, CDentry *dn, bool dirty) {
// add the dir
lump.nnull++;
- lump.add_dnull(nullbit(dn->get_name(),
- dn->first, dn->last,
- dn->get_projected_version(),
- dirty));
+ lump.add_dnull(dn->get_name(), dn->first, dn->last,
+ dn->get_projected_version(), dirty);
}
void add_remote_dentry(CDentry *dn, bool dirty) {
rdt = dn->get_projected_linkage()->get_remote_d_type();
}
lump.nremote++;
- lump.add_dremote(remotebit(dn->get_name(),
- dn->first, dn->last,
- dn->get_projected_version(),
- rino, rdt,
- dirty));
+ lump.add_dremote(dn->get_name(), dn->first, dn->last,
+ dn->get_projected_version(), rino, rdt, dirty);
}
// return remote pointer to to-be-journaled inode
if (!in)
in = dn->get_projected_linkage()->get_inode();
+ if (in->is_ephemeral_rand()) {
+ state |= fullbit::STATE_EPHEMERAL_RANDOM;
+ }
+
// make note of where this inode was last journaled
in->last_journaled = event_seq;
//cout << "journaling " << in->inode.ino << " at " << my_offset << std::endl;
- const inode_t *pi = in->get_projected_inode();
+ const auto pi = in->get_projected_inode();
if ((state & fullbit::STATE_DIRTY) && pi->is_backtrace_updated())
state |= fullbit::STATE_DIRTYPARENT;
sr->encode(snapbl);
lump.nfull++;
- lump.add_dfull(ceph::shared_ptr<fullbit>(new fullbit(dn->get_name(),
- dn->first, dn->last,
- dn->get_projected_version(),
- *pi, in->dirfragtree,
- *in->get_projected_xattrs(),
- in->symlink,
- in->oldest_snap, snapbl,
- state, &in->old_inodes)));
+ lump.add_dfull(dn->get_name(), dn->first, dn->last, dn->get_projected_version(),
+ *pi, in->dirfragtree, *in->get_projected_xattrs(), in->symlink,
+ in->oldest_snap, snapbl, state, &in->old_inodes);
}
// convenience: primary or remote? figure it out.
add_null_dentry(dn, dirty);
return;
}
- assert(dn->get_projected_linkage()->is_primary());
+ ceph_assert(dn->get_projected_linkage()->is_primary());
add_primary_dentry(dn, 0, dirty, dirty_parent, dirty_pool);
}
- void add_root(bool dirty, CInode *in, const inode_t *pi=0, fragtree_t *pdft=0, bufferlist *psnapbl=0,
- map<string,bufferptr> *px=0) {
+ void add_root(bool dirty, CInode *in) {
in->last_journaled = event_seq;
//cout << "journaling " << in->inode.ino << " at " << my_offset << std::endl;
- if (!pi) pi = in->get_projected_inode();
- if (!pdft) pdft = &in->dirfragtree;
- if (!px) px = in->get_projected_xattrs();
+ const auto& pi = *(in->get_projected_inode());
+ const auto& pdft = in->dirfragtree;
+ const auto& px = *(in->get_projected_xattrs());
bufferlist snapbl;
- if (psnapbl)
- snapbl = *psnapbl;
- else
- in->encode_snap_blob(snapbl);
+ const sr_t *sr = in->get_projected_srnode();
+ if (sr)
+ sr->encode(snapbl);
- for (list<ceph::shared_ptr<fullbit> >::iterator p = roots.begin(); p != roots.end(); ++p) {
- if ((*p)->inode.ino == in->ino()) {
+ for (auto p = roots.begin(); p != roots.end(); ++p) {
+ if (p->inode.ino == in->ino()) {
roots.erase(p);
break;
}
}
string empty;
- roots.push_back(ceph::shared_ptr<fullbit>(new fullbit(empty, in->first, in->last, 0, *pi,
- *pdft, *px, in->symlink,
- in->oldest_snap, snapbl,
- dirty ? fullbit::STATE_DIRTY : 0,
- &in->old_inodes)));
+ roots.emplace_back(empty, in->first, in->last, 0, pi, pdft, px, in->symlink,
+ in->oldest_snap, snapbl, (dirty ? fullbit::STATE_DIRTY : 0),
+ &in->old_inodes);
}
dirlump& add_dir(CDir *dir, bool dirty, bool complete=false) {