}
// EMetaBlob::remotebit
-void EMetaBlob::remotebit::update_referent_inode(MDSRank *mds, CInode *in)
-{
- in->reset_inode(std::move(referent_inode));
- // Note: xattrs, old_inodes are not journalled for referent inodes. Not required.
-
- /*
- * In case there was anything malformed in the journal that we are
- * replaying, do sanity checks on the inodes we're replaying and
- * go damaged instead of letting any trash into a live cache
- */
- if (in->is_file()) {
- // Files must have valid layouts with a pool set
- if (in->get_inode()->layout.pool_id == -1 ||
- !in->get_inode()->layout.is_valid()) {
- dout(0) << "EMetaBlob.replay invalid layout on ino " << *in
- << ": " << in->get_inode()->layout << dendl;
- CachedStackStringStream css;
- *css << "Invalid layout for inode " << in->ino() << " in journal";
- mds->clog->error() << css->strv();
- mds->damaged();
- ceph_abort(); // Should be unreachable because damaged() calls respawn()
- }
- }
-}
-
void EMetaBlob::remotebit::encode(bufferlist& bl, uint64_t features) const
{
ENCODE_START(4, 2, bl);
}
// remote dentries
- for (auto& rb : lump.get_dremote()) {
- dout(20) << __func__ << " Going over remotebit " << rb << dendl;
+ for (const auto& rb : lump.get_dremote()) {
CDentry *dn = dir->lookup_exact_snap(rb.dn, rb.dnlast);
if (!dn) {
- /* Add remote dentry if it's not referent. For referent remote, add a null
- * dentry and linkage would happen after initiating referent CInode
- */
- if (rb.referent_ino == 0)
- dn = dir->add_remote_dentry(rb.dn, nullptr, rb.ino, rb.d_type, mempool::mds_co::string(rb.alternate_name), rb.dnfirst, rb.dnlast);
- else
- dn = dir->add_null_dentry(rb.dn, rb.dnfirst, rb.dnlast);
+ //TODO: Fix for referent inodes
+ dn = dir->add_remote_dentry(rb.dn, nullptr, rb.ino, rb.d_type, mempool::mds_co::string(rb.alternate_name), rb.dnfirst, rb.dnlast);
dn->set_version(rb.dnv);
if (rb.dirty) dn->_mark_dirty(logseg);
dout(10) << "EMetaBlob.replay added " << *dn << dendl;
} else {
- if (rb.referent_ino == 0 && !dn->get_linkage()->is_null()) {
+ if (!dn->get_linkage()->is_null()) {
dout(10) << "EMetaBlob.replay unlinking " << *dn << dendl;
if (dn->get_linkage()->is_primary()) {
unlinked[dn->get_linkage()->get_inode()] = dir;
dir->unlink_inode(dn, false);
}
dn->set_alternate_name(mempool::mds_co::string(rb.alternate_name));
- //rb.referent_ino can be 0
- if (rb.referent_ino == 0)
- dir->link_remote_inode(dn, rb.ino, rb.d_type);
+ dir->link_remote_inode(dn, rb.ino, rb.d_type);
dn->set_version(rb.dnv);
if (rb.dirty) dn->_mark_dirty(logseg);
dout(10) << "EMetaBlob.replay for [" << rb.dnfirst << "," << rb.dnlast << "] had " << *dn << dendl;
if (lump.is_importing())
dn->mark_auth();
- /* TODO: In multi-version inode, i.e., a file has hardlinks and the primary link is being deleted,
- * the primary inode is added as remote in the journal. In this case, it will not have a
- * referent inode. So rb.referent_ino=0. Are we good here ?
- *
- * Also takes care of the situation if referent inode feature is disabled
- */
- CInode *ref_in = nullptr;
- if (rb.referent_ino != 0) {
- ref_in = mds->mdcache->get_inode(rb.referent_ino, rb.dnlast);
- if (!ref_in) {
- // referent inode, use default first and last
- ref_in = new CInode(mds->mdcache, dn->is_auth());
- rb.update_referent_inode(mds, ref_in);
- ceph_assert(ref_in->_get_inode()->remote_ino == rb.ino);
- ceph_assert(ref_in->_get_inode()->ino == rb.referent_ino);
- mds->mdcache->add_inode(ref_in);
- dout(10) << __func__ << " referent inode created for dn " << *dn << " inode " << *ref_in << " ref ino " << rb.referent_ino << dendl;
- if (!dn->get_linkage()->is_null()) {
- if (dn->get_linkage()->is_referent_remote()) {
- unlinked[dn->get_linkage()->get_referent_inode()] = dir;
- CachedStackStringStream css;
- *css << "EMetaBlob.replay FIXME had dentry linked to wrong referent inode " << *dn
- << " " << *dn->get_linkage()->get_referent_inode() << " should be " << ref_in->ino();
- dout(0) << css->strv() << dendl;
- mds->clog->warn() << css->strv();
- }
- dir->unlink_inode(dn, false);
- }
- if (unlinked.count(ref_in))
- linked.insert(ref_in);
- dn->set_alternate_name(mempool::mds_co::string(rb.alternate_name));
- dir->link_referent_inode(dn, ref_in, rb.ino, rb.d_type);
- dout(10) << __func__ << " referent remote inode added " << *ref_in << dendl;
- } else {
- ref_in->first = rb.dnfirst;
- rb.update_referent_inode(mds, ref_in);
- dout(10) << __func__ << " referent inode found in memory for dn " << *dn << " inode " << *ref_in << " ref ino " << rb.referent_ino << dendl;
- if (dn->get_linkage()->get_referent_inode() != ref_in && ref_in->get_parent_dn()) {
- dout(10) << __func__ << " referent inode unlinking " << *ref_in << dendl;
- unlinked[ref_in] = ref_in->get_parent_dir();
- ref_in->get_parent_dir()->unlink_inode(ref_in->get_parent_dn());
- }
- if (dn->get_linkage()->get_inode() != ref_in) {
- if (!dn->get_linkage()->is_null()) { // note: might be remote. as with stray reintegration.
- if (dn->get_linkage()->is_referent_remote()) {
- unlinked[dn->get_linkage()->get_referent_inode()] = dir;
- CachedStackStringStream css;
- *css << "EMetaBlob.replay FIXME had dentry linked to wrong referent inode " << *dn
- << " " << *dn->get_linkage()->get_referent_inode() << " should be " << ref_in->ino();
- dout(0) << css->strv() << dendl;
- mds->clog->warn() << css->strv();
- }
- dir->unlink_inode(dn, false);
- }
- if (unlinked.count(ref_in))
- linked.insert(ref_in);
- dn->set_alternate_name(mempool::mds_co::string(rb.alternate_name));
- dir->link_referent_inode(dn, ref_in, rb.ino, rb.d_type);
- dout(10) << __func__ << " linked referent inode" << *ref_in << dendl;
- } else {
- dout(10) << __func__ << " referent inode for [" << rb.dnfirst << "," << rb.dnlast << "] had " << *ref_in << " dentry " << *dn << dendl;
- }
- }
-
- //TODO: dirty referent inode parent in->mark_dirty_parent(logseg, fb.is_dirty_pool());
- // for now mark dirty always
- ref_in->mark_dirty_parent(logseg, true);
- }
-
if (!(++count % mds->heartbeat_reset_grace()))
mds->heartbeat_reset();
}