for (auto &p : *dir) {
CDentry *dn = p.second;
CInode *in = dn->get_linkage()->get_inode();
+ CInode *ref_in = dn->get_linkage()->get_referent_inode();
num_exported++;
continue;
}
+ if (dn->get_linkage()->is_referent_remote()) {
+ // referent inode
+ ceph_assert(ref_in);
+ exportbl.append("r", 1); // referent inode dentry
+ ENCODE_START(2, 1, exportbl);
+ encode_export_inode(ref_in, exportbl, exported_client_map, exported_client_metadata_map); // encode, and (update state for) export
+ encode(dn->alternate_name, exportbl);
+ ENCODE_FINISH(exportbl);
+ continue;
+ }
// primary link
// -- inode
exportbl.append("i", 1); // inode dentry
// subdirs?
auto&& dirs = in->get_nested_dirfrags();
subdirs.insert(std::end(subdirs), std::begin(dirs), std::end(dirs));
+ } else if (dn->get_linkage()->is_referent_remote()) { //referent inode ?
+ CInode *ref_in = dn->get_linkage()->get_referent_inode();
+ finish_export_inode(ref_in, peer, peer_imported[ref_in->ino()], finished);
+ // referent inode - no subdirs
}
mdcache->touch_dentry_bottom(dn); // move dentry to tail of LRU
}
// link before state -- or not! -sage
- if (dn->get_linkage()->get_inode() != in) {
+ if (in->get_remote_ino()) { //referent inode ?
+ dout(20) << __func__ << " linking decoded referent_inode=" << *in << " remote_inode=" << in->get_remote_ino() << dendl;
+ if (dn->get_linkage()->get_referent_inode() != in) {
+ ceph_assert(!dn->get_linkage()->get_referent_inode());
+ dout(20) << __func__ << " null dentry_linkage, linking decode referent_inode, linkage referent_inode=" << dn->get_linkage()->get_referent_inode() << dendl;
+ dn->dir->link_referent_inode(dn, in, in->get_remote_ino(), in->d_type());
+ } else {
+ dout(20) << __func__ << " non-null dentry_linkage, validating decoded referent_inode against existing" << dendl;
+ ceph_assert(dn->get_linkage()->get_remote_ino() == in->get_remote_ino());
+ ceph_assert(dn->get_linkage()->get_referent_ino() == in->ino());
+ }
+ } else if (dn->get_linkage()->get_inode() != in) {
ceph_assert(!dn->get_linkage()->get_inode());
dn->dir->link_primary_inode(dn, in);
}
peer_exports, updated_scatterlocks);
}
}
+ else if (icode == 'R' || icode == 'r') {
+ // remote link with referent inode
+ ceph_assert(le);
+ if (icode == 'r') {
+ DECODE_START(2, blp);
+ decode_import_inode(dn, blp, oldauth, ls,
+ peer_exports, updated_scatterlocks);
+ ceph_assert(!dn->is_projected());
+ decode(dn->alternate_name, blp);
+ DECODE_FINISH(blp);
+ } else {
+ decode_import_inode(dn, blp, oldauth, ls,
+ peer_exports, updated_scatterlocks);
+ }
+ }
// add dentry to journal entry
if (le)