1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
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.
15 #ifndef CEPH_MCLIENTRECONNECT_H
16 #define CEPH_MCLIENTRECONNECT_H
18 #include "msg/Message.h"
19 #include "mds/mdstypes.h"
20 #include "include/ceph_features.h"
23 class MClientReconnect final
: public SafeMessage
{
25 static constexpr int HEAD_VERSION
= 5;
26 static constexpr int COMPAT_VERSION
= 4;
29 std::map
<inodeno_t
, cap_reconnect_t
> caps
; // only head inodes
30 std::vector
<snaprealm_reconnect_t
> realms
;
35 SafeMessage
{CEPH_MSG_CLIENT_RECONNECT
, HEAD_VERSION
, COMPAT_VERSION
} {}
36 ~MClientReconnect() final
{}
39 size_t realm_size
= 0;
40 size_t approx_size
= sizeof(__u32
) + sizeof(__u32
) + 1;
42 void calc_item_size() {
45 ceph::buffer::list bl
;
50 cap_size
= bl
.length();
53 ceph::buffer::list bl
;
54 snaprealm_reconnect_t sr
;
56 realm_size
= bl
.length();
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 )";
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
) {
72 header
.compat_version
= 0;
74 size_t get_approx_size() {
77 void mark_more() { more
= true; }
78 bool has_more() const { return more
; }
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
)
83 caps
[ino
] = cap_reconnect_t(cap_id
, pathbase
, path
, wanted
, issued
, sr
, sf
, lb
);
86 approx_size
+= cap_size
+ path
.length() + lb
.length();
88 void add_snaprealm(inodeno_t ino
, snapid_t seq
, inodeno_t parent
) {
89 snaprealm_reconnect_t r
;
92 r
.realm
.parent
= parent
;
96 approx_size
+= realm_size
;
99 void encode_payload(uint64_t features
) override
{
100 if (header
.version
== 0) {
101 if (features
& CEPH_FEATURE_MDSENC
)
103 else if (features
& CEPH_FEATURE_FLOCK
)
112 if (header
.version
>= 4) {
114 encode(realms
, data
);
118 if (header
.version
== 3) {
120 } else if (header
.version
== 2) {
121 __u32 n
= caps
.size();
123 for (auto& p
: caps
) {
124 encode(p
.first
, data
);
125 p
.second
.encode_old(data
);
128 std::map
<inodeno_t
, old_cap_reconnect_t
> ocaps
;
129 for (auto& p
: caps
) {
130 ocaps
[p
.first
] = p
.second
;
133 for (auto& r
: realms
)
138 void decode_payload() override
{
140 auto p
= data
.cbegin();
141 if (header
.version
>= 4) {
144 if (header
.version
>= 5)
148 if (header
.version
== 3) {
150 } else if (header
.version
== 2) {
156 caps
[ino
].decode_old(p
);
159 std::map
<inodeno_t
, old_cap_reconnect_t
> ocaps
;
161 for (auto &q
: ocaps
)
162 caps
[q
.first
] = q
.second
;
165 realms
.push_back(snaprealm_reconnect_t());
166 realms
.back().decode_old(p
);
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
);