From: Kotresh HR Date: Thu, 27 Feb 2025 20:57:20 +0000 (+0530) Subject: tools/cephfs-journal-tool: Recover referent hardlink dentry X-Git-Tag: v20.3.0~377^2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f6f460c14920211535b04fc009ea5b212ee49f8e;p=ceph.git tools/cephfs-journal-tool: Recover referent hardlink dentry Recover hardlink dentry with referent inode with the following command. cephfs-journal-tool --rank={fs}:{rank} event recover_dentries list|summary Fixes: https://tracker.ceph.com/issues/69338 Signed-off-by: Kotresh HR --- diff --git a/src/tools/cephfs/JournalTool.cc b/src/tools/cephfs/JournalTool.cc index 58f08a9886f..0c970bd7bae 100644 --- a/src/tools/cephfs/JournalTool.cc +++ b/src/tools/cephfs/JournalTool.cc @@ -945,6 +945,12 @@ int JournalTool::recover_dentries( << "' with lump fnode version " << lump.fnode->version << "vs existing fnode version " << old_fnode_version << dendl; write_dentry = old_fnode_version < lump.fnode->version; + } else if (dentry_type == 'R' || dentry_type == 'r') { + dout(10) << "Existing hardlink referent full inode in slot to be (maybe) " + << "written by a remote inode from the journal dn '" << rb.dn.c_str() + << "' with lump fnode version " << lump.fnode->version + << "vs existing fnode version " << old_fnode_version << dendl; + write_dentry = old_fnode_version < lump.fnode->version; } else if (dentry_type == 'I' || dentry_type == 'i') { dout(10) << "Existing full inode in slot to be (maybe) written " << "by a remote inode from the journal dn '" << rb.dn.c_str() @@ -959,22 +965,46 @@ int JournalTool::recover_dentries( } if ((other_pool || write_dentry) && !dry_run) { - dout(4) << "writing L dentry " << key << " into frag " - << frag_oid.name << dendl; - - // Compose: Dentry format is dnfirst, [I|L], ino, d_type, alternate_name - bufferlist dentry_bl; - encode(rb.dnfirst, dentry_bl); - encode('l', dentry_bl); - ENCODE_START(2, 1, dentry_bl); - encode(rb.ino, dentry_bl); - encode(rb.d_type, dentry_bl); - encode(rb.alternate_name, dentry_bl); - ENCODE_FINISH(dentry_bl); - - // Record for writing to RADOS - write_vals[key] = dentry_bl; - consumed_inos->insert(rb.ino); + dout(4) << "writing r|l (referent|just remote) dentry " << key + << " into frag " << frag_oid.name << " rb.referent_ino " + << rb.referent_ino << " referent_inode " << rb.referent_inode + << "rb.ino " << rb.ino << dendl; + + if (rb.referent_ino != 0) { + dout(4) << "writing 'r' (referent remote) dentry " << key + << " into frag " << frag_oid.name << dendl; + + // Compose: Dentry format is dnfirst, r, alternate_name, InodeStore + bufferlist dentry_bl; + encode(rb.dnfirst, dentry_bl); + encode('r', dentry_bl); + ENCODE_START(2, 1, dentry_bl); + encode(rb.alternate_name, dentry_bl); + encode_remotebit_as_referent_inode(rb, &dentry_bl); + ENCODE_FINISH(dentry_bl); + + // Record for writing to RADOS + write_vals[key] = dentry_bl; + consumed_inos->insert(rb.referent_ino); + consumed_inos->insert(rb.ino); + } else { + dout(4) << "writing l dentry " << key << " into frag " + << frag_oid.name << dendl; + + // Compose: Dentry format is dnfirst, l, ino, d_type, alternate_name + bufferlist dentry_bl; + encode(rb.dnfirst, dentry_bl); + encode('l', dentry_bl); + ENCODE_START(2, 1, dentry_bl); + encode(rb.ino, dentry_bl); + encode(rb.d_type, dentry_bl); + encode(rb.alternate_name, dentry_bl); + ENCODE_FINISH(dentry_bl); + + // Record for writing to RADOS + write_vals[key] = dentry_bl; + consumed_inos->insert(rb.ino); + } } } @@ -1219,6 +1249,20 @@ void JournalTool::encode_fullbit_as_inode( new_inode.encode(*out_bl, CEPH_FEATURES_SUPPORTED_DEFAULT); } +void JournalTool::encode_remotebit_as_referent_inode( + const EMetaBlob::remotebit &rb, + bufferlist *out_bl) +{ + ceph_assert(out_bl != NULL); + + // Compose InodeStore + InodeStore new_inode; + new_inode.inode = rb.referent_inode; + + // Serialize InodeStore + new_inode.encode(*out_bl, CEPH_FEATURES_SUPPORTED_DEFAULT); +} + /** * Given a list of inode numbers known to be in use by * inodes in the backing store, ensure that none of these diff --git a/src/tools/cephfs/JournalTool.h b/src/tools/cephfs/JournalTool.h index ac4258b89e4..9a5edac5baf 100644 --- a/src/tools/cephfs/JournalTool.h +++ b/src/tools/cephfs/JournalTool.h @@ -79,6 +79,9 @@ class JournalTool : public MDSUtility void encode_fullbit_as_inode( const EMetaBlob::fullbit &fb, bufferlist *out_bl); + void encode_remotebit_as_referent_inode( + const EMetaBlob::remotebit &rb, + bufferlist *out_bl); int consume_inos(const std::set &inos); //validate type