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) 2013 Inktank Storage, Inc.
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 #include "ECMsgTypes.h"
22 using ceph::bufferlist
;
23 using ceph::Formatter
;
25 void ECSubWrite::encode(bufferlist
&bl
) const
27 ENCODE_START(4, 1, bl
);
34 encode(at_version
, bl
);
36 encode(log_entries
, bl
);
37 encode(temp_added
, bl
);
38 encode(temp_removed
, bl
);
39 encode(updated_hit_set_history
, bl
);
40 encode(roll_forward_to
, bl
);
41 encode(backfill_or_async_recovery
, bl
);
45 void ECSubWrite::decode(bufferlist::const_iterator
&bl
)
54 decode(at_version
, bl
);
56 decode(log_entries
, bl
);
57 decode(temp_added
, bl
);
58 decode(temp_removed
, bl
);
60 decode(updated_hit_set_history
, bl
);
63 decode(roll_forward_to
, bl
);
65 roll_forward_to
= trim_to
;
68 decode(backfill_or_async_recovery
, bl
);
70 // The old protocol used an empty transaction to indicate backfill or async_recovery
71 backfill_or_async_recovery
= t
.empty();
76 std::ostream
&operator<<(
77 std::ostream
&lhs
, const ECSubWrite
&rhs
)
79 lhs
<< "ECSubWrite(tid=" << rhs
.tid
80 << ", reqid=" << rhs
.reqid
81 << ", at_version=" << rhs
.at_version
82 << ", trim_to=" << rhs
.trim_to
83 << ", roll_forward_to=" << rhs
.roll_forward_to
;
84 if (rhs
.updated_hit_set_history
)
85 lhs
<< ", has_updated_hit_set_history";
86 if (rhs
.backfill_or_async_recovery
)
87 lhs
<< ", backfill_or_async_recovery";
91 void ECSubWrite::dump(Formatter
*f
) const
93 f
->dump_unsigned("tid", tid
);
94 f
->dump_stream("reqid") << reqid
;
95 f
->dump_stream("at_version") << at_version
;
96 f
->dump_stream("trim_to") << trim_to
;
97 f
->dump_stream("roll_forward_to") << roll_forward_to
;
98 f
->dump_bool("has_updated_hit_set_history",
99 static_cast<bool>(updated_hit_set_history
));
100 f
->dump_bool("backfill_or_async_recovery", backfill_or_async_recovery
);
103 void ECSubWrite::generate_test_instances(list
<ECSubWrite
*> &o
)
105 o
.push_back(new ECSubWrite());
107 o
.back()->at_version
= eversion_t(2, 100);
108 o
.back()->trim_to
= eversion_t(1, 40);
109 o
.push_back(new ECSubWrite());
111 o
.back()->reqid
= osd_reqid_t(entity_name_t::CLIENT(123), 1, 45678);
112 o
.back()->at_version
= eversion_t(10, 300);
113 o
.back()->trim_to
= eversion_t(5, 42);
114 o
.push_back(new ECSubWrite());
116 o
.back()->reqid
= osd_reqid_t(entity_name_t::CLIENT(123), 1, 45678);
117 o
.back()->at_version
= eversion_t(10, 300);
118 o
.back()->trim_to
= eversion_t(5, 42);
119 o
.back()->roll_forward_to
= eversion_t(8, 250);
122 void ECSubWriteReply::encode(bufferlist
&bl
) const
124 ENCODE_START(1, 1, bl
);
127 encode(last_complete
, bl
);
128 encode(committed
, bl
);
133 void ECSubWriteReply::decode(bufferlist::const_iterator
&bl
)
138 decode(last_complete
, bl
);
139 decode(committed
, bl
);
144 std::ostream
&operator<<(
145 std::ostream
&lhs
, const ECSubWriteReply
&rhs
)
148 << "ECSubWriteReply(tid=" << rhs
.tid
149 << ", last_complete=" << rhs
.last_complete
150 << ", committed=" << rhs
.committed
151 << ", applied=" << rhs
.applied
<< ")";
154 void ECSubWriteReply::dump(Formatter
*f
) const
156 f
->dump_unsigned("tid", tid
);
157 f
->dump_stream("last_complete") << last_complete
;
158 f
->dump_bool("committed", committed
);
159 f
->dump_bool("applied", applied
);
162 void ECSubWriteReply::generate_test_instances(list
<ECSubWriteReply
*>& o
)
164 o
.push_back(new ECSubWriteReply());
166 o
.back()->last_complete
= eversion_t(100, 2000);
167 o
.back()->committed
= true;
168 o
.push_back(new ECSubWriteReply());
170 o
.back()->last_complete
= eversion_t(50, 200);
171 o
.back()->applied
= true;
174 void ECSubRead::encode(bufferlist
&bl
, uint64_t features
) const
176 if ((features
& CEPH_FEATURE_OSD_FADVISE_FLAGS
) == 0) {
177 ENCODE_START(2, 1, bl
);
180 map
<hobject_t
, list
<pair
<uint64_t, uint64_t> >> tmp
;
181 for (auto m
= to_read
.cbegin(); m
!= to_read
.cend(); ++m
) {
182 list
<pair
<uint64_t, uint64_t> > tlist
;
183 for (auto l
= m
->second
.cbegin(); l
!= m
->second
.cend(); ++l
) {
184 tlist
.push_back(std::make_pair(l
->get
<0>(), l
->get
<1>()));
186 tmp
[m
->first
] = tlist
;
189 encode(attrs_to_read
, bl
);
190 encode(subchunks
, bl
);
195 ENCODE_START(3, 2, bl
);
199 encode(attrs_to_read
, bl
);
200 encode(subchunks
, bl
);
204 void ECSubRead::decode(bufferlist::const_iterator
&bl
)
210 map
<hobject_t
, list
<pair
<uint64_t, uint64_t> >>tmp
;
212 for (auto m
= tmp
.cbegin(); m
!= tmp
.cend(); ++m
) {
213 list
<boost::tuple
<uint64_t, uint64_t, uint32_t> > tlist
;
214 for (auto l
= m
->second
.cbegin(); l
!= m
->second
.cend(); ++l
) {
215 tlist
.push_back(boost::make_tuple(l
->first
, l
->second
, 0));
217 to_read
[m
->first
] = tlist
;
222 decode(attrs_to_read
, bl
);
223 if (struct_v
> 2 && struct_v
> struct_compat
) {
224 decode(subchunks
, bl
);
226 for (auto &i
: to_read
) {
227 subchunks
[i
.first
].push_back(make_pair(0, 1));
233 std::ostream
&operator<<(
234 std::ostream
&lhs
, const ECSubRead
&rhs
)
237 << "ECSubRead(tid=" << rhs
.tid
238 << ", to_read=" << rhs
.to_read
239 << ", subchunks=" << rhs
.subchunks
240 << ", attrs_to_read=" << rhs
.attrs_to_read
<< ")";
243 void ECSubRead::dump(Formatter
*f
) const
245 f
->dump_stream("from") << from
;
246 f
->dump_unsigned("tid", tid
);
247 f
->open_array_section("objects");
248 for (auto i
= to_read
.cbegin(); i
!= to_read
.cend(); ++i
) {
249 f
->open_object_section("object");
250 f
->dump_stream("oid") << i
->first
;
251 f
->open_array_section("extents");
252 for (auto j
= i
->second
.cbegin(); j
!= i
->second
.cend(); ++j
) {
253 f
->open_object_section("extent");
254 f
->dump_unsigned("off", j
->get
<0>());
255 f
->dump_unsigned("len", j
->get
<1>());
256 f
->dump_unsigned("flags", j
->get
<2>());
264 f
->open_array_section("object_attrs_requested");
265 for (auto i
= attrs_to_read
.cbegin(); i
!= attrs_to_read
.cend(); ++i
) {
266 f
->open_object_section("object");
267 f
->dump_stream("oid") << *i
;
273 void ECSubRead::generate_test_instances(list
<ECSubRead
*>& o
)
275 hobject_t
hoid1(sobject_t("asdf", 1));
276 hobject_t
hoid2(sobject_t("asdf2", CEPH_NOSNAP
));
277 o
.push_back(new ECSubRead());
278 o
.back()->from
= pg_shard_t(2, shard_id_t(-1));
280 o
.back()->to_read
[hoid1
].push_back(boost::make_tuple(100, 200, 0));
281 o
.back()->to_read
[hoid1
].push_back(boost::make_tuple(400, 600, 0));
282 o
.back()->to_read
[hoid2
].push_back(boost::make_tuple(400, 600, 0));
283 o
.back()->attrs_to_read
.insert(hoid1
);
284 o
.push_back(new ECSubRead());
285 o
.back()->from
= pg_shard_t(2, shard_id_t(-1));
287 o
.back()->to_read
[hoid1
].push_back(boost::make_tuple(300, 200, 0));
288 o
.back()->to_read
[hoid2
].push_back(boost::make_tuple(400, 600, 0));
289 o
.back()->to_read
[hoid2
].push_back(boost::make_tuple(2000, 600, 0));
290 o
.back()->attrs_to_read
.insert(hoid2
);
293 void ECSubReadReply::encode(bufferlist
&bl
) const
295 ENCODE_START(1, 1, bl
);
298 encode(buffers_read
, bl
);
299 encode(attrs_read
, bl
);
304 void ECSubReadReply::decode(bufferlist::const_iterator
&bl
)
309 decode(buffers_read
, bl
);
310 decode(attrs_read
, bl
);
315 std::ostream
&operator<<(
316 std::ostream
&lhs
, const ECSubReadReply
&rhs
)
319 << "ECSubReadReply(tid=" << rhs
.tid
320 << ", attrs_read=" << rhs
.attrs_read
.size()
324 void ECSubReadReply::dump(Formatter
*f
) const
326 f
->dump_stream("from") << from
;
327 f
->dump_unsigned("tid", tid
);
328 f
->open_array_section("buffers_read");
329 for (auto i
= buffers_read
.cbegin(); i
!= buffers_read
.cend(); ++i
) {
330 f
->open_object_section("object");
331 f
->dump_stream("oid") << i
->first
;
332 f
->open_array_section("data");
333 for (auto j
= i
->second
.cbegin(); j
!= i
->second
.cend(); ++j
) {
334 f
->open_object_section("extent");
335 f
->dump_unsigned("off", j
->first
);
336 f
->dump_unsigned("buf_len", j
->second
.length());
344 f
->open_array_section("attrs_returned");
345 for (auto i
= attrs_read
.cbegin(); i
!= attrs_read
.cend(); ++i
) {
346 f
->open_object_section("object_attrs");
347 f
->dump_stream("oid") << i
->first
;
348 f
->open_array_section("attrs");
349 for (auto j
= i
->second
.cbegin(); j
!= i
->second
.cend(); ++j
) {
350 f
->open_object_section("attr");
351 f
->dump_string("attr", j
->first
);
352 f
->dump_unsigned("val_len", j
->second
.length());
360 f
->open_array_section("errors");
361 for (auto i
= errors
.cbegin(); i
!= errors
.cend(); ++i
) {
362 f
->open_object_section("error_pair");
363 f
->dump_stream("oid") << i
->first
;
364 f
->dump_int("error", i
->second
);
370 void ECSubReadReply::generate_test_instances(list
<ECSubReadReply
*>& o
)
372 hobject_t
hoid1(sobject_t("asdf", 1));
373 hobject_t
hoid2(sobject_t("asdf2", CEPH_NOSNAP
));
377 bl2
.append_zero(200);
378 o
.push_back(new ECSubReadReply());
379 o
.back()->from
= pg_shard_t(2, shard_id_t(-1));
381 o
.back()->buffers_read
[hoid1
].push_back(make_pair(20, bl
));
382 o
.back()->buffers_read
[hoid1
].push_back(make_pair(2000, bl2
));
383 o
.back()->buffers_read
[hoid2
].push_back(make_pair(0, bl
));
384 o
.back()->attrs_read
[hoid1
]["foo"] = bl
;
385 o
.back()->attrs_read
[hoid1
]["_"] = bl2
;
386 o
.push_back(new ECSubReadReply());
387 o
.back()->from
= pg_shard_t(2, shard_id_t(-1));
389 o
.back()->buffers_read
[hoid2
].push_back(make_pair(0, bl2
));
390 o
.back()->attrs_read
[hoid2
]["foo"] = bl
;
391 o
.back()->attrs_read
[hoid2
]["_"] = bl2
;
392 o
.back()->errors
[hoid1
] = -2;