]> git.proxmox.com Git - ceph.git/blob - ceph/src/mds/DamageTable.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / mds / DamageTable.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15
16 #ifndef DAMAGE_TABLE_H_
17 #define DAMAGE_TABLE_H_
18
19 #include <string_view>
20
21 #include "mdstypes.h"
22 #include "include/random.h"
23
24 class CDir;
25
26 typedef uint64_t damage_entry_id_t;
27
28 typedef enum
29 {
30 DAMAGE_ENTRY_DIRFRAG,
31 DAMAGE_ENTRY_DENTRY,
32 DAMAGE_ENTRY_BACKTRACE
33
34 } damage_entry_type_t;
35
36 class DamageEntry
37 {
38 public:
39 damage_entry_id_t id;
40 utime_t reported_at;
41
42 // path is optional, advisory. Used to give the admin an idea of what
43 // part of his tree the damage affects.
44 std::string path;
45
46 DamageEntry()
47 {
48 id = ceph::util::generate_random_number<damage_entry_id_t>(0, 0xffffffff);
49 reported_at = ceph_clock_now();
50 }
51
52 virtual damage_entry_type_t get_type() const = 0;
53
54 virtual ~DamageEntry();
55
56 virtual void dump(Formatter *f) const = 0;
57 };
58
59
60 typedef std::shared_ptr<DamageEntry> DamageEntryRef;
61
62
63 class DirFragIdent
64 {
65 public:
66 inodeno_t ino;
67 frag_t frag;
68
69 bool operator<(const DirFragIdent &rhs) const
70 {
71 if (ino == rhs.ino) {
72 return frag < rhs.frag;
73 } else {
74 return ino < rhs.ino;
75 }
76 }
77
78 DirFragIdent(inodeno_t ino_, frag_t frag_)
79 : ino(ino_), frag(frag_)
80 {}
81 };
82
83 class DentryIdent
84 {
85 public:
86 std::string dname;
87 snapid_t snap_id;
88
89 bool operator<(const DentryIdent &rhs) const
90 {
91 if (dname == rhs.dname) {
92 return snap_id < rhs.snap_id;
93 } else {
94 return dname < rhs.dname;
95 }
96 }
97
98 DentryIdent(std::string_view dname_, snapid_t snap_id_)
99 : dname(dname_), snap_id(snap_id_)
100 {}
101 };
102
103 /**
104 * Registry of in-RADOS metadata damage identified
105 * during forward scrub or during normal fetches.
106 *
107 * Used to indicate damage to the administrator, and
108 * to cache known-bad paths so that we don't hit them
109 * repeatedly.
110 *
111 * Callers notifying damage must check return code; if
112 * an fatal condition is indicated then they should mark the MDS
113 * rank damaged.
114 *
115 * An artificial limit on the number of damage entries
116 * is imposed to avoid this structure growing indefinitely. If
117 * a notification causes the limit to be exceeded, the fatal
118 * condition will be indicated in the return code and the MDS
119 * rank should be marked damaged.
120 *
121 * Protected by MDS::mds_lock
122 */
123 class DamageTable
124 {
125 protected:
126
127 // Map of all dirfrags reported damaged
128 std::map<DirFragIdent, DamageEntryRef> dirfrags;
129
130 // Store dentries in a map per dirfrag, so that we can
131 // readily look up all the bad dentries in a particular
132 // dirfrag
133 std::map<DirFragIdent, std::map<DentryIdent, DamageEntryRef> > dentries;
134
135 // Map of all inodes which could not be resolved remotely
136 // (i.e. have probably/possibly missing backtraces)
137 std::map<inodeno_t, DamageEntryRef> remotes;
138
139 // All damage, by ID. This is a secondary index
140 // to the dirfrag, dentry, remote maps. It exists
141 // to enable external tools to unambiguously operate
142 // on particular entries.
143 std::map<damage_entry_id_t, DamageEntryRef> by_id;
144
145 // I need to know my MDS rank so that I can check if
146 // metadata items are part of my mydir.
147 const mds_rank_t rank;
148
149 bool oversized() const;
150
151 public:
152
153 /**
154 * Return true if no damage entries exist
155 */
156 bool empty() const
157 {
158 return by_id.empty();
159 }
160
161 /**
162 * Indicate that a dirfrag cannot be loaded.
163 *
164 * @return true if fatal
165 */
166 bool notify_dirfrag(inodeno_t ino, frag_t frag, std::string_view path);
167
168 /**
169 * Indicate that a particular dentry cannot be loaded.
170 *
171 * @return true if fatal
172 */
173 bool notify_dentry(
174 inodeno_t ino, frag_t frag,
175 snapid_t snap_id, std::string_view dname, std::string_view path);
176
177 /**
178 * Indicate that a particular Inode could not be loaded by number
179 */
180 bool notify_remote_damaged(
181 inodeno_t ino, std::string_view path);
182
183 bool is_dentry_damaged(
184 const CDir *dir_frag,
185 std::string_view dname,
186 const snapid_t snap_id) const;
187
188 bool is_dirfrag_damaged(
189 const CDir *dir_frag) const;
190
191 bool is_remote_damaged(
192 const inodeno_t ino) const;
193
194
195 explicit DamageTable(const mds_rank_t rank_)
196 : rank(rank_)
197 {
198 ceph_assert(rank_ != MDS_RANK_NONE);
199 }
200
201 void dump(Formatter *f) const;
202
203 void erase(damage_entry_id_t damage_id);
204 };
205
206 #endif // DAMAGE_TABLE_H_
207