]> git.proxmox.com Git - ceph.git/blob - ceph/src/messages/MClientReconnect.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / messages / MClientReconnect.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_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
23 class MClientReconnect final : public SafeMessage {
24 private:
25 static constexpr int HEAD_VERSION = 5;
26 static constexpr int COMPAT_VERSION = 4;
27
28 public:
29 std::map<inodeno_t, cap_reconnect_t> caps; // only head inodes
30 std::vector<snaprealm_reconnect_t> realms;
31 bool more = false;
32
33 private:
34 MClientReconnect() :
35 SafeMessage{CEPH_MSG_CLIENT_RECONNECT, HEAD_VERSION, COMPAT_VERSION} {}
36 ~MClientReconnect() final {}
37
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 {
45 ceph::buffer::list bl;
46 inodeno_t ino;
47 cap_reconnect_t cr;
48 encode(ino, bl);
49 encode(cr, bl);
50 cap_size = bl.length();
51 }
52 {
53 ceph::buffer::list bl;
54 snaprealm_reconnect_t sr;
55 encode(sr, bl);
56 realm_size = bl.length();
57 }
58 }
59
60 public:
61 std::string_view get_type_name() const override { return "client_reconnect"; }
62 void print(std::ostream& out) const override {
63 out << "client_reconnect("
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;
76 }
77 void mark_more() { more = true; }
78 bool has_more() const { return more; }
79
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)
82 {
83 caps[ino] = cap_reconnect_t(cap_id, pathbase, path, wanted, issued, sr, sf, lb);
84 if (!cap_size)
85 calc_item_size();
86 approx_size += cap_size + path.length() + lb.length();
87 }
88 void add_snaprealm(inodeno_t ino, snapid_t seq, inodeno_t parent) {
89 snaprealm_reconnect_t r;
90 r.realm.ino = ino;
91 r.realm.seq = seq;
92 r.realm.parent = parent;
93 realms.push_back(r);
94 if (!realm_size)
95 calc_item_size();
96 approx_size += realm_size;
97 }
98
99 void encode_payload(uint64_t features) override {
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;
110 data.clear();
111
112 if (header.version >= 4) {
113 encode(caps, data);
114 encode(realms, data);
115 encode(more, data);
116 } else {
117 // compat crap
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 {
128 std::map<inodeno_t, old_cap_reconnect_t> ocaps;
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 }
136 }
137 }
138 void decode_payload() override {
139 using ceph::decode;
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);
146 } else {
147 // compat crap
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 {
159 std::map<inodeno_t, old_cap_reconnect_t> ocaps;
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 }
168 }
169 }
170 private:
171 template<class T, typename... Args>
172 friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
173 template<class T, typename... Args>
174 friend MURef<T> crimson::make_message(Args&&... args);
175 };
176
177
178 #endif