]> git.proxmox.com Git - ceph.git/blame - ceph/src/messages/MClientReconnect.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / messages / MClientReconnect.h
CommitLineData
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 23class MClientReconnect final : public SafeMessage {
11fdf7f2
TL
24private:
25 static constexpr int HEAD_VERSION = 5;
26 static constexpr int COMPAT_VERSION = 4;
7c673cae
FG
27
28public:
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 33private:
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 60public:
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
170private:
171 template<class T, typename... Args>
172 friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
7c673cae
FG
173};
174
175
176#endif