This requires making the late-decoded attributes mutable.
The motivation is to allow get_paths and all the code downstream
of that to be const too.
Signed-off-by: John Spray <john.spray@inktank.com>
* If the subclass embeds a MetaBlob, return it here so that
* tools can examine metablobs while traversing lists of LogEvent.
*/
- virtual EMetaBlob *get_metablob() {return NULL;}
+ virtual EMetaBlob const *get_metablob() const {return NULL;}
};
inline ostream& operator<<(ostream& out, LogEvent& le) {
private:
mutable bufferlist dnbl;
- bool dn_decoded;
- list<ceph::shared_ptr<fullbit> > dfull;
- list<remotebit> dremote;
- list<nullbit> dnull;
+ mutable bool dn_decoded;
+ mutable list<ceph::shared_ptr<fullbit> > dfull;
+ mutable list<remotebit> dremote;
+ mutable list<nullbit> dnull;
public:
dirlump() : state(0), nfull(0), nremote(0), nnull(0), dn_decoded(true) { }
bool is_dirty_dft() { return state & STATE_DIRTYDFT; }
void mark_dirty_dft() { state |= STATE_DIRTYDFT; }
- list<ceph::shared_ptr<fullbit> > &get_dfull() { return dfull; }
- list<remotebit> &get_dremote() { return dremote; }
- list<nullbit> &get_dnull() { return dnull; }
+ 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; }
+
+ 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); };
void print(dirfrag_t dirfrag, ostream& out) {
out << "dirlump " << dirfrag << " v " << fnode.version
::encode(dremote, dnbl);
::encode(dnull, dnbl);
}
- void _decode_bits() {
+ void _decode_bits() const {
if (dn_decoded) return;
bufferlist::iterator p = dnbl.begin();
::decode(dfull, p);
public:
void encode(bufferlist& bl) const;
void decode(bufferlist::iterator& bl);
- void get_inodes(std::set<inodeno_t> &inodes);
- void get_paths(std::vector<std::string> &paths);
- void get_dentries(std::map<dirfrag_t, std::set<std::string> > &dentries);
+ 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;
void add_null_dentry(dirlump& lump, CDentry *dn, bool dirty) {
// add the dir
lump.nnull++;
- lump.get_dnull().push_back(nullbit(dn->get_name(),
- dn->first, dn->last,
- dn->get_projected_version(),
- dirty));
+ lump.add_dnull(nullbit(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.get_dremote().push_back(remotebit(dn->get_name(),
- dn->first, dn->last,
- dn->get_projected_version(),
- rino, rdt,
- dirty));
+ lump.add_dremote(remotebit(dn->get_name(),
+ dn->first, dn->last,
+ dn->get_projected_version(),
+ rino, rdt,
+ dirty));
}
// return remote pointer to to-be-journaled inode
sr->encode(snapbl);
lump.nfull++;
- lump.get_dfull().push_back(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, snapbl,
- state,
- &in->old_inodes)));
+ 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, snapbl,
+ state,
+ &in->old_inodes)));
}
// convenience: primary or remote? figure it out.
void update_segment();
void replay(MDS *mds);
- EMetaBlob *get_metablob() {return &metablob;}
+ EMetaBlob const *get_metablob() const {return &metablob;}
};
#endif
void update_segment();
void replay(MDS *mds);
- EMetaBlob *get_metablob() {return &metablob;}
+ EMetaBlob const *get_metablob() const {return &metablob;}
};
#endif
* dirlumps, and the inodes of the dirs themselves.
*/
void EMetaBlob::get_inodes(
- std::set<inodeno_t> &inodes)
+ std::set<inodeno_t> &inodes) const
{
// For all dirlumps in this metablob
- for (std::map<dirfrag_t, dirlump>::iterator i = lump_map.begin(); i != lump_map.end(); ++i) {
+ for (std::map<dirfrag_t, dirlump>::const_iterator i = lump_map.begin(); i != lump_map.end(); ++i) {
// Record inode of dirlump
inodeno_t const dir_ino = i->first.ino;
inodes.insert(dir_ino);
// Decode dirlump bits
- dirlump &dl = i->second;
+ dirlump const &dl = i->second;
dl._decode_bits();
// Record inodes of fullbits
- list<ceph::shared_ptr<fullbit> > &fb_list = dl.get_dfull();
+ list<ceph::shared_ptr<fullbit> > const &fb_list = dl.get_dfull();
for (list<ceph::shared_ptr<fullbit> >::const_iterator
iter = fb_list.begin(); iter != fb_list.end(); ++iter) {
inodes.insert((*iter)->inode.ino);
}
// Record inodes of remotebits
- list<remotebit> &rb_list = dl.get_dremote();
+ list<remotebit> const &rb_list = dl.get_dremote();
for (list<remotebit>::const_iterator
iter = rb_list.begin(); iter != rb_list.end(); ++iter) {
inodes.insert(iter->ino);
* Get a map of dirfrag to set of dentries in that dirfrag which are
* touched in this operation.
*/
-void EMetaBlob::get_dentries(std::map<dirfrag_t, std::set<std::string> > &dentries)
+void EMetaBlob::get_dentries(std::map<dirfrag_t, std::set<std::string> > &dentries) const
{
- for (std::map<dirfrag_t, dirlump>::iterator i = lump_map.begin(); i != lump_map.end(); ++i) {
- dirlump &dl = i->second;
+ for (std::map<dirfrag_t, dirlump>::const_iterator i = lump_map.begin(); i != lump_map.end(); ++i) {
+ dirlump const &dl = i->second;
dirfrag_t const &df = i->first;
// Get all bits
dl._decode_bits();
- list<ceph::shared_ptr<fullbit> > &fb_list = dl.get_dfull();
- list<nullbit> &nb_list = dl.get_dnull();
- list<remotebit> &rb_list = dl.get_dremote();
+ list<ceph::shared_ptr<fullbit> > const &fb_list = dl.get_dfull();
+ list<nullbit> const &nb_list = dl.get_dnull();
+ list<remotebit> const &rb_list = dl.get_dremote();
// For all bits, store dentry
for (list<ceph::shared_ptr<fullbit> >::const_iterator
* Calculate all paths that we can infer are touched by this metablob. Only uses
* information local to this metablob so it may only be the path within the
* subtree.
- *
- * This is not const because the contained dirlump and 'bit' objects
- * are modified by being decoded.
*/
void EMetaBlob::get_paths(
- std::vector<std::string> &paths)
+ std::vector<std::string> &paths) const
{
// Each dentry has a 'location' which is a 2-tuple of parent inode and dentry name
typedef std::pair<inodeno_t, std::string> Location;
// First pass
// ==========
// Build a tiny local metadata cache for the path structure in this metablob
- for (std::map<dirfrag_t, dirlump>::iterator i = lump_map.begin(); i != lump_map.end(); ++i) {
+ for (std::map<dirfrag_t, dirlump>::const_iterator i = lump_map.begin(); i != lump_map.end(); ++i) {
inodeno_t const dir_ino = i->first.ino;
- dirlump &dl = i->second;
+ dirlump const &dl = i->second;
dl._decode_bits();
- list<ceph::shared_ptr<fullbit> > &fb_list = dl.get_dfull();
- list<nullbit> &nb_list = dl.get_dnull();
- list<remotebit> &rb_list = dl.get_dremote();
+ list<ceph::shared_ptr<fullbit> > const &fb_list = dl.get_dfull();
+ list<nullbit> const &nb_list = dl.get_dnull();
+ list<remotebit> const &rb_list = dl.get_dremote();
for (list<ceph::shared_ptr<fullbit> >::const_iterator
iter = fb_list.begin(); iter != fb_list.end(); ++iter) {
// Second pass
// ===========
// Output paths for all childless nodes in the metablob
- for (std::map<dirfrag_t, dirlump>::iterator i = lump_map.begin(); i != lump_map.end(); ++i) {
+ for (std::map<dirfrag_t, dirlump>::const_iterator i = lump_map.begin(); i != lump_map.end(); ++i) {
inodeno_t const dir_ino = i->first.ino;
- dirlump &dl = i->second;
+ dirlump const &dl = i->second;
dl._decode_bits();
- list<ceph::shared_ptr<fullbit> > &fb_list = dl.get_dfull();
+ list<ceph::shared_ptr<fullbit> > const &fb_list = dl.get_dfull();
for (list<ceph::shared_ptr<fullbit> >::const_iterator
iter = fb_list.begin(); iter != fb_list.end(); ++iter) {
std::string const &dentry = (*iter)->dn;
}
}
- list<nullbit> &nb_list = dl.get_dnull();
+ list<nullbit> const &nb_list = dl.get_dnull();
for (list<nullbit>::const_iterator
iter = nb_list.begin(); iter != nb_list.end(); ++iter) {
std::string const &dentry = iter->dn;
leaf_locations.push_back(Location(dir_ino, dentry));
}
- list<remotebit> &rb_list = dl.get_dremote();
+ list<remotebit> const &rb_list = dl.get_dremote();
for (list<remotebit>::const_iterator
iter = rb_list.begin(); iter != rb_list.end(); ++iter) {
std::string const &dentry = iter->dn;
lump._decode_bits();
// full dentry+inode pairs
- for (list<ceph::shared_ptr<fullbit> >::iterator pp = lump.get_dfull().begin();
+ for (list<ceph::shared_ptr<fullbit> >::const_iterator pp = lump.get_dfull().begin();
pp != lump.get_dfull().end();
++pp) {
ceph::shared_ptr<fullbit> p = *pp;
}
// remote dentries
- for (list<remotebit>::iterator p = lump.get_dremote().begin();
+ for (list<remotebit>::const_iterator p = lump.get_dremote().begin();
p != lump.get_dremote().end();
++p) {
CDentry *dn = dir->lookup_exact_snap(p->dn, p->dnlast);
}
// null dentries
- for (list<nullbit>::iterator p = lump.get_dnull().begin();
+ for (list<nullbit>::const_iterator p = lump.get_dnull().begin();
p != lump.get_dnull().end();
++p) {
CDentry *dn = dir->lookup_exact_snap(p->dn, p->dnlast);
{
for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
std::vector<std::string> ev_paths;
- EMetaBlob *emb = i->second.log_event->get_metablob();
+ EMetaBlob const *emb = i->second.log_event->get_metablob();
if (emb) {
emb->get_paths(ev_paths);
}
/* Filtering by client */
if (client_name.num()) {
- EMetaBlob *metablob = le.get_metablob();
+ EMetaBlob const *metablob = le.get_metablob();
if (metablob) {
if (metablob->get_client_name() != client_name) {
return false;
/* Filtering by inode */
if (inode) {
- EMetaBlob *metablob = le.get_metablob();
+ EMetaBlob const *metablob = le.get_metablob();
if (metablob) {
std::set<inodeno_t> inodes;
metablob->get_inodes(inodes);
/* Filtering by frag and dentry */
if (!frag_dentry.empty() || frag.ino) {
- EMetaBlob *metablob = le.get_metablob();
+ EMetaBlob const *metablob = le.get_metablob();
if (metablob) {
std::map<dirfrag_t, std::set<std::string> > dentries;
metablob->get_dentries(dentries);
/* Filtering by file path */
if (!path_expr.empty()) {
- EMetaBlob *metablob = le.get_metablob();
+ EMetaBlob const *metablob = le.get_metablob();
if (metablob) {
std::vector<std::string> paths;
metablob->get_paths(paths);
for (JournalScanner::EventMap::iterator i = js.events.begin(); i != js.events.end(); ++i) {
LogEvent *le = i->second.log_event;
- EMetaBlob *mb = le->get_metablob();
+ EMetaBlob const *mb = le->get_metablob();
if (mb) {
replay_offline(*mb, dry_run);
}
}
-int JournalTool::replay_offline(EMetaBlob &metablob, bool const dry_run)
+int JournalTool::replay_offline(EMetaBlob const &metablob, bool const dry_run)
{
int r;
// Replay roots
- for (list<ceph::shared_ptr<EMetaBlob::fullbit> >::iterator p = metablob.roots.begin(); p != metablob.roots.end(); ++p) {
- EMetaBlob::fullbit &fb = *(*p);
+ for (list<ceph::shared_ptr<EMetaBlob::fullbit> >::const_iterator p = metablob.roots.begin(); p != metablob.roots.end(); ++p) {
+ EMetaBlob::fullbit const &fb = *(*p);
inodeno_t ino = fb.inode.ino;
dout(4) << __func__ << ": updating root 0x" << std::hex << ino << std::dec << dendl;
// indicate renamed directories)
// Replay fullbits (dentry+inode)
- for (list<dirfrag_t>::iterator lp = metablob.lump_order.begin(); lp != metablob.lump_order.end(); ++lp) {
- dirfrag_t &frag = *lp;
- EMetaBlob::dirlump &lump = metablob.lump_map[frag];
+ for (list<dirfrag_t>::const_iterator lp = metablob.lump_order.begin(); lp != metablob.lump_order.end(); ++lp) {
+ dirfrag_t const &frag = *lp;
+ EMetaBlob::dirlump const &lump = metablob.lump_map.find(frag)->second;
lump._decode_bits();
object_t frag_object_id = InodeStore::get_object_name(frag.ino, frag.frag, "");
}
// Try to get the existing dentry
- list<ceph::shared_ptr<EMetaBlob::fullbit> > &fb_list = lump.get_dfull();
- for (list<ceph::shared_ptr<EMetaBlob::fullbit> >::iterator fbi = fb_list.begin(); fbi != fb_list.end(); ++fbi) {
- EMetaBlob::fullbit &fb = *(*fbi);
+ list<ceph::shared_ptr<EMetaBlob::fullbit> > const &fb_list = lump.get_dfull();
+ for (list<ceph::shared_ptr<EMetaBlob::fullbit> >::const_iterator fbi = fb_list.begin(); fbi != fb_list.end(); ++fbi) {
+ EMetaBlob::fullbit const &fb = *(*fbi);
// Get a key like "foobar_head"
std::string key;
}
}
- list<EMetaBlob::nullbit> &nb_list = lump.get_dnull();
+ list<EMetaBlob::nullbit> const &nb_list = lump.get_dnull();
for (list<EMetaBlob::nullbit>::const_iterator
iter = nb_list.begin(); iter != nb_list.end(); ++iter) {
EMetaBlob::nullbit const &nb = *iter;
}
}
- for (std::vector<inodeno_t>::iterator i = metablob.destroyed_inodes.begin();
+ for (std::vector<inodeno_t>::const_iterator i = metablob.destroyed_inodes.begin();
i != metablob.destroyed_inodes.end(); ++i) {
dout(4) << "Destroyed inode: " << *i << dendl;
// TODO: if it was a dir, then delete its dirfrag objects
librados::IoCtx io;
// Metadata backing store manipulation
- int replay_offline(EMetaBlob &metablob, bool const dry_run);
+ int replay_offline(EMetaBlob const &metablob, bool const dry_run);
// Splicing
int erase_region(JournalScanner const &jp, uint64_t const pos, uint64_t const length);