f->close_section();
}
+void DamageTable::erase(damage_entry_id_t damage_id)
+{
+ if (by_id.count(damage_id) == 0) {
+ return;
+ }
+
+ DamageEntryRef entry = by_id.at(damage_id);
+ assert(entry->id == damage_id); // Sanity
+
+ const auto type = entry->get_type();
+ if (type == DAMAGE_ENTRY_DIRFRAG) {
+ auto dirfrag_entry = std::static_pointer_cast<DirFragDamage>(entry);
+ dirfrags.erase(DirFragIdent(dirfrag_entry->ino, dirfrag_entry->frag));
+ } else if (type == DAMAGE_ENTRY_DENTRY) {
+ auto dentry_entry = std::static_pointer_cast<DentryDamage>(entry);
+ dentries.erase(DirFragIdent(dentry_entry->ino, dentry_entry->frag));
+ } else if (type == DAMAGE_ENTRY_BACKTRACE) {
+ auto backtrace_entry = std::static_pointer_cast<BacktraceDamage>(entry);
+ remotes.erase(backtrace_entry->ino);
+ } else {
+ derr << "Invalid type " << type << dendl;
+ assert(0);
+ }
+
+ by_id.erase(damage_id);
+}
+
typedef uint64_t damage_entry_id_t;
+typedef enum
+{
+ DAMAGE_ENTRY_DIRFRAG,
+ DAMAGE_ENTRY_DENTRY,
+ DAMAGE_ENTRY_BACKTRACE
+
+} damage_entry_type_t;
+
class DamageEntry
{
public:
reported_at = ceph_clock_now(g_ceph_context);
}
+ virtual damage_entry_type_t get_type() const = 0;
+
virtual ~DamageEntry();
virtual void dump(Formatter *f) const = 0;
: ino(ino_), frag(frag_)
{}
+ virtual damage_entry_type_t get_type() const
+ {
+ return DAMAGE_ENTRY_DIRFRAG;
+ }
+
void dump(Formatter *f) const
{
f->open_object_section("dir_frag_damage");
: ino(ino_), frag(frag_), dname(dname_), snap_id(snap_id_)
{}
+ virtual damage_entry_type_t get_type() const
+ {
+ return DAMAGE_ENTRY_DENTRY;
+ }
+
void dump(Formatter *f) const
{
f->open_object_section("dentry_damage");
: ino(ino_)
{}
+ virtual damage_entry_type_t get_type() const
+ {
+ return DAMAGE_ENTRY_BACKTRACE;
+ }
+
void dump(Formatter *f) const
{
f->open_object_section("backtrace_damage");
}
void dump(Formatter *f) const;
+
+ void erase(damage_entry_id_t damage_id);
};
#endif // DAMAGE_TABLE_H_
"Evict client session(s)", "mds", "rw", "cli,rest")
COMMAND("damage ls",
"List detected metadata damage", "mds", "r", "cli,rest")
+COMMAND("damage rm name=damage_id,type=CephInt",
+ "Remove a damage table entry", "mds", "rw", "cli,rest")
COMMAND("heap " \
"name=heapcmd,type=CephChoices,strings=dump|start_profiler|stop_profiler|release|stats", \
"show heap usage info (available only if compiled with tcmalloc)", \
f->flush(*ds);
delete f;
return true;
+ } else if (prefix == "damage rm") {
+ damage_entry_id_t id = 0;
+ bool got = cmd_getval(g_ceph_context, cmdmap, "damage_id", (int64_t&)id);
+ if (!got) {
+ *r = -EINVAL;
+ return true;
+ }
+
+ damage_table.erase(id);
+ return true;
} else {
return false;
}