]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
11fdf7f2 | 19 | #include <string_view> |
94b18763 | 20 | |
7c673cae | 21 | #include "mdstypes.h" |
11fdf7f2 | 22 | #include "include/random.h" |
7c673cae FG |
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: | |
9f95a23c TL |
39 | DamageEntry() |
40 | { | |
41 | id = ceph::util::generate_random_number<damage_entry_id_t>(0, 0xffffffff); | |
42 | reported_at = ceph_clock_now(); | |
43 | } | |
7c673cae | 44 | |
9f95a23c | 45 | virtual ~DamageEntry(); |
7c673cae | 46 | |
9f95a23c TL |
47 | virtual damage_entry_type_t get_type() const = 0; |
48 | virtual void dump(Formatter *f) const = 0; | |
7c673cae | 49 | |
9f95a23c TL |
50 | damage_entry_id_t id; |
51 | utime_t reported_at; | |
7c673cae | 52 | |
9f95a23c TL |
53 | // path is optional, advisory. Used to give the admin an idea of what |
54 | // part of his tree the damage affects. | |
55 | std::string path; | |
7c673cae FG |
56 | }; |
57 | ||
11fdf7f2 | 58 | typedef std::shared_ptr<DamageEntry> DamageEntryRef; |
7c673cae | 59 | |
7c673cae FG |
60 | class DirFragIdent |
61 | { | |
62 | public: | |
9f95a23c TL |
63 | DirFragIdent(inodeno_t ino_, frag_t frag_) |
64 | : ino(ino_), frag(frag_) | |
65 | {} | |
66 | ||
67 | bool operator<(const DirFragIdent &rhs) const | |
68 | { | |
69 | if (ino == rhs.ino) { | |
70 | return frag < rhs.frag; | |
71 | } else { | |
72 | return ino < rhs.ino; | |
73 | } | |
7c673cae | 74 | } |
7c673cae | 75 | |
9f95a23c TL |
76 | inodeno_t ino; |
77 | frag_t frag; | |
7c673cae FG |
78 | }; |
79 | ||
80 | class DentryIdent | |
81 | { | |
82 | public: | |
9f95a23c TL |
83 | DentryIdent(std::string_view dname_, snapid_t snap_id_) |
84 | : dname(dname_), snap_id(snap_id_) | |
85 | {} | |
86 | ||
87 | bool operator<(const DentryIdent &rhs) const | |
88 | { | |
89 | if (dname == rhs.dname) { | |
90 | return snap_id < rhs.snap_id; | |
91 | } else { | |
92 | return dname < rhs.dname; | |
93 | } | |
7c673cae | 94 | } |
7c673cae | 95 | |
9f95a23c TL |
96 | std::string dname; |
97 | snapid_t snap_id; | |
7c673cae FG |
98 | }; |
99 | ||
100 | /** | |
101 | * Registry of in-RADOS metadata damage identified | |
102 | * during forward scrub or during normal fetches. | |
103 | * | |
104 | * Used to indicate damage to the administrator, and | |
105 | * to cache known-bad paths so that we don't hit them | |
106 | * repeatedly. | |
107 | * | |
108 | * Callers notifying damage must check return code; if | |
109 | * an fatal condition is indicated then they should mark the MDS | |
110 | * rank damaged. | |
111 | * | |
112 | * An artificial limit on the number of damage entries | |
113 | * is imposed to avoid this structure growing indefinitely. If | |
114 | * a notification causes the limit to be exceeded, the fatal | |
115 | * condition will be indicated in the return code and the MDS | |
116 | * rank should be marked damaged. | |
117 | * | |
118 | * Protected by MDS::mds_lock | |
119 | */ | |
120 | class DamageTable | |
121 | { | |
9f95a23c TL |
122 | public: |
123 | explicit DamageTable(const mds_rank_t rank_) | |
124 | : rank(rank_) | |
125 | { | |
126 | ceph_assert(rank_ != MDS_RANK_NONE); | |
127 | } | |
128 | ||
129 | /** | |
130 | * Return true if no damage entries exist | |
131 | */ | |
132 | bool empty() const | |
133 | { | |
134 | return by_id.empty(); | |
135 | } | |
136 | ||
137 | /** | |
138 | * Indicate that a dirfrag cannot be loaded. | |
139 | * | |
140 | * @return true if fatal | |
141 | */ | |
142 | bool notify_dirfrag(inodeno_t ino, frag_t frag, std::string_view path); | |
143 | ||
144 | /** | |
145 | * Indicate that a particular dentry cannot be loaded. | |
146 | * | |
147 | * @return true if fatal | |
148 | */ | |
149 | bool notify_dentry( | |
150 | inodeno_t ino, frag_t frag, | |
151 | snapid_t snap_id, std::string_view dname, std::string_view path); | |
152 | ||
153 | /** | |
154 | * Indicate that a particular Inode could not be loaded by number | |
155 | */ | |
156 | bool notify_remote_damaged(inodeno_t ino, std::string_view path); | |
157 | ||
158 | bool is_dentry_damaged( | |
7c673cae | 159 | const CDir *dir_frag, |
11fdf7f2 | 160 | std::string_view dname, |
7c673cae FG |
161 | const snapid_t snap_id) const; |
162 | ||
9f95a23c | 163 | bool is_dirfrag_damaged(const CDir *dir_frag) const; |
7c673cae | 164 | |
9f95a23c | 165 | bool is_remote_damaged(const inodeno_t ino) const; |
7c673cae | 166 | |
9f95a23c | 167 | void dump(Formatter *f) const; |
7c673cae | 168 | |
9f95a23c | 169 | void erase(damage_entry_id_t damage_id); |
7c673cae | 170 | |
9f95a23c TL |
171 | protected: |
172 | // I need to know my MDS rank so that I can check if | |
173 | // metadata items are part of my mydir. | |
174 | const mds_rank_t rank; | |
7c673cae | 175 | |
9f95a23c | 176 | bool oversized() const; |
7c673cae | 177 | |
9f95a23c TL |
178 | // Map of all dirfrags reported damaged |
179 | std::map<DirFragIdent, DamageEntryRef> dirfrags; | |
180 | ||
181 | // Store dentries in a map per dirfrag, so that we can | |
182 | // readily look up all the bad dentries in a particular | |
183 | // dirfrag | |
184 | std::map<DirFragIdent, std::map<DentryIdent, DamageEntryRef> > dentries; | |
7c673cae | 185 | |
9f95a23c TL |
186 | // Map of all inodes which could not be resolved remotely |
187 | // (i.e. have probably/possibly missing backtraces) | |
188 | std::map<inodeno_t, DamageEntryRef> remotes; | |
189 | ||
190 | // All damage, by ID. This is a secondary index | |
191 | // to the dirfrag, dentry, remote maps. It exists | |
192 | // to enable external tools to unambiguously operate | |
193 | // on particular entries. | |
194 | std::map<damage_entry_id_t, DamageEntryRef> by_id; | |
195 | }; | |
196 | #endif // DAMAGE_TABLE_H_ |