if (mode == TO_AUTH_SUBTREE_ROOT) {
// subtree root?
- if (dir->is_subtree_root() &&
- !dir->state_test(CDir::STATE_EXPORTBOUND)) {
- if (dir->is_auth() && !dir->is_ambiguous_auth() ) {
- if (dir->state_test(CDir::STATE_AUXSUBTREE) &&
- dir->get_dir_auth().first == diri->authority().first) {
- // auxiliary subtree. treat it as normal dirfrag
- dout(20) << "EMetaBlob::add_dir_context(" << dir << ") auxiliary subtree " << dendl;
+ if (dir->is_subtree_root()) {
+ // match logic in MDCache::create_subtree_map()
+ if (dir->get_dir_auth().first == mds->get_nodeid()) {
+ mds_authority_t parent_auth = parent ? parent->authority() : CDIR_AUTH_UNDEF;
+ if (parent_auth.first == dir->get_dir_auth().first) {
+ if (parent_auth.second == CDIR_AUTH_UNKNOWN &&
+ !dir->is_ambiguous_dir_auth() &&
+ !dir->state_test(CDir::STATE_EXPORTBOUND) &&
+ !dir->state_test(CDir::STATE_AUXSUBTREE) &&
+ !diri->state_test(CInode::STATE_AMBIGUOUSAUTH)) {
+ dout(0) << "EMetaBlob::add_dir_context unexpected subtree " << *dir << dendl;
+ assert(0);
+ }
+ dout(20) << "EMetaBlob::add_dir_context(" << dir << ") ambiguous or transient subtree " << dendl;
} else {
// it's an auth subtree, we don't need maybe (if any), and we're done.
dout(20) << "EMetaBlob::add_dir_context(" << dir << ") reached unambig auth subtree, don't need " << maybe
maybenot = false;
}
}
-
+
// was the inode journaled in this blob?
if (event_seq && diri->last_journaled == event_seq) {
dout(20) << "EMetaBlob::add_dir_context(" << dir << ") already have diri this blob " << *diri << dendl;
inode.dump(f);
f->close_section(); // inode
f->open_object_section("xattrs");
- for (map<string, bufferptr>::const_iterator iter = xattrs.begin();
- iter != xattrs.end(); ++iter) {
- string s(iter->second.c_str(), iter->second.length());
- f->dump_string(iter->first.c_str(), s);
+ for (const auto &p : xattrs) {
+ std::string s(p.second.c_str(), p.second.length());
+ f->dump_string(p.first.c_str(), s);
}
f->close_section(); // xattrs
if (inode.is_symlink()) {
f->dump_string("state", state_string());
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) {
+ for (const auto &p : old_inodes) {
f->open_object_section("inode");
- f->dump_int("snapid", iter->first);
- iter->second.dump(f);
+ f->dump_int("snapid", p.first);
+ p.second.dump(f);
f->close_section(); // inode
}
f->close_section(); // old inodes
void EMetaBlob::fullbit::generate_test_instances(list<EMetaBlob::fullbit*>& ls)
{
- inode_t inode;
+ CInode::mempool_inode inode;
fragtree_t fragtree;
- map<string,bufferptr> empty_xattrs;
+ CInode::mempool_xattr_map empty_xattrs;
bufferlist empty_snapbl;
fullbit *sample = new fullbit("/testdn", 0, 0, 0,
inode, fragtree, empty_xattrs, "", 0, empty_snapbl,
{
in->inode = inode;
in->xattrs = xattrs;
+ in->maybe_export_pin();
if (in->inode.is_dir()) {
if (!(in->dirfragtree == dirfragtree)) {
dout(10) << "EMetaBlob::fullbit::update_inode dft " << in->dirfragtree << " -> "
}
}
} else if (in->inode.is_symlink()) {
- in->symlink = symlink;
+ in->symlink = mempool::mds_co::string(boost::string_view(symlink));
}
in->old_inodes = old_inodes;
if (!in->old_inodes.empty()) {
for (list<ceph::shared_ptr<fullbit> >::const_iterator
iter = fb_list.begin(); iter != fb_list.end(); ++iter) {
- std::string const &dentry = (*iter)->dn;
- children[dir_ino].push_back(dentry);
- ino_locations[(*iter)->inode.ino] = Location(dir_ino, dentry);
+ boost::string_view dentry = (*iter)->dn;
+ children[dir_ino].emplace_back(dentry);
+ ino_locations[(*iter)->inode.ino] = Location(dir_ino, std::string(dentry));
}
for (list<nullbit>::const_iterator
iter = nb_list.begin(); iter != nb_list.end(); ++iter) {
- std::string const &dentry = iter->dn;
- children[dir_ino].push_back(dentry);
+ boost::string_view dentry = iter->dn;
+ children[dir_ino].emplace_back(dentry);
}
for (list<remotebit>::const_iterator
iter = rb_list.begin(); iter != rb_list.end(); ++iter) {
- std::string const &dentry = iter->dn;
- children[dir_ino].push_back(dentry);
+ boost::string_view dentry = iter->dn;
+ children[dir_ino].emplace_back(dentry);
}
}
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;
+ std::string dentry((*iter)->dn);
children[dir_ino].push_back(dentry);
- ino_locations[(*iter)->inode.ino] = Location(dir_ino, dentry);
+ ino_locations[(*iter)->inode.ino] = Location(dir_ino, std::string(dentry));
if (children.find((*iter)->inode.ino) == children.end()) {
- leaf_locations.push_back(Location(dir_ino, dentry));
+ leaf_locations.push_back(Location(dir_ino, std::string(dentry)));
}
}
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));
+ boost::string_view dentry = iter->dn;
+ leaf_locations.push_back(Location(dir_ino, std::string(dentry)));
}
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;
- leaf_locations.push_back(Location(dir_ino, dentry));
+ boost::string_view dentry = iter->dn;
+ leaf_locations.push_back(Location(dir_ino, std::string(dentry)));
}
}
dout(0) << ss.str() << dendl;
mds->clog->warn(ss);
}
- dir->unlink_inode(dn);
- mds->mdcache->touch_dentry_bottom(dn);
+ dir->unlink_inode(dn, false);
}
if (unlinked.count(in))
linked.insert(in);
if (dn->get_linkage()->get_inode() != in && in->get_parent_dn()) {
dout(10) << "EMetaBlob.replay unlinking " << *in << dendl;
unlinked[in] = in->get_parent_dir();
- CDentry *unlinked_dn = in->get_parent_dn();
in->get_parent_dir()->unlink_inode(in->get_parent_dn());
- mds->mdcache->touch_dentry_bottom(unlinked_dn);
}
if (dn->get_linkage()->get_inode() != in) {
if (!dn->get_linkage()->is_null()) { // note: might be remote. as with stray reintegration.
dout(0) << ss.str() << dendl;
mds->clog->warn(ss);
}
- dir->unlink_inode(dn);
- mds->mdcache->touch_dentry_bottom(dn);
+ dir->unlink_inode(dn, false);
}
if (unlinked.count(in))
linked.insert(in);
<< " " << *dn->get_linkage()->get_inode() << " should be remote " << p->ino;
dout(0) << ss.str() << dendl;
}
- dir->unlink_inode(dn);
- mds->mdcache->touch_dentry_bottom(dn);
+ dir->unlink_inode(dn, false);
}
dir->link_remote_inode(dn, p->ino, p->d_type);
dn->set_version(p->dnv);
if (dn->get_linkage()->is_primary())
unlinked[in] = dir;
dir->unlink_inode(dn);
- mds->mdcache->touch_dentry_bottom(dn);
}
}
dn->set_version(p->dnv);
// Make null dentries the first things we trim
dout(10) << "EMetaBlob.replay pushing to bottom of lru " << *dn << dendl;
- mds->mdcache->touch_dentry_bottom(dn);
}
}
dir = renamed_diri->get_or_open_dirfrag(mds->mdcache, *p);
dout(10) << " creating new rename import bound " << *dir << dendl;
dir->state_clear(CDir::STATE_AUTH);
- mds->mdcache->adjust_subtree_auth(dir, CDIR_AUTH_UNDEF, false);
+ mds->mdcache->adjust_subtree_auth(dir, CDIR_AUTH_UNDEF);
}
}
if (parent) {
dout(10) << "EMetaBlob.replay unlinked from dentry " << *parent << dendl;
assert(parent->get_linkage()->is_null());
- mds->mdcache->touch_dentry_bottom(parent);
}
} else {
dout(10) << "EMetaBlob.replay destroyed " << *p << ", not in cache" << dendl;
void EExport::encode(bufferlist& bl, uint64_t features) const
{
- ENCODE_START(3, 3, bl);
+ ENCODE_START(4, 3, bl);
::encode(stamp, bl);
::encode(metablob, bl, features);
::encode(base, bl);
::encode(bounds, bl);
+ ::encode(target, bl);
ENCODE_FINISH(bl);
}
::decode(metablob, bl);
::decode(base, bl);
::decode(bounds, bl);
+ if (struct_v >= 4)
+ ::decode(target, bl);
DECODE_FINISH(bl);
}
bufferlist::iterator blp = client_map.begin();
::decode(cm, blp);
mds->sessionmap.open_sessions(cm);
- assert(mds->sessionmap.get_version() == cmapv);
+ if (mds->sessionmap.get_version() != cmapv)
+ {
+ derr << "sessionmap version " << mds->sessionmap.get_version()
+ << " != cmapv " << cmapv << dendl;
+ mds->clog->error() << "failure replaying journal (EImportStart)";
+ mds->damaged();
+ ceph_abort(); // Should be unreachable because damaged() calls respawn()
+ }
mds->sessionmap.set_projected(mds->sessionmap.get_version());
}
update_segment();
}
void EImportStart::encode(bufferlist &bl, uint64_t features) const {
- ENCODE_START(3, 3, bl);
+ ENCODE_START(4, 3, bl);
::encode(stamp, bl);
::encode(base, bl);
::encode(metablob, bl, features);
::encode(bounds, bl);
::encode(cmapv, bl);
::encode(client_map, bl);
+ ::encode(from, bl);
ENCODE_FINISH(bl);
}
::decode(bounds, bl);
::decode(cmapv, bl);
::decode(client_map, bl);
+ if (struct_v >= 4)
+ ::decode(from, bl);
DECODE_FINISH(bl);
}