From c39977ff26f03006aac03ddfb5e285dbe61bd7fe Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Tue, 25 Feb 2025 02:32:27 +0530 Subject: [PATCH] multi-mds/link: Handle rollback for referent_inodes list The referent inode added to the list on the primary/real inode upon hardlink creation needs to rolled back properly on failure. This patch takes care of the same. Fixes: https://tracker.ceph.com/issues/54205 Signed-off-by: Kotresh HR --- src/mds/Server.cc | 11 +++++++++-- src/mds/events/EPeerUpdate.h | 1 + src/mds/journal.cc | 8 ++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 4f1343849870d..ef6906bcb9741 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -8124,6 +8124,7 @@ void Server::handle_peer_link_prep(const MDRequestRef& mdr) const auto& pf = targeti->get_parent_dn()->get_dir()->get_projected_fnode(); rollback.old_dir_mtime = pf->fragstat.mtime; rollback.old_dir_rctime = pf->rstat.rctime; + rollback.referent_ino = referent_ino; rollback.was_inc = inc; if (realm_projected) { if (targeti->snaprealm) { @@ -8283,10 +8284,16 @@ void Server::do_link_rollback(bufferlist &rbl, mds_rank_t leader, const MDReques // inode pi.inode->ctime = rollback.old_ctime; - if (rollback.was_inc) + if (rollback.was_inc) { pi.inode->nlink--; - else + if (rollback.referent_ino > 0) { + pi.inode->remove_referent_ino(rollback.referent_ino); + dout(10) << __func__ << " referent_inodes " << std::hex << pi.inode->get_referent_inodes() + << " referent ino removed " << rollback.referent_ino << dendl; + } + } else { pi.inode->nlink++; + } map> splits; if (rollback.snapbl.length() && in->snaprealm) { diff --git a/src/mds/events/EPeerUpdate.h b/src/mds/events/EPeerUpdate.h index 88ddaa264a3ea..087caa77996ab 100644 --- a/src/mds/events/EPeerUpdate.h +++ b/src/mds/events/EPeerUpdate.h @@ -33,6 +33,7 @@ struct link_rollback { utime_t old_dir_mtime; utime_t old_dir_rctime; bufferlist snapbl; + inodeno_t referent_ino; link_rollback() : ino(0), was_inc(false) {} diff --git a/src/mds/journal.cc b/src/mds/journal.cc index 87fd489a6f546..b1888bda3a0c3 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -2570,7 +2570,7 @@ void ECommitted::generate_test_instances(std::list& ls) void link_rollback::encode(bufferlist &bl) const { - ENCODE_START(3, 2, bl); + ENCODE_START(4, 2, bl); encode(reqid, bl); encode(ino, bl); encode(was_inc, bl); @@ -2578,12 +2578,13 @@ void link_rollback::encode(bufferlist &bl) const encode(old_dir_mtime, bl); encode(old_dir_rctime, bl); encode(snapbl, bl); + encode(referent_ino, bl); ENCODE_FINISH(bl); } void link_rollback::decode(bufferlist::const_iterator &bl) { - DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl); + DECODE_START_LEGACY_COMPAT_LEN(4, 2, 2, bl); decode(reqid, bl); decode(ino, bl); decode(was_inc, bl); @@ -2592,6 +2593,8 @@ void link_rollback::decode(bufferlist::const_iterator &bl) decode(old_dir_rctime, bl); if (struct_v >= 3) decode(snapbl, bl); + if (struct_v >= 4) + decode(referent_ino, bl); DECODE_FINISH(bl); } @@ -2603,6 +2606,7 @@ void link_rollback::dump(Formatter *f) const f->dump_stream("old_ctime") << old_ctime; f->dump_stream("old_dir_mtime") << old_dir_mtime; f->dump_stream("old_dir_rctime") << old_dir_rctime; + f->dump_stream("referent_ino") << referent_ino; } void link_rollback::generate_test_instances(std::list& ls) -- 2.39.5