X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fjournal%2FEntry.cc;fp=src%2Fceph%2Fsrc%2Fjournal%2FEntry.cc;h=257fa583af5e4eb8fd48508f659d751ae5952855;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/journal/Entry.cc b/src/ceph/src/journal/Entry.cc new file mode 100644 index 0000000..257fa58 --- /dev/null +++ b/src/ceph/src/journal/Entry.cc @@ -0,0 +1,149 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "journal/Entry.h" +#include "include/encoding.h" +#include "include/stringify.h" +#include "common/Formatter.h" +#include + +#define dout_subsys ceph_subsys_journaler +#undef dout_prefix +#define dout_prefix *_dout << "Entry: " << this << " " + +namespace journal { + +namespace { + +const uint32_t HEADER_FIXED_SIZE = 25; /// preamble, version, entry tid, tag id +const uint32_t REMAINDER_FIXED_SIZE = 8; /// data size, crc + +} // anonymous namespace + +uint32_t Entry::get_fixed_size() { + return HEADER_FIXED_SIZE + REMAINDER_FIXED_SIZE; +} + +void Entry::encode(bufferlist &bl) const { + bufferlist data_bl; + ::encode(preamble, data_bl); + ::encode(static_cast(1), data_bl); + ::encode(m_entry_tid, data_bl); + ::encode(m_tag_tid, data_bl); + ::encode(m_data, data_bl); + + uint32_t crc = data_bl.crc32c(0); + uint32_t bl_offset = bl.length(); + bl.claim_append(data_bl); + ::encode(crc, bl); + assert(get_fixed_size() + m_data.length() + bl_offset == bl.length()); +} + +void Entry::decode(bufferlist::iterator &iter) { + uint32_t start_offset = iter.get_off(); + uint64_t bl_preamble; + ::decode(bl_preamble, iter); + if (bl_preamble != preamble) { + throw buffer::malformed_input("incorrect preamble: " + + stringify(bl_preamble)); + } + + uint8_t version; + ::decode(version, iter); + if (version != 1) { + throw buffer::malformed_input("unknown version: " + stringify(version)); + } + + ::decode(m_entry_tid, iter); + ::decode(m_tag_tid, iter); + ::decode(m_data, iter); + uint32_t end_offset = iter.get_off(); + + uint32_t crc; + ::decode(crc, iter); + + bufferlist data_bl; + data_bl.substr_of(iter.get_bl(), start_offset, end_offset - start_offset); + uint32_t actual_crc = data_bl.crc32c(0); + if (crc != actual_crc) { + throw buffer::malformed_input("crc mismatch: " + stringify(crc) + + " != " + stringify(actual_crc)); + } +} + +void Entry::dump(Formatter *f) const { + f->dump_unsigned("tag_tid", m_tag_tid); + f->dump_unsigned("entry_tid", m_entry_tid); + + std::stringstream data; + m_data.hexdump(data); + f->dump_string("data", data.str()); +} + +bool Entry::is_readable(bufferlist::iterator iter, uint32_t *bytes_needed) { + uint32_t start_off = iter.get_off(); + if (iter.get_remaining() < HEADER_FIXED_SIZE) { + *bytes_needed = HEADER_FIXED_SIZE - iter.get_remaining(); + return false; + } + uint64_t bl_preamble; + ::decode(bl_preamble, iter); + if (bl_preamble != preamble) { + *bytes_needed = 0; + return false; + } + iter.advance(HEADER_FIXED_SIZE - sizeof(bl_preamble)); + + if (iter.get_remaining() < sizeof(uint32_t)) { + *bytes_needed = sizeof(uint32_t) - iter.get_remaining(); + return false; + } + uint32_t data_size; + ::decode(data_size, iter); + + if (iter.get_remaining() < data_size) { + *bytes_needed = data_size - iter.get_remaining(); + return false; + } + iter.advance(data_size); + uint32_t end_off = iter.get_off(); + + if (iter.get_remaining() < sizeof(uint32_t)) { + *bytes_needed = sizeof(uint32_t) - iter.get_remaining(); + return false; + } + + bufferlist crc_bl; + crc_bl.substr_of(iter.get_bl(), start_off, end_off - start_off); + + *bytes_needed = 0; + uint32_t crc; + ::decode(crc, iter); + if (crc != crc_bl.crc32c(0)) { + return false; + } + return true; +} + +void Entry::generate_test_instances(std::list &o) { + o.push_back(new Entry(1, 123, bufferlist())); + + bufferlist bl; + bl.append("data"); + o.push_back(new Entry(2, 123, bl)); +} + +bool Entry::operator==(const Entry& rhs) const { + return (m_tag_tid == rhs.m_tag_tid && m_entry_tid == rhs.m_entry_tid && + const_cast(m_data).contents_equal( + const_cast(rhs.m_data))); +} + +std::ostream &operator<<(std::ostream &os, const Entry &entry) { + os << "Entry[tag_tid=" << entry.get_tag_tid() << ", " + << "entry_tid=" << entry.get_entry_tid() << ", " + << "data size=" << entry.get_data().length() << "]"; + return os; +} + +} // namespace journal