]> git.proxmox.com Git - ceph.git/blame - ceph/src/mds/InoTable.cc
import 15.2.0 Octopus source
[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;
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}
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{
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}
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
9f95a23c 85void 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 91void 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
101void 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}
115void 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}
131void 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
140void 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
149void 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
162void 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 188void InoTable::generate_test_instances(std::list<InoTable*>& ls)
7c673cae
FG
189{
190 ls.push_back(new InoTable());
191}
192
193
194bool InoTable::is_marked_free(inodeno_t id) const
195{
196 return free.contains(id) || projected_free.contains(id);
197}
198
199bool 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
211bool 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
227bool 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}