]>
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 | #include "InoTable.h" | |
16 | #include "MDSRank.h" | |
17 | ||
18 | #include "include/types.h" | |
19 | ||
20 | #include "common/config.h" | |
21 | ||
22 | #define dout_context g_ceph_context | |
23 | #define dout_subsys ceph_subsys_mds | |
24 | #undef dout_prefix | |
25 | #define dout_prefix *_dout << "mds." << rank << "." << table_name << ": " | |
26 | ||
27 | void InoTable::reset_state() | |
28 | { | |
29 | // use generic range. FIXME THIS IS CRAP | |
30 | free.clear(); | |
31 | //#ifdef __LP64__ | |
32 | uint64_t start = (uint64_t)(rank+1) << 40; | |
33 | uint64_t len = (uint64_t)1 << 40; | |
34 | //#else | |
35 | //# warning this looks like a 32-bit system, using small inode numbers. | |
36 | // uint64_t start = (uint64_t)(mds->get_nodeid()+1) << 25; | |
37 | // uint64_t end = ((uint64_t)(mds->get_nodeid()+2) << 25) - 1; | |
38 | //#endif | |
39 | free.insert(start, len); | |
40 | ||
41 | projected_free = free; | |
42 | } | |
43 | ||
44 | inodeno_t InoTable::project_alloc_id(inodeno_t id) | |
45 | { | |
46 | dout(10) << "project_alloc_id " << id << " to " << projected_free << "/" << free << dendl; | |
11fdf7f2 | 47 | ceph_assert(is_active()); |
7c673cae FG |
48 | if (!id) |
49 | id = projected_free.range_start(); | |
50 | projected_free.erase(id); | |
51 | ++projected_version; | |
52 | return id; | |
53 | } | |
54 | void InoTable::apply_alloc_id(inodeno_t id) | |
55 | { | |
56 | dout(10) << "apply_alloc_id " << id << " to " << projected_free << "/" << free << dendl; | |
57 | free.erase(id); | |
58 | ++version; | |
59 | } | |
60 | ||
61 | void InoTable::project_alloc_ids(interval_set<inodeno_t>& ids, int want) | |
62 | { | |
11fdf7f2 | 63 | ceph_assert(is_active()); |
7c673cae FG |
64 | while (want > 0) { |
65 | inodeno_t start = projected_free.range_start(); | |
66 | inodeno_t end = projected_free.end_after(start); | |
67 | inodeno_t num = end - start; | |
68 | if (num > (inodeno_t)want) | |
69 | num = want; | |
70 | projected_free.erase(start, num); | |
71 | ids.insert(start, num); | |
72 | want -= num; | |
73 | } | |
74 | dout(10) << "project_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl; | |
75 | ++projected_version; | |
76 | } | |
77 | void InoTable::apply_alloc_ids(interval_set<inodeno_t>& ids) | |
78 | { | |
79 | dout(10) << "apply_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl; | |
80 | free.subtract(ids); | |
81 | ++version; | |
82 | } | |
83 | ||
84 | ||
9f95a23c | 85 | void InoTable::project_release_ids(const interval_set<inodeno_t>& ids) |
7c673cae FG |
86 | { |
87 | dout(10) << "project_release_ids " << ids << " to " << projected_free << "/" << free << dendl; | |
88 | projected_free.insert(ids); | |
89 | ++projected_version; | |
90 | } | |
9f95a23c | 91 | void InoTable::apply_release_ids(const interval_set<inodeno_t>& ids) |
7c673cae FG |
92 | { |
93 | dout(10) << "apply_release_ids " << ids << " to " << projected_free << "/" << free << dendl; | |
94 | free.insert(ids); | |
95 | ++version; | |
96 | } | |
97 | ||
98 | ||
99 | // | |
100 | ||
101 | void InoTable::replay_alloc_id(inodeno_t id) | |
102 | { | |
11fdf7f2 | 103 | ceph_assert(mds); // Only usable in online mode |
7c673cae FG |
104 | |
105 | dout(10) << "replay_alloc_id " << id << dendl; | |
106 | if (free.contains(id)) { | |
107 | free.erase(id); | |
108 | projected_free.erase(id); | |
109 | } else { | |
110 | mds->clog->error() << "journal replay alloc " << id | |
111 | << " not in free " << free; | |
112 | } | |
113 | projected_version = ++version; | |
114 | } | |
115 | void InoTable::replay_alloc_ids(interval_set<inodeno_t>& ids) | |
116 | { | |
11fdf7f2 | 117 | ceph_assert(mds); // Only usable in online mode |
7c673cae FG |
118 | |
119 | dout(10) << "replay_alloc_ids " << ids << dendl; | |
120 | interval_set<inodeno_t> is; | |
121 | is.intersection_of(free, ids); | |
11fdf7f2 | 122 | if (!(is==ids)) { |
7c673cae FG |
123 | mds->clog->error() << "journal replay alloc " << ids << ", only " |
124 | << is << " is in free " << free; | |
7c673cae | 125 | } |
11fdf7f2 TL |
126 | free.subtract(is); |
127 | projected_free.subtract(is); | |
128 | ||
7c673cae FG |
129 | projected_version = ++version; |
130 | } | |
131 | void InoTable::replay_release_ids(interval_set<inodeno_t>& ids) | |
132 | { | |
133 | dout(10) << "replay_release_ids " << ids << dendl; | |
134 | free.insert(ids); | |
135 | projected_free.insert(ids); | |
136 | projected_version = ++version; | |
137 | } | |
138 | ||
139 | ||
140 | void InoTable::replay_reset() | |
141 | { | |
142 | dout(10) << "replay_reset " << free << dendl; | |
143 | skip_inos(inodeno_t(10000000)); // a lot! | |
144 | projected_free = free; | |
145 | projected_version = ++version; | |
146 | } | |
147 | ||
148 | ||
149 | void InoTable::skip_inos(inodeno_t i) | |
150 | { | |
151 | dout(10) << "skip_inos was " << free << dendl; | |
152 | inodeno_t first = free.range_start(); | |
153 | interval_set<inodeno_t> s; | |
154 | s.insert(first, i); | |
155 | s.intersection_of(free); | |
156 | free.subtract(s); | |
157 | projected_free = free; | |
158 | projected_version = ++version; | |
159 | dout(10) << "skip_inos now " << free << dendl; | |
160 | } | |
161 | ||
162 | void InoTable::dump(Formatter *f) const | |
163 | { | |
164 | f->open_object_section("inotable"); | |
165 | ||
166 | f->open_array_section("projected_free"); | |
167 | for (interval_set<inodeno_t>::const_iterator i = projected_free.begin(); i != projected_free.end(); ++i) { | |
168 | f->open_object_section("range"); | |
169 | f->dump_int("start", (*i).first); | |
170 | f->dump_int("len", (*i).second); | |
171 | f->close_section(); | |
172 | } | |
173 | f->close_section(); | |
174 | ||
175 | f->open_array_section("free"); | |
176 | for (interval_set<inodeno_t>::const_iterator i = free.begin(); i != free.end(); ++i) { | |
177 | f->open_object_section("range"); | |
178 | f->dump_int("start", (*i).first); | |
179 | f->dump_int("len", (*i).second); | |
180 | f->close_section(); | |
181 | } | |
182 | f->close_section(); | |
183 | ||
184 | f->close_section(); | |
185 | } | |
186 | ||
187 | ||
9f95a23c | 188 | void InoTable::generate_test_instances(std::list<InoTable*>& ls) |
7c673cae FG |
189 | { |
190 | ls.push_back(new InoTable()); | |
191 | } | |
192 | ||
193 | ||
194 | bool InoTable::is_marked_free(inodeno_t id) const | |
195 | { | |
196 | return free.contains(id) || projected_free.contains(id); | |
197 | } | |
198 | ||
199 | bool InoTable::intersects_free( | |
200 | const interval_set<inodeno_t> &other, | |
201 | interval_set<inodeno_t> *intersection) | |
202 | { | |
203 | interval_set<inodeno_t> i; | |
204 | i.intersection_of(free, other); | |
205 | if (intersection != nullptr) { | |
206 | *intersection = i; | |
207 | } | |
208 | return !(i.empty()); | |
209 | } | |
210 | ||
211 | bool InoTable::repair(inodeno_t id) | |
212 | { | |
213 | if (projected_version != version) { | |
214 | // Can't do the repair while other things are in flight | |
215 | return false; | |
216 | } | |
217 | ||
11fdf7f2 TL |
218 | ceph_assert(is_marked_free(id)); |
219 | dout(10) << "repair: before status. ino = " << id << " pver =" << projected_version << " ver= " << version << dendl; | |
7c673cae FG |
220 | free.erase(id); |
221 | projected_free.erase(id); | |
222 | projected_version = ++version; | |
11fdf7f2 | 223 | dout(10) << "repair: after status. ino = " << id << " pver =" << projected_version << " ver= " << version << dendl; |
7c673cae FG |
224 | return true; |
225 | } | |
11fdf7f2 TL |
226 | |
227 | bool InoTable::force_consume_to(inodeno_t ino) | |
228 | { | |
eafe8130 TL |
229 | inodeno_t first = free.range_start(); |
230 | if (first > ino) | |
11fdf7f2 | 231 | return false; |
eafe8130 TL |
232 | |
233 | skip_inos(inodeno_t(ino + 1 - first)); | |
234 | return true; | |
11fdf7f2 | 235 | } |