]>
git.proxmox.com Git - ceph.git/blob - ceph/src/journal/Entry.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "journal/Entry.h"
5 #include "include/encoding.h"
6 #include "include/stringify.h"
7 #include "common/Formatter.h"
10 #define dout_subsys ceph_subsys_journaler
12 #define dout_prefix *_dout << "Entry: " << this << " "
18 const uint32_t HEADER_FIXED_SIZE
= 25; /// preamble, version, entry tid, tag id
19 const uint32_t REMAINDER_FIXED_SIZE
= 8; /// data size, crc
21 } // anonymous namespace
23 uint32_t Entry::get_fixed_size() {
24 return HEADER_FIXED_SIZE
+ REMAINDER_FIXED_SIZE
;
27 void Entry::encode(bufferlist
&bl
) const {
30 encode(preamble
, data_bl
);
31 encode(static_cast<uint8_t>(1), data_bl
);
32 encode(m_entry_tid
, data_bl
);
33 encode(m_tag_tid
, data_bl
);
34 encode(m_data
, data_bl
);
36 uint32_t crc
= data_bl
.crc32c(0);
37 uint32_t bl_offset
= bl
.length();
38 bl
.claim_append(data_bl
);
40 ceph_assert(get_fixed_size() + m_data
.length() + bl_offset
== bl
.length());
43 void Entry::decode(bufferlist::const_iterator
&iter
) {
45 uint32_t start_offset
= iter
.get_off();
47 decode(bl_preamble
, iter
);
48 if (bl_preamble
!= preamble
) {
49 throw buffer::malformed_input("incorrect preamble: " +
50 stringify(bl_preamble
));
54 decode(version
, iter
);
56 throw buffer::malformed_input("unknown version: " + stringify(version
));
59 decode(m_entry_tid
, iter
);
60 decode(m_tag_tid
, iter
);
62 uint32_t end_offset
= iter
.get_off();
68 data_bl
.substr_of(iter
.get_bl(), start_offset
, end_offset
- start_offset
);
69 uint32_t actual_crc
= data_bl
.crc32c(0);
70 if (crc
!= actual_crc
) {
71 throw buffer::malformed_input("crc mismatch: " + stringify(crc
) +
72 " != " + stringify(actual_crc
));
76 void Entry::dump(Formatter
*f
) const {
77 f
->dump_unsigned("tag_tid", m_tag_tid
);
78 f
->dump_unsigned("entry_tid", m_entry_tid
);
80 std::stringstream data
;
82 f
->dump_string("data", data
.str());
85 bool Entry::is_readable(bufferlist::const_iterator iter
, uint32_t *bytes_needed
) {
87 uint32_t start_off
= iter
.get_off();
88 if (iter
.get_remaining() < HEADER_FIXED_SIZE
) {
89 *bytes_needed
= HEADER_FIXED_SIZE
- iter
.get_remaining();
93 decode(bl_preamble
, iter
);
94 if (bl_preamble
!= preamble
) {
98 iter
.advance(HEADER_FIXED_SIZE
- sizeof(bl_preamble
));
100 if (iter
.get_remaining() < sizeof(uint32_t)) {
101 *bytes_needed
= sizeof(uint32_t) - iter
.get_remaining();
105 decode(data_size
, iter
);
107 if (iter
.get_remaining() < data_size
) {
108 *bytes_needed
= data_size
- iter
.get_remaining();
111 iter
.advance(data_size
);
112 uint32_t end_off
= iter
.get_off();
114 if (iter
.get_remaining() < sizeof(uint32_t)) {
115 *bytes_needed
= sizeof(uint32_t) - iter
.get_remaining();
120 crc_bl
.substr_of(iter
.get_bl(), start_off
, end_off
- start_off
);
125 if (crc
!= crc_bl
.crc32c(0)) {
131 void Entry::generate_test_instances(std::list
<Entry
*> &o
) {
132 o
.push_back(new Entry(1, 123, bufferlist()));
136 o
.push_back(new Entry(2, 123, bl
));
139 bool Entry::operator==(const Entry
& rhs
) const {
140 return (m_tag_tid
== rhs
.m_tag_tid
&& m_entry_tid
== rhs
.m_entry_tid
&&
141 const_cast<bufferlist
&>(m_data
).contents_equal(
142 const_cast<bufferlist
&>(rhs
.m_data
)));
145 std::ostream
&operator<<(std::ostream
&os
, const Entry
&entry
) {
146 os
<< "Entry[tag_tid=" << entry
.get_tag_tid() << ", "
147 << "entry_tid=" << entry
.get_entry_tid() << ", "
148 << "data size=" << entry
.get_data().length() << "]";
152 } // namespace journal