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