]> git.proxmox.com Git - ceph.git/blame - ceph/src/journal/Entry.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / journal / Entry.cc
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#include "journal/Entry.h"
5#include "include/encoding.h"
6#include "include/stringify.h"
7#include "common/Formatter.h"
8#include <strstream>
9
10#define dout_subsys ceph_subsys_journaler
11#undef dout_prefix
12#define dout_prefix *_dout << "Entry: " << this << " "
13
14namespace journal {
15
16namespace {
17
18const uint32_t HEADER_FIXED_SIZE = 25; /// preamble, version, entry tid, tag id
19const uint32_t REMAINDER_FIXED_SIZE = 8; /// data size, crc
20
21} // anonymous namespace
22
23uint32_t Entry::get_fixed_size() {
24 return HEADER_FIXED_SIZE + REMAINDER_FIXED_SIZE;
25}
26
27void Entry::encode(bufferlist &bl) const {
11fdf7f2 28 using ceph::encode;
7c673cae 29 bufferlist data_bl;
11fdf7f2
TL
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);
7c673cae
FG
35
36 uint32_t crc = data_bl.crc32c(0);
37 uint32_t bl_offset = bl.length();
38 bl.claim_append(data_bl);
11fdf7f2
TL
39 encode(crc, bl);
40 ceph_assert(get_fixed_size() + m_data.length() + bl_offset == bl.length());
7c673cae
FG
41}
42
11fdf7f2
TL
43void Entry::decode(bufferlist::const_iterator &iter) {
44 using ceph::decode;
7c673cae
FG
45 uint32_t start_offset = iter.get_off();
46 uint64_t bl_preamble;
11fdf7f2 47 decode(bl_preamble, iter);
7c673cae
FG
48 if (bl_preamble != preamble) {
49 throw buffer::malformed_input("incorrect preamble: " +
50 stringify(bl_preamble));
51 }
52
53 uint8_t version;
11fdf7f2 54 decode(version, iter);
7c673cae
FG
55 if (version != 1) {
56 throw buffer::malformed_input("unknown version: " + stringify(version));
57 }
58
11fdf7f2
TL
59 decode(m_entry_tid, iter);
60 decode(m_tag_tid, iter);
61 decode(m_data, iter);
7c673cae
FG
62 uint32_t end_offset = iter.get_off();
63
64 uint32_t crc;
11fdf7f2 65 decode(crc, iter);
7c673cae
FG
66
67 bufferlist data_bl;
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));
73 }
74}
75
76void Entry::dump(Formatter *f) const {
77 f->dump_unsigned("tag_tid", m_tag_tid);
78 f->dump_unsigned("entry_tid", m_entry_tid);
79
80 std::stringstream data;
81 m_data.hexdump(data);
82 f->dump_string("data", data.str());
83}
84
11fdf7f2
TL
85bool Entry::is_readable(bufferlist::const_iterator iter, uint32_t *bytes_needed) {
86 using ceph::decode;
7c673cae
FG
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();
90 return false;
91 }
92 uint64_t bl_preamble;
11fdf7f2 93 decode(bl_preamble, iter);
7c673cae
FG
94 if (bl_preamble != preamble) {
95 *bytes_needed = 0;
96 return false;
97 }
98 iter.advance(HEADER_FIXED_SIZE - sizeof(bl_preamble));
99
100 if (iter.get_remaining() < sizeof(uint32_t)) {
101 *bytes_needed = sizeof(uint32_t) - iter.get_remaining();
102 return false;
103 }
104 uint32_t data_size;
11fdf7f2 105 decode(data_size, iter);
7c673cae
FG
106
107 if (iter.get_remaining() < data_size) {
108 *bytes_needed = data_size - iter.get_remaining();
109 return false;
110 }
111 iter.advance(data_size);
112 uint32_t end_off = iter.get_off();
113
114 if (iter.get_remaining() < sizeof(uint32_t)) {
115 *bytes_needed = sizeof(uint32_t) - iter.get_remaining();
116 return false;
117 }
118
119 bufferlist crc_bl;
120 crc_bl.substr_of(iter.get_bl(), start_off, end_off - start_off);
121
122 *bytes_needed = 0;
123 uint32_t crc;
11fdf7f2 124 decode(crc, iter);
7c673cae
FG
125 if (crc != crc_bl.crc32c(0)) {
126 return false;
127 }
128 return true;
129}
130
131void Entry::generate_test_instances(std::list<Entry *> &o) {
132 o.push_back(new Entry(1, 123, bufferlist()));
133
134 bufferlist bl;
135 bl.append("data");
136 o.push_back(new Entry(2, 123, bl));
137}
138
139bool 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)));
143}
144
145std::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() << "]";
149 return os;
150}
151
152} // namespace journal