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