]> git.proxmox.com Git - ceph.git/blame - ceph/src/mds/InoTable.cc
update sources to v12.2.5
[ceph.git] / ceph / src / mds / InoTable.cc
CommitLineData
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
27void 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
44inodeno_t InoTable::project_alloc_id(inodeno_t id)
45{
46 dout(10) << "project_alloc_id " << id << " to " << projected_free << "/" << free << dendl;
47 assert(is_active());
48 if (!id)
49 id = projected_free.range_start();
50 projected_free.erase(id);
51 ++projected_version;
52 return id;
53}
54void 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
61void InoTable::project_alloc_ids(interval_set<inodeno_t>& ids, int want)
62{
63 assert(is_active());
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}
77void 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
85void InoTable::project_release_ids(interval_set<inodeno_t>& ids)
86{
87 dout(10) << "project_release_ids " << ids << " to " << projected_free << "/" << free << dendl;
88 projected_free.insert(ids);
89 ++projected_version;
90}
91void InoTable::apply_release_ids(interval_set<inodeno_t>& ids)
92{
93 dout(10) << "apply_release_ids " << ids << " to " << projected_free << "/" << free << dendl;
94 free.insert(ids);
95 ++version;
96}
97
98
99//
100
101void InoTable::replay_alloc_id(inodeno_t id)
102{
103 assert(mds); // Only usable in online mode
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}
115void InoTable::replay_alloc_ids(interval_set<inodeno_t>& ids)
116{
117 assert(mds); // Only usable in online mode
118
119 dout(10) << "replay_alloc_ids " << ids << dendl;
120 interval_set<inodeno_t> is;
121 is.intersection_of(free, ids);
122 if (is == ids) {
123 free.subtract(ids);
124 projected_free.subtract(ids);
125 } else {
126 mds->clog->error() << "journal replay alloc " << ids << ", only "
127 << is << " is in free " << free;
128 free.subtract(is);
129 projected_free.subtract(is);
130 }
131 projected_version = ++version;
132}
133void InoTable::replay_release_ids(interval_set<inodeno_t>& ids)
134{
135 dout(10) << "replay_release_ids " << ids << dendl;
136 free.insert(ids);
137 projected_free.insert(ids);
138 projected_version = ++version;
139}
140
141
142void InoTable::replay_reset()
143{
144 dout(10) << "replay_reset " << free << dendl;
145 skip_inos(inodeno_t(10000000)); // a lot!
146 projected_free = free;
147 projected_version = ++version;
148}
149
150
151void InoTable::skip_inos(inodeno_t i)
152{
153 dout(10) << "skip_inos was " << free << dendl;
154 inodeno_t first = free.range_start();
155 interval_set<inodeno_t> s;
156 s.insert(first, i);
157 s.intersection_of(free);
158 free.subtract(s);
159 projected_free = free;
160 projected_version = ++version;
161 dout(10) << "skip_inos now " << free << dendl;
162}
163
164void InoTable::dump(Formatter *f) const
165{
166 f->open_object_section("inotable");
167
168 f->open_array_section("projected_free");
169 for (interval_set<inodeno_t>::const_iterator i = projected_free.begin(); i != projected_free.end(); ++i) {
170 f->open_object_section("range");
171 f->dump_int("start", (*i).first);
172 f->dump_int("len", (*i).second);
173 f->close_section();
174 }
175 f->close_section();
176
177 f->open_array_section("free");
178 for (interval_set<inodeno_t>::const_iterator i = free.begin(); i != free.end(); ++i) {
179 f->open_object_section("range");
180 f->dump_int("start", (*i).first);
181 f->dump_int("len", (*i).second);
182 f->close_section();
183 }
184 f->close_section();
185
186 f->close_section();
187}
188
189
190void InoTable::generate_test_instances(list<InoTable*>& ls)
191{
192 ls.push_back(new InoTable());
193}
194
195
196bool InoTable::is_marked_free(inodeno_t id) const
197{
198 return free.contains(id) || projected_free.contains(id);
199}
200
201bool InoTable::intersects_free(
202 const interval_set<inodeno_t> &other,
203 interval_set<inodeno_t> *intersection)
204{
205 interval_set<inodeno_t> i;
206 i.intersection_of(free, other);
207 if (intersection != nullptr) {
208 *intersection = i;
209 }
210 return !(i.empty());
211}
212
213bool InoTable::repair(inodeno_t id)
214{
215 if (projected_version != version) {
216 // Can't do the repair while other things are in flight
217 return false;
218 }
219
220 assert(is_marked_free(id));
221 dout(10) << "repair: before status. ino = 0x" << std::hex << id << " pver =" << projected_version << " ver= " << version << dendl;
222 free.erase(id);
223 projected_free.erase(id);
224 projected_version = ++version;
225 dout(10) << "repair: after status. ino = 0x" << std::hex <<id << " pver =" << projected_version << " ver= " << version << dendl;
226 return true;
227}