]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
multi-mds/link: Handle rollback for referent_inodes list
authorKotresh HR <khiremat@redhat.com>
Mon, 24 Feb 2025 21:02:27 +0000 (02:32 +0530)
committerKotresh HR <khiremat@redhat.com>
Tue, 4 Mar 2025 06:20:47 +0000 (11:50 +0530)
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 <khiremat@redhat.com>
src/mds/Server.cc
src/mds/events/EPeerUpdate.h
src/mds/journal.cc

index 4f1343849870d431695373479569e7e25d9326fa..ef6906bcb9741f8cbde91e0a111f963e8bbdb872 100644 (file)
@@ -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<client_t,ref_t<MClientSnap>> splits;
   if (rollback.snapbl.length() && in->snaprealm) {
index 88ddaa264a3ea174bb49d8d4db715b5b4e4afbff..087caa77996abee4022116c1770b54672bce4dee 100644 (file)
@@ -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) {}
 
index 87fd489a6f5469aa1934b5d1e88285bb6b962d9e..b1888bda3a0c3e1876778d563d39917e06e7251e 100644 (file)
@@ -2570,7 +2570,7 @@ void ECommitted::generate_test_instances(std::list<ECommitted*>& 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<link_rollback*>& ls)