From: Kotresh HR Date: Thu, 20 Feb 2025 19:59:48 +0000 (+0530) Subject: mds/migration: Handle referent inode during subtree migration X-Git-Tag: v20.3.0~377^2~37 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=11eddc85d5a4561f6de9098a0b2a6936245a64ad;p=ceph.git mds/migration: Handle referent inode during subtree migration The referent inode should be considered while migrating the subtree. This patch takes care of migrating the referent inode. Fixes: https://tracker.ceph.com/issues/54205 Signed-off-by: Kotresh HR --- diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index 2d182b4aecdfb..328ccf3a92ba7 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -1805,6 +1805,7 @@ void Migrator::encode_export_dir(bufferlist& exportbl, 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++; @@ -1835,6 +1836,16 @@ void Migrator::encode_export_dir(bufferlist& exportbl, 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 @@ -1902,6 +1913,10 @@ void Migrator::finish_export_dir(CDir *dir, mds_rank_t peer, // 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 @@ -3345,7 +3360,18 @@ void Migrator::decode_import_inode(CDentry *dn, bufferlist::const_iterator& blp, } // 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); } @@ -3596,6 +3622,21 @@ void Migrator::decode_import_dir(bufferlist::const_iterator& blp, 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)