]>
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_MCLIENTRECONNECT_H | |
16 | #define CEPH_MCLIENTRECONNECT_H | |
17 | ||
18 | #include "msg/Message.h" | |
19 | #include "mds/mdstypes.h" | |
20 | #include "include/ceph_features.h" | |
21 | ||
22 | ||
f67539c2 | 23 | class MClientReconnect final : public SafeMessage { |
11fdf7f2 TL |
24 | private: |
25 | static constexpr int HEAD_VERSION = 5; | |
26 | static constexpr int COMPAT_VERSION = 4; | |
7c673cae FG |
27 | |
28 | public: | |
f67539c2 TL |
29 | std::map<inodeno_t, cap_reconnect_t> caps; // only head inodes |
30 | std::vector<snaprealm_reconnect_t> realms; | |
11fdf7f2 | 31 | bool more = false; |
7c673cae | 32 | |
7c673cae | 33 | private: |
9f95a23c TL |
34 | MClientReconnect() : |
35 | SafeMessage{CEPH_MSG_CLIENT_RECONNECT, HEAD_VERSION, COMPAT_VERSION} {} | |
f67539c2 | 36 | ~MClientReconnect() final {} |
7c673cae | 37 | |
11fdf7f2 TL |
38 | size_t cap_size = 0; |
39 | size_t realm_size = 0; | |
40 | size_t approx_size = sizeof(__u32) + sizeof(__u32) + 1; | |
41 | ||
42 | void calc_item_size() { | |
43 | using ceph::encode; | |
44 | { | |
f67539c2 | 45 | ceph::buffer::list bl; |
11fdf7f2 TL |
46 | inodeno_t ino; |
47 | cap_reconnect_t cr; | |
48 | encode(ino, bl); | |
49 | encode(cr, bl); | |
50 | cap_size = bl.length(); | |
51 | } | |
52 | { | |
f67539c2 | 53 | ceph::buffer::list bl; |
11fdf7f2 TL |
54 | snaprealm_reconnect_t sr; |
55 | encode(sr, bl); | |
56 | realm_size = bl.length(); | |
57 | } | |
58 | } | |
59 | ||
7c673cae | 60 | public: |
11fdf7f2 | 61 | std::string_view get_type_name() const override { return "client_reconnect"; } |
f67539c2 | 62 | void print(std::ostream& out) const override { |
7c673cae | 63 | out << "client_reconnect(" |
11fdf7f2 TL |
64 | << caps.size() << " caps " << realms.size() << " realms )"; |
65 | } | |
66 | ||
67 | // Force to use old encoding. | |
68 | // Use connection's features to choose encoding if version is set to 0. | |
69 | void set_encoding_version(int v) { | |
70 | header.version = v; | |
71 | if (v <= 3) | |
72 | header.compat_version = 0; | |
73 | } | |
74 | size_t get_approx_size() { | |
75 | return approx_size; | |
7c673cae | 76 | } |
11fdf7f2 TL |
77 | void mark_more() { more = true; } |
78 | bool has_more() const { return more; } | |
7c673cae | 79 | |
f67539c2 TL |
80 | void add_cap(inodeno_t ino, uint64_t cap_id, inodeno_t pathbase, const std::string& path, |
81 | int wanted, int issued, inodeno_t sr, snapid_t sf, ceph::buffer::list& lb) | |
7c673cae FG |
82 | { |
83 | caps[ino] = cap_reconnect_t(cap_id, pathbase, path, wanted, issued, sr, sf, lb); | |
11fdf7f2 TL |
84 | if (!cap_size) |
85 | calc_item_size(); | |
86 | approx_size += cap_size + path.length() + lb.length(); | |
7c673cae FG |
87 | } |
88 | void add_snaprealm(inodeno_t ino, snapid_t seq, inodeno_t parent) { | |
11fdf7f2 TL |
89 | snaprealm_reconnect_t r; |
90 | r.realm.ino = ino; | |
91 | r.realm.seq = seq; | |
92 | r.realm.parent = parent; | |
7c673cae | 93 | realms.push_back(r); |
11fdf7f2 TL |
94 | if (!realm_size) |
95 | calc_item_size(); | |
96 | approx_size += realm_size; | |
7c673cae FG |
97 | } |
98 | ||
99 | void encode_payload(uint64_t features) override { | |
11fdf7f2 TL |
100 | if (header.version == 0) { |
101 | if (features & CEPH_FEATURE_MDSENC) | |
102 | header.version = 3; | |
103 | else if (features & CEPH_FEATURE_FLOCK) | |
104 | header.version = 2; | |
105 | else | |
106 | header.version = 1; | |
107 | } | |
108 | ||
109 | using ceph::encode; | |
7c673cae | 110 | data.clear(); |
11fdf7f2 TL |
111 | |
112 | if (header.version >= 4) { | |
113 | encode(caps, data); | |
114 | encode(realms, data); | |
115 | encode(more, data); | |
7c673cae FG |
116 | } else { |
117 | // compat crap | |
11fdf7f2 TL |
118 | if (header.version == 3) { |
119 | encode(caps, data); | |
120 | } else if (header.version == 2) { | |
121 | __u32 n = caps.size(); | |
122 | encode(n, data); | |
123 | for (auto& p : caps) { | |
124 | encode(p.first, data); | |
125 | p.second.encode_old(data); | |
126 | } | |
127 | } else { | |
f67539c2 | 128 | std::map<inodeno_t, old_cap_reconnect_t> ocaps; |
11fdf7f2 TL |
129 | for (auto& p : caps) { |
130 | ocaps[p.first] = p.second; | |
131 | encode(ocaps, data); | |
132 | } | |
133 | for (auto& r : realms) | |
134 | r.encode_old(data); | |
135 | } | |
7c673cae | 136 | } |
7c673cae FG |
137 | } |
138 | void decode_payload() override { | |
f67539c2 | 139 | using ceph::decode; |
11fdf7f2 TL |
140 | auto p = data.cbegin(); |
141 | if (header.version >= 4) { | |
142 | decode(caps, p); | |
143 | decode(realms, p); | |
144 | if (header.version >= 5) | |
145 | decode(more, p); | |
7c673cae FG |
146 | } else { |
147 | // compat crap | |
11fdf7f2 TL |
148 | if (header.version == 3) { |
149 | decode(caps, p); | |
150 | } else if (header.version == 2) { | |
151 | __u32 n; | |
152 | decode(n, p); | |
153 | inodeno_t ino; | |
154 | while (n--) { | |
155 | decode(ino, p); | |
156 | caps[ino].decode_old(p); | |
157 | } | |
158 | } else { | |
f67539c2 | 159 | std::map<inodeno_t, old_cap_reconnect_t> ocaps; |
11fdf7f2 TL |
160 | decode(ocaps, p); |
161 | for (auto &q : ocaps) | |
162 | caps[q.first] = q.second; | |
163 | } | |
164 | while (!p.end()) { | |
165 | realms.push_back(snaprealm_reconnect_t()); | |
166 | realms.back().decode_old(p); | |
167 | } | |
7c673cae FG |
168 | } |
169 | } | |
9f95a23c TL |
170 | private: |
171 | template<class T, typename... Args> | |
172 | friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args); | |
20effc67 TL |
173 | template<class T, typename... Args> |
174 | friend MURef<T> crimson::make_message(Args&&... args); | |
7c673cae FG |
175 | }; |
176 | ||
177 | ||
178 | #endif |