]> git.proxmox.com Git - ceph.git/blob - ceph/src/mds/Capability.cc
import ceph 12.2.12
[ceph.git] / ceph / src / mds / Capability.cc
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 "Capability.h"
16 #include "SessionMap.h"
17
18 #include "common/Formatter.h"
19
20
21 /*
22 * Capability::Export
23 */
24
25 void Capability::Export::encode(bufferlist &bl) const
26 {
27 ENCODE_START(2, 2, bl);
28 ::encode(cap_id, bl);
29 ::encode(wanted, bl);
30 ::encode(issued, bl);
31 ::encode(pending, bl);
32 ::encode(client_follows, bl);
33 ::encode(seq, bl);
34 ::encode(mseq, bl);
35 ::encode(last_issue_stamp, bl);
36 ENCODE_FINISH(bl);
37 }
38
39 void Capability::Export::decode(bufferlist::iterator &p)
40 {
41 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, p);
42 ::decode(cap_id, p);
43 ::decode(wanted, p);
44 ::decode(issued, p);
45 ::decode(pending, p);
46 ::decode(client_follows, p);
47 ::decode(seq, p);
48 ::decode(mseq, p);
49 ::decode(last_issue_stamp, p);
50 DECODE_FINISH(p);
51 }
52
53 void Capability::Export::dump(Formatter *f) const
54 {
55 f->dump_unsigned("cap_id", cap_id);
56 f->dump_unsigned("wanted", wanted);
57 f->dump_unsigned("issued", issued);
58 f->dump_unsigned("pending", pending);
59 f->dump_unsigned("client_follows", client_follows);
60 f->dump_unsigned("seq", seq);
61 f->dump_unsigned("migrate_seq", mseq);
62 f->dump_stream("last_issue_stamp") << last_issue_stamp;
63 }
64
65 void Capability::Export::generate_test_instances(list<Capability::Export*>& ls)
66 {
67 ls.push_back(new Export);
68 ls.push_back(new Export);
69 ls.back()->wanted = 1;
70 ls.back()->issued = 2;
71 ls.back()->pending = 3;
72 ls.back()->client_follows = 4;
73 ls.back()->mseq = 5;
74 ls.back()->last_issue_stamp = utime_t(6, 7);
75 }
76
77 void Capability::Import::encode(bufferlist &bl) const
78 {
79 ENCODE_START(1, 1, bl);
80 ::encode(cap_id, bl);
81 ::encode(issue_seq, bl);
82 ::encode(mseq, bl);
83 ENCODE_FINISH(bl);
84 }
85
86 void Capability::Import::decode(bufferlist::iterator &bl)
87 {
88 DECODE_START(1, bl);
89 ::decode(cap_id, bl);
90 ::decode(issue_seq, bl);
91 ::decode(mseq, bl);
92 DECODE_FINISH(bl);
93 }
94
95 void Capability::Import::dump(Formatter *f) const
96 {
97 f->dump_unsigned("cap_id", cap_id);
98 f->dump_unsigned("issue_seq", issue_seq);
99 f->dump_unsigned("migrate_seq", mseq);
100 }
101
102 /*
103 * Capability::revoke_info
104 */
105
106 void Capability::revoke_info::encode(bufferlist& bl) const
107 {
108 ENCODE_START(2, 2, bl)
109 ::encode(before, bl);
110 ::encode(seq, bl);
111 ::encode(last_issue, bl);
112 ENCODE_FINISH(bl);
113 }
114
115 void Capability::revoke_info::decode(bufferlist::iterator& bl)
116 {
117 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
118 ::decode(before, bl);
119 ::decode(seq, bl);
120 ::decode(last_issue, bl);
121 DECODE_FINISH(bl);
122 }
123
124 void Capability::revoke_info::dump(Formatter *f) const
125 {
126 f->dump_unsigned("before", before);
127 f->dump_unsigned("seq", seq);
128 f->dump_unsigned("last_issue", last_issue);
129 }
130
131 void Capability::revoke_info::generate_test_instances(list<Capability::revoke_info*>& ls)
132 {
133 ls.push_back(new revoke_info);
134 ls.push_back(new revoke_info);
135 ls.back()->before = 1;
136 ls.back()->seq = 2;
137 ls.back()->last_issue = 3;
138 }
139
140
141 /*
142 * Capability
143 */
144 Capability::Capability(CInode *i, Session *s, uint64_t id) :
145 client_follows(0),
146 client_xattr_version(0), client_inline_version(0),
147 last_rbytes(0), last_rsize(0),
148 item_session_caps(this), item_snaprealm_caps(this),
149 item_revoking_caps(this), item_client_revoking_caps(this),
150 inode(i), session(s),
151 cap_id(id), _wanted(0), num_revoke_warnings(0),
152 _pending(0), _issued(0), last_sent(0), last_issue(0), mseq(0),
153 suppress(0), state(0)
154 {
155 if (session) {
156 session->touch_cap_bottom(this);
157 cap_gen = session->get_cap_gen();
158 }
159 }
160
161 client_t Capability::get_client() const
162 {
163 return session ? session->get_client() : client_t(-1);
164 }
165
166 bool Capability::is_stale() const
167 {
168 return session ? session->is_stale() : false;
169 }
170
171 bool Capability::is_valid() const
172 {
173 return !session || session->get_cap_gen() == cap_gen;
174 }
175
176 void Capability::revalidate()
177 {
178 if (is_valid())
179 return;
180
181 if (_pending & ~CEPH_CAP_PIN)
182 inc_last_seq();
183
184 bool was_revoking = _issued & ~_pending;
185 _pending = _issued = CEPH_CAP_PIN;
186 _revokes.clear();
187
188 cap_gen = session->get_cap_gen();
189
190 if (was_revoking)
191 maybe_clear_notable();
192 }
193
194 void Capability::mark_notable()
195 {
196 state |= STATE_NOTABLE;
197 session->touch_cap(this);
198 }
199
200 void Capability::maybe_clear_notable()
201 {
202 if ((_issued == _pending) &&
203 !is_clientwriteable() &&
204 !is_wanted_notable(_wanted)) {
205 ceph_assert(is_notable());
206 state &= ~STATE_NOTABLE;
207 session->touch_cap_bottom(this);
208 }
209 }
210
211 void Capability::set_wanted(int w) {
212 CInode *in = get_inode();
213 if (in) {
214 if (!is_wanted_notable(_wanted) && is_wanted_notable(w)) {
215 if (!is_notable())
216 mark_notable();
217 } else if (is_wanted_notable(_wanted) && !is_wanted_notable(w)) {
218 maybe_clear_notable();
219 }
220 }
221 _wanted = w;
222 }
223
224 void Capability::encode(bufferlist& bl) const
225 {
226 ENCODE_START(2, 2, bl)
227 ::encode(last_sent, bl);
228 ::encode(last_issue_stamp, bl);
229
230 ::encode(_wanted, bl);
231 ::encode(_pending, bl);
232 ::encode(_revokes, bl);
233 ENCODE_FINISH(bl);
234 }
235
236 void Capability::decode(bufferlist::iterator &bl)
237 {
238 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl)
239 ::decode(last_sent, bl);
240 ::decode(last_issue_stamp, bl);
241
242 ::decode(_wanted, bl);
243 ::decode(_pending, bl);
244 ::decode(_revokes, bl);
245 DECODE_FINISH(bl);
246
247 calc_issued();
248 }
249
250 void Capability::dump(Formatter *f) const
251 {
252 f->dump_unsigned("last_sent", last_sent);
253 f->dump_unsigned("last_issue_stamp", last_issue_stamp);
254 f->dump_unsigned("wanted", _wanted);
255 f->dump_unsigned("pending", _pending);
256
257 f->open_array_section("revokes");
258 for (const auto &r : _revokes) {
259 f->open_object_section("revoke");
260 r.dump(f);
261 f->close_section();
262 }
263 f->close_section();
264 }
265
266 void Capability::generate_test_instances(list<Capability*>& ls)
267 {
268 ls.push_back(new Capability);
269 ls.push_back(new Capability);
270 ls.back()->last_sent = 11;
271 ls.back()->last_issue_stamp = utime_t(12, 13);
272 ls.back()->_wanted = 14;
273 ls.back()->_pending = 15;
274 {
275 ls.back()->_revokes.emplace_back();
276 auto &r = ls.back()->_revokes.back();
277 r.before = 16;
278 r.seq = 17;
279 r.last_issue = 18;
280 }
281 {
282 ls.back()->_revokes.emplace_back();
283 auto &r = ls.back()->_revokes.back();
284 r.before = 19;
285 r.seq = 20;
286 r.last_issue = 21;
287 }
288 }
289
290 MEMPOOL_DEFINE_OBJECT_FACTORY(Capability, co_cap, mds_co);