]>
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 | #ifndef CEPH_MMDSCACHEREJOIN_H | |
16 | #define CEPH_MMDSCACHEREJOIN_H | |
17 | ||
11fdf7f2 | 18 | #include <string_view> |
7c673cae | 19 | #include "include/types.h" |
7c673cae FG |
20 | #include "mds/CInode.h" |
21 | #include "mds/CDir.h" | |
22 | #include "mds/mdstypes.h" | |
f67539c2 | 23 | #include "messages/MMDSOp.h" |
7c673cae FG |
24 | |
25 | // sent from replica to auth | |
26 | ||
f67539c2 | 27 | class MMDSCacheRejoin final : public MMDSOp { |
11fdf7f2 | 28 | public: |
11fdf7f2 TL |
29 | static constexpr int OP_WEAK = 1; // replica -> auth, i exist, + maybe open files. |
30 | static constexpr int OP_STRONG = 2; // replica -> auth, i exist, + open files and lock state. | |
31 | static constexpr int OP_ACK = 3; // auth -> replica, here is your lock state. | |
7c673cae FG |
32 | static const char *get_opname(int op) { |
33 | switch (op) { | |
34 | case OP_WEAK: return "weak"; | |
35 | case OP_STRONG: return "strong"; | |
36 | case OP_ACK: return "ack"; | |
37 | default: ceph_abort(); return 0; | |
38 | } | |
39 | } | |
40 | ||
41 | // -- types -- | |
42 | struct inode_strong { | |
11fdf7f2 TL |
43 | uint32_t nonce = 0; |
44 | int32_t caps_wanted = 0; | |
45 | int32_t filelock = 0, nestlock = 0, dftlock = 0; | |
7c673cae FG |
46 | inode_strong() {} |
47 | inode_strong(int n, int cw, int dl, int nl, int dftl) : | |
48 | nonce(n), caps_wanted(cw), | |
49 | filelock(dl), nestlock(nl), dftlock(dftl) { } | |
f67539c2 | 50 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 TL |
51 | using ceph::encode; |
52 | encode(nonce, bl); | |
53 | encode(caps_wanted, bl); | |
54 | encode(filelock, bl); | |
55 | encode(nestlock, bl); | |
56 | encode(dftlock, bl); | |
7c673cae | 57 | } |
f67539c2 | 58 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
59 | using ceph::decode; |
60 | decode(nonce, bl); | |
61 | decode(caps_wanted, bl); | |
62 | decode(filelock, bl); | |
63 | decode(nestlock, bl); | |
64 | decode(dftlock, bl); | |
7c673cae FG |
65 | } |
66 | }; | |
67 | WRITE_CLASS_ENCODER(inode_strong) | |
68 | ||
69 | struct dirfrag_strong { | |
11fdf7f2 TL |
70 | uint32_t nonce = 0; |
71 | int8_t dir_rep = 0; | |
7c673cae FG |
72 | dirfrag_strong() {} |
73 | dirfrag_strong(int n, int dr) : nonce(n), dir_rep(dr) {} | |
f67539c2 | 74 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 TL |
75 | using ceph::encode; |
76 | encode(nonce, bl); | |
77 | encode(dir_rep, bl); | |
7c673cae | 78 | } |
f67539c2 | 79 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
80 | using ceph::decode; |
81 | decode(nonce, bl); | |
82 | decode(dir_rep, bl); | |
7c673cae FG |
83 | } |
84 | }; | |
85 | WRITE_CLASS_ENCODER(dirfrag_strong) | |
86 | ||
87 | struct dn_strong { | |
88 | snapid_t first; | |
f67539c2 TL |
89 | std::string alternate_name; |
90 | inodeno_t ino = 0; | |
91 | inodeno_t remote_ino = 0; | |
92 | unsigned char remote_d_type = 0; | |
93 | uint32_t nonce = 0; | |
94 | int32_t lock = 0; | |
95 | dn_strong() = default; | |
96 | dn_strong(snapid_t f, std::string_view altn, inodeno_t pi, inodeno_t ri, unsigned char rdt, int n, int l) : | |
97 | first(f), alternate_name(altn), ino(pi), remote_ino(ri), remote_d_type(rdt), nonce(n), lock(l) {} | |
11fdf7f2 TL |
98 | bool is_primary() const { return ino > 0; } |
99 | bool is_remote() const { return remote_ino > 0; } | |
100 | bool is_null() const { return ino == 0 && remote_ino == 0; } | |
f67539c2 | 101 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 TL |
102 | using ceph::encode; |
103 | encode(first, bl); | |
104 | encode(ino, bl); | |
105 | encode(remote_ino, bl); | |
106 | encode(remote_d_type, bl); | |
107 | encode(nonce, bl); | |
108 | encode(lock, bl); | |
f67539c2 | 109 | encode(alternate_name, bl); |
7c673cae | 110 | } |
f67539c2 | 111 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
112 | using ceph::decode; |
113 | decode(first, bl); | |
114 | decode(ino, bl); | |
115 | decode(remote_ino, bl); | |
116 | decode(remote_d_type, bl); | |
117 | decode(nonce, bl); | |
118 | decode(lock, bl); | |
f67539c2 | 119 | decode(alternate_name, bl); |
7c673cae FG |
120 | } |
121 | }; | |
122 | WRITE_CLASS_ENCODER(dn_strong) | |
123 | ||
124 | struct dn_weak { | |
125 | snapid_t first; | |
f67539c2 TL |
126 | inodeno_t ino = 0; |
127 | dn_weak() = default; | |
7c673cae | 128 | dn_weak(snapid_t f, inodeno_t pi) : first(f), ino(pi) {} |
f67539c2 | 129 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 TL |
130 | using ceph::encode; |
131 | encode(first, bl); | |
132 | encode(ino, bl); | |
7c673cae | 133 | } |
f67539c2 | 134 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
135 | using ceph::decode; |
136 | decode(first, bl); | |
137 | decode(ino, bl); | |
7c673cae FG |
138 | } |
139 | }; | |
140 | WRITE_CLASS_ENCODER(dn_weak) | |
141 | ||
7c673cae | 142 | struct lock_bls { |
f67539c2 TL |
143 | ceph::buffer::list file, nest, dft; |
144 | void encode(ceph::buffer::list& bl) const { | |
11fdf7f2 TL |
145 | using ceph::encode; |
146 | encode(file, bl); | |
147 | encode(nest, bl); | |
148 | encode(dft, bl); | |
7c673cae | 149 | } |
f67539c2 | 150 | void decode(ceph::buffer::list::const_iterator& bl) { |
11fdf7f2 TL |
151 | using ceph::decode; |
152 | decode(file, bl); | |
153 | decode(nest, bl); | |
154 | decode(dft, bl); | |
7c673cae FG |
155 | } |
156 | }; | |
157 | WRITE_CLASS_ENCODER(lock_bls) | |
158 | ||
7c673cae | 159 | // authpins, xlocks |
f67539c2 | 160 | struct peer_reqid { |
7c673cae FG |
161 | metareqid_t reqid; |
162 | __u32 attempt; | |
f67539c2 TL |
163 | peer_reqid() : attempt(0) {} |
164 | peer_reqid(const metareqid_t& r, __u32 a) | |
7c673cae | 165 | : reqid(r), attempt(a) {} |
f67539c2 | 166 | void encode(ceph::buffer::list& bl) const { |
11fdf7f2 TL |
167 | using ceph::encode; |
168 | encode(reqid, bl); | |
169 | encode(attempt, bl); | |
7c673cae | 170 | } |
f67539c2 | 171 | void decode(ceph::buffer::list::const_iterator& bl) { |
11fdf7f2 TL |
172 | using ceph::decode; |
173 | decode(reqid, bl); | |
174 | decode(attempt, bl); | |
7c673cae FG |
175 | } |
176 | }; | |
7c673cae | 177 | |
11fdf7f2 | 178 | std::string_view get_type_name() const override { return "cache_rejoin"; } |
f67539c2 | 179 | void print(std::ostream& out) const override { |
7c673cae FG |
180 | out << "cache_rejoin " << get_opname(op); |
181 | } | |
182 | ||
183 | // -- builders -- | |
184 | // inodes | |
185 | void add_weak_inode(vinodeno_t i) { | |
186 | weak_inodes.insert(i); | |
187 | } | |
188 | void add_strong_inode(vinodeno_t i, int n, int cw, int dl, int nl, int dftl) { | |
189 | strong_inodes[i] = inode_strong(n, cw, dl, nl, dftl); | |
190 | } | |
f67539c2 | 191 | void add_inode_locks(CInode *in, __u32 nonce, ceph::buffer::list& bl) { |
11fdf7f2 | 192 | using ceph::encode; |
f67539c2 | 193 | encode(in->ino(), inode_locks); |
11fdf7f2 TL |
194 | encode(in->last, inode_locks); |
195 | encode(nonce, inode_locks); | |
196 | encode(bl, inode_locks); | |
7c673cae FG |
197 | } |
198 | void add_inode_base(CInode *in, uint64_t features) { | |
11fdf7f2 | 199 | using ceph::encode; |
f67539c2 | 200 | encode(in->ino(), inode_base); |
11fdf7f2 | 201 | encode(in->last, inode_base); |
f67539c2 | 202 | ceph::buffer::list bl; |
7c673cae | 203 | in->_encode_base(bl, features); |
11fdf7f2 | 204 | encode(bl, inode_base); |
7c673cae FG |
205 | } |
206 | void add_inode_authpin(vinodeno_t ino, const metareqid_t& ri, __u32 attempt) { | |
f67539c2 | 207 | authpinned_inodes[ino].push_back(peer_reqid(ri, attempt)); |
7c673cae FG |
208 | } |
209 | void add_inode_frozen_authpin(vinodeno_t ino, const metareqid_t& ri, __u32 attempt) { | |
f67539c2 | 210 | frozen_authpin_inodes[ino] = peer_reqid(ri, attempt); |
7c673cae FG |
211 | } |
212 | void add_inode_xlock(vinodeno_t ino, int lt, const metareqid_t& ri, __u32 attempt) { | |
f67539c2 | 213 | xlocked_inodes[ino][lt] = peer_reqid(ri, attempt); |
7c673cae FG |
214 | } |
215 | void add_inode_wrlock(vinodeno_t ino, int lt, const metareqid_t& ri, __u32 attempt) { | |
f67539c2 | 216 | wrlocked_inodes[ino][lt].push_back(peer_reqid(ri, attempt)); |
7c673cae FG |
217 | } |
218 | ||
219 | void add_scatterlock_state(CInode *in) { | |
220 | if (inode_scatterlocks.count(in->ino())) | |
221 | return; // already added this one | |
222 | in->encode_lock_state(CEPH_LOCK_IFILE, inode_scatterlocks[in->ino()].file); | |
223 | in->encode_lock_state(CEPH_LOCK_INEST, inode_scatterlocks[in->ino()].nest); | |
224 | in->encode_lock_state(CEPH_LOCK_IDFT, inode_scatterlocks[in->ino()].dft); | |
225 | } | |
226 | ||
227 | // dirfrags | |
228 | void add_strong_dirfrag(dirfrag_t df, int n, int dr) { | |
229 | strong_dirfrags[df] = dirfrag_strong(n, dr); | |
230 | } | |
231 | void add_dirfrag_base(CDir *dir) { | |
f67539c2 | 232 | ceph::buffer::list& bl = dirfrag_bases[dir->dirfrag()]; |
7c673cae FG |
233 | dir->_encode_base(bl); |
234 | } | |
235 | ||
236 | // dentries | |
237 | void add_weak_dirfrag(dirfrag_t df) { | |
238 | weak_dirfrags.insert(df); | |
239 | } | |
11fdf7f2 | 240 | void add_weak_dentry(inodeno_t dirino, std::string_view dname, snapid_t last, dn_weak& dnw) { |
7c673cae FG |
241 | weak[dirino][string_snap_t(dname, last)] = dnw; |
242 | } | |
11fdf7f2 | 243 | void add_weak_primary_dentry(inodeno_t dirino, std::string_view dname, snapid_t first, snapid_t last, inodeno_t ino) { |
7c673cae FG |
244 | weak[dirino][string_snap_t(dname, last)] = dn_weak(first, ino); |
245 | } | |
f67539c2 TL |
246 | void add_strong_dentry(dirfrag_t df, std::string_view dname, std::string_view altn, snapid_t first, snapid_t last, inodeno_t pi, inodeno_t ri, unsigned char rdt, int n, int ls) { |
247 | auto& m = strong_dentries[df]; | |
248 | m.insert_or_assign(string_snap_t(dname, last), dn_strong(first, altn, pi, ri, rdt, n, ls)); | |
7c673cae | 249 | } |
11fdf7f2 | 250 | void add_dentry_authpin(dirfrag_t df, std::string_view dname, snapid_t last, |
7c673cae | 251 | const metareqid_t& ri, __u32 attempt) { |
f67539c2 | 252 | authpinned_dentries[df][string_snap_t(dname, last)].push_back(peer_reqid(ri, attempt)); |
7c673cae | 253 | } |
11fdf7f2 | 254 | void add_dentry_xlock(dirfrag_t df, std::string_view dname, snapid_t last, |
7c673cae | 255 | const metareqid_t& ri, __u32 attempt) { |
f67539c2 | 256 | xlocked_dentries[df][string_snap_t(dname, last)] = peer_reqid(ri, attempt); |
7c673cae FG |
257 | } |
258 | ||
259 | // -- encoding -- | |
260 | void encode_payload(uint64_t features) override { | |
11fdf7f2 TL |
261 | using ceph::encode; |
262 | encode(op, payload); | |
263 | encode(strong_inodes, payload); | |
264 | encode(inode_base, payload); | |
265 | encode(inode_locks, payload); | |
266 | encode(inode_scatterlocks, payload); | |
267 | encode(authpinned_inodes, payload); | |
268 | encode(frozen_authpin_inodes, payload); | |
269 | encode(xlocked_inodes, payload); | |
270 | encode(wrlocked_inodes, payload); | |
271 | encode(cap_exports, payload); | |
272 | encode(client_map, payload, features); | |
273 | encode(imported_caps, payload); | |
274 | encode(strong_dirfrags, payload); | |
275 | encode(dirfrag_bases, payload); | |
276 | encode(weak, payload); | |
277 | encode(weak_dirfrags, payload); | |
278 | encode(weak_inodes, payload); | |
279 | encode(strong_dentries, payload); | |
280 | encode(authpinned_dentries, payload); | |
281 | encode(xlocked_dentries, payload); | |
282 | encode(client_metadata_map, payload); | |
7c673cae FG |
283 | } |
284 | void decode_payload() override { | |
11fdf7f2 TL |
285 | auto p = payload.cbegin(); |
286 | using ceph::decode; | |
287 | decode(op, p); | |
288 | decode(strong_inodes, p); | |
289 | decode(inode_base, p); | |
290 | decode(inode_locks, p); | |
291 | decode(inode_scatterlocks, p); | |
292 | decode(authpinned_inodes, p); | |
293 | decode(frozen_authpin_inodes, p); | |
294 | decode(xlocked_inodes, p); | |
295 | decode(wrlocked_inodes, p); | |
296 | decode(cap_exports, p); | |
297 | decode(client_map, p); | |
298 | decode(imported_caps, p); | |
299 | decode(strong_dirfrags, p); | |
300 | decode(dirfrag_bases, p); | |
301 | decode(weak, p); | |
302 | decode(weak_dirfrags, p); | |
303 | decode(weak_inodes, p); | |
304 | decode(strong_dentries, p); | |
305 | decode(authpinned_dentries, p); | |
306 | decode(xlocked_dentries, p); | |
307 | if (header.version >= 2) | |
308 | decode(client_metadata_map, p); | |
7c673cae FG |
309 | } |
310 | ||
9f95a23c TL |
311 | // -- data -- |
312 | int32_t op = 0; | |
313 | ||
314 | // weak | |
f67539c2 TL |
315 | std::map<inodeno_t, std::map<string_snap_t, dn_weak> > weak; |
316 | std::set<dirfrag_t> weak_dirfrags; | |
317 | std::set<vinodeno_t> weak_inodes; | |
318 | std::map<inodeno_t, lock_bls> inode_scatterlocks; | |
9f95a23c TL |
319 | |
320 | // strong | |
f67539c2 TL |
321 | std::map<dirfrag_t, dirfrag_strong> strong_dirfrags; |
322 | std::map<dirfrag_t, std::map<string_snap_t, dn_strong> > strong_dentries; | |
323 | std::map<vinodeno_t, inode_strong> strong_inodes; | |
9f95a23c TL |
324 | |
325 | // open | |
f67539c2 TL |
326 | std::map<inodeno_t,std::map<client_t, cap_reconnect_t> > cap_exports; |
327 | std::map<client_t, entity_inst_t> client_map; | |
328 | std::map<client_t,client_metadata_t> client_metadata_map; | |
329 | ceph::buffer::list imported_caps; | |
9f95a23c TL |
330 | |
331 | // full | |
f67539c2 TL |
332 | ceph::buffer::list inode_base; |
333 | ceph::buffer::list inode_locks; | |
334 | std::map<dirfrag_t, ceph::buffer::list> dirfrag_bases; | |
9f95a23c | 335 | |
f67539c2 TL |
336 | std::map<vinodeno_t, std::list<peer_reqid> > authpinned_inodes; |
337 | std::map<vinodeno_t, peer_reqid> frozen_authpin_inodes; | |
338 | std::map<vinodeno_t, std::map<__s32, peer_reqid> > xlocked_inodes; | |
339 | std::map<vinodeno_t, std::map<__s32, std::list<peer_reqid> > > wrlocked_inodes; | |
340 | std::map<dirfrag_t, std::map<string_snap_t, std::list<peer_reqid> > > authpinned_dentries; | |
341 | std::map<dirfrag_t, std::map<string_snap_t, peer_reqid> > xlocked_dentries; | |
9f95a23c TL |
342 | |
343 | private: | |
344 | template<class T, typename... Args> | |
345 | friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args); | |
20effc67 TL |
346 | template<class T, typename... Args> |
347 | friend MURef<T> crimson::make_message(Args&&... args); | |
9f95a23c TL |
348 | |
349 | static constexpr int HEAD_VERSION = 2; | |
350 | static constexpr int COMPAT_VERSION = 1; | |
351 | ||
352 | MMDSCacheRejoin(int o) : MMDSCacheRejoin() { op = o; } | |
f67539c2 TL |
353 | MMDSCacheRejoin() : MMDSOp{MSG_MDS_CACHEREJOIN, HEAD_VERSION, COMPAT_VERSION} {} |
354 | ~MMDSCacheRejoin() final {} | |
7c673cae FG |
355 | }; |
356 | ||
357 | WRITE_CLASS_ENCODER(MMDSCacheRejoin::inode_strong) | |
358 | WRITE_CLASS_ENCODER(MMDSCacheRejoin::dirfrag_strong) | |
359 | WRITE_CLASS_ENCODER(MMDSCacheRejoin::dn_strong) | |
360 | WRITE_CLASS_ENCODER(MMDSCacheRejoin::dn_weak) | |
361 | WRITE_CLASS_ENCODER(MMDSCacheRejoin::lock_bls) | |
f67539c2 | 362 | WRITE_CLASS_ENCODER(MMDSCacheRejoin::peer_reqid) |
7c673cae | 363 | |
f67539c2 | 364 | inline std::ostream& operator<<(std::ostream& out, const MMDSCacheRejoin::peer_reqid& r) { |
7c673cae FG |
365 | return out << r.reqid << '.' << r.attempt; |
366 | } | |
367 | ||
368 | #endif |