]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add DamageTable infra to hold uninline failures
authorMilind Changire <mchangir@redhat.com>
Wed, 12 Oct 2022 10:14:54 +0000 (15:44 +0530)
committerMilind Changire <mchangir@redhat.com>
Wed, 28 Aug 2024 07:03:39 +0000 (12:33 +0530)
Signed-off-by: Milind Changire <mchangir@redhat.com>
src/mds/DamageTable.cc
src/mds/DamageTable.h

index 2079d23333a835915d355a00953594549f4a9b44..4b9cba199da8d8816343d7c7c9f759a8a2351df0 100644 (file)
@@ -123,6 +123,41 @@ class BacktraceDamage : public DamageEntry
     f->close_section();
   }
 };
+
+/**
+ * Record about Uninline failures during scrub
+ */
+class UninlineDamage : public DamageEntry
+{
+  public:
+  inodeno_t ino;
+  mds_rank_t rank;
+  int32_t failure_errno;
+  std::string scrub_tag;
+
+  UninlineDamage(
+    inodeno_t ino_, mds_rank_t rank_, int32_t errno_, std::string_view scrub_tag_)
+    : ino(ino_), rank(rank_), failure_errno(errno_), scrub_tag(scrub_tag_)
+  {}
+
+  damage_entry_type_t get_type() const override
+  {
+    return DAMAGE_ENTRY_UNINLINE_FILE;
+  }
+
+  void dump(Formatter *f) const override
+  {
+    f->open_object_section("uninline_damage");
+    f->dump_string("damage_type", "uninline");
+    f->dump_int("id", id);
+    f->dump_int("ino", ino);
+    f->dump_int("rank", rank);
+    f->dump_string("errno", cpp_strerror(failure_errno));
+    f->dump_string("scrub_tag", scrub_tag);
+    f->dump_string("path", path);
+    f->close_section();
+  }
+};
 }
 
 DamageEntry::~DamageEntry()
@@ -228,6 +263,27 @@ void DamageTable::remove_backtrace_damage_entry(inodeno_t ino)
   }  
 }
 
+bool DamageTable::notify_uninline_failed(
+  inodeno_t ino,
+  mds_rank_t rank,
+  int32_t failure_errno,
+  std::string_view scrub_tag,
+  std::string_view path)
+{
+  if (oversized()) {
+    return true;
+  }
+
+  if (auto [it, inserted] = uninline_failures.try_emplace(ino); inserted) {
+    auto entry = std::make_shared<UninlineDamage>(ino, rank, errno, scrub_tag);
+    entry->path = path;
+    it->second = entry;
+    by_id[entry->id] = std::move(entry);
+  }
+
+  return false;
+}
+
 bool DamageTable::oversized() const
 {
   return by_id.size() > (size_t)(g_conf()->mds_damage_table_max_entries);
@@ -293,6 +349,9 @@ void DamageTable::erase(damage_entry_id_t damage_id)
   } else if (type == DAMAGE_ENTRY_BACKTRACE) {
     auto backtrace_entry = std::static_pointer_cast<BacktraceDamage>(entry);
     remotes.erase(backtrace_entry->ino);
+  } else if (type == DAMAGE_ENTRY_UNINLINE_FILE) {
+    auto uninline_entry = std::static_pointer_cast<UninlineDamage>(entry);
+    uninline_failures.erase(uninline_entry->ino);
   } else {
     derr << "Invalid type " << type << dendl;
     ceph_abort();
index a1b96fe2218642934b68e8fccdd45a6b33708188..a8182491a9f783dce717c0d4cb6440c1202338b6 100644 (file)
@@ -30,7 +30,8 @@ typedef enum
 {
   DAMAGE_ENTRY_DIRFRAG,
   DAMAGE_ENTRY_DENTRY,
-  DAMAGE_ENTRY_BACKTRACE
+  DAMAGE_ENTRY_BACKTRACE,
+  DAMAGE_ENTRY_UNINLINE_FILE
 
 } damage_entry_type_t;
 
@@ -162,6 +163,16 @@ class DamageTable
 
     void remove_backtrace_damage_entry(inodeno_t ino);
 
+    /**
+     * Indicate that there was some error when attempting to unline data of
+     * the file.
+     *
+     * @return true if fatal
+     */
+    bool notify_uninline_failed(
+      inodeno_t ino, mds_rank_t rank, int32_t failure_errno,
+      std::string_view scrub_tag, std::string_view path);
+
     bool is_dentry_damaged(
       const CDir *dir_frag,
       std::string_view dname,
@@ -194,6 +205,9 @@ class DamageTable
     // (i.e. have probably/possibly missing backtraces)
     std::map<inodeno_t, DamageEntryRef> remotes;
 
+    // Map of all inodes for which Data Uninlining failed
+    std::map<inodeno_t, DamageEntryRef> uninline_failures;
+
     // All damage, by ID.  This is a secondary index
     // to the dirfrag, dentry, remote maps.  It exists
     // to enable external tools to unambiguously operate