From: Jason Dillaman Date: Wed, 8 Jul 2015 18:58:38 +0000 (-0400) Subject: librbd: initial journal entry structures X-Git-Tag: v10.0.1~52^2~29 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6f18f0453a2f85bfbe2ba3a0fb0e52459bf6dd47;p=ceph.git librbd: initial journal entry structures New journal entries to cover AIO write/discard/flush operations. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/JournalTypes.cc b/src/librbd/JournalTypes.cc new file mode 100644 index 000000000000..01b850183354 --- /dev/null +++ b/src/librbd/JournalTypes.cc @@ -0,0 +1,181 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/JournalTypes.h" +#include "include/assert.h" +#include "include/stringify.h" +#include "common/Formatter.h" + +namespace librbd { +namespace journal { + +namespace { + +class EncodeEventVisitor : public boost::static_visitor { +public: + EncodeEventVisitor(bufferlist &bl) : m_bl(bl) { + } + + template + inline void operator()(const Event &event) const { + ::encode(static_cast(Event::EVENT_TYPE), m_bl); + event.encode(m_bl); + } +private: + bufferlist &m_bl; +}; + +class DecodeEventVisitor : public boost::static_visitor { +public: + DecodeEventVisitor(__u8 version, bufferlist::iterator &iter) + : m_version(version), m_iter(iter) { + } + + template + inline void operator()(Event &event) const { + event.decode(m_version, m_iter); + } +private: + __u8 m_version; + bufferlist::iterator &m_iter; +}; + +class DumpEventVisitor : public boost::static_visitor { +public: + DumpEventVisitor(Formatter *formatter) : m_formatter(formatter) {} + + template + inline void operator()(const Event &event) const { + EventType event_type = Event::EVENT_TYPE; + m_formatter->dump_string("event_type", stringify(event_type)); + event.dump(m_formatter); + } +private: + ceph::Formatter *m_formatter; +}; + +} // anonymous namespace + +void AioDiscardEvent::encode(bufferlist& bl) const { + ::encode(offset, bl); + ::encode(length, bl); +} + +void AioDiscardEvent::decode(__u8 version, bufferlist::iterator& it) { + ::decode(offset, it); + ::decode(length, it); +} + +void AioDiscardEvent::dump(Formatter *f) const { + f->dump_unsigned("offset", offset); + f->dump_unsigned("length", length); +} + +void AioWriteEvent::encode(bufferlist& bl) const { + ::encode(offset, bl); + ::encode(length, bl); + ::encode(data, bl); +} + +void AioWriteEvent::decode(__u8 version, bufferlist::iterator& it) { + ::decode(offset, it); + ::decode(length, it); + ::decode(data, it); +} + +void AioWriteEvent::dump(Formatter *f) const { + f->dump_unsigned("offset", offset); + f->dump_unsigned("length", length); +} + +void AioFlushEvent::encode(bufferlist& bl) const { +} + +void AioFlushEvent::decode(__u8 version, bufferlist::iterator& it) { +} + +void AioFlushEvent::dump(Formatter *f) const { +} + +void UnknownEvent::encode(bufferlist& bl) const { + assert(false); +} + +void UnknownEvent::decode(__u8 version, bufferlist::iterator& it) { +} + +void UnknownEvent::dump(Formatter *f) const { +} + +void EventEntry::encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + boost::apply_visitor(EncodeEventVisitor(bl), event); + ENCODE_FINISH(bl); +} + +void EventEntry::decode(bufferlist::iterator& it) { + DECODE_START(1, it); + + uint32_t event_type; + ::decode(event_type, it); + + // select the correct payload variant based upon the encoded op + switch (event_type) { + case EVENT_TYPE_AIO_DISCARD: + event = AioDiscardEvent(); + break; + case EVENT_TYPE_AIO_WRITE: + event = AioWriteEvent(); + break; + case EVENT_TYPE_AIO_FLUSH: + event = AioFlushEvent(); + break; + default: + event = UnknownEvent(); + break; + } + + boost::apply_visitor(DecodeEventVisitor(struct_v, it), event); + DECODE_FINISH(it); +} + +void EventEntry::dump(Formatter *f) const { + boost::apply_visitor(DumpEventVisitor(f), event); +} + +void EventEntry::generate_test_instances(std::list &o) { + o.push_back(new EventEntry(AioDiscardEvent())); + o.push_back(new EventEntry(AioDiscardEvent(123, 345))); + + bufferlist bl; + bl.append(std::string(32, '1')); + o.push_back(new EventEntry(AioWriteEvent())); + o.push_back(new EventEntry(AioWriteEvent(123, 456, bl))); + + o.push_back(new EventEntry(AioFlushEvent())); +} + +} // namespace journal +} // namespace librbd + +std::ostream &operator<<(std::ostream &out, + const librbd::journal::EventType &type) { + using namespace librbd::journal; + + switch (type) { + case EVENT_TYPE_AIO_DISCARD: + out << "AioDiscard"; + break; + case EVENT_TYPE_AIO_WRITE: + out << "AioWrite"; + break; + case EVENT_TYPE_AIO_FLUSH: + out << "AioFlush"; + break; + default: + out << "Unknown (" << static_cast(type) << ")"; + break; + } + return out; +} + diff --git a/src/librbd/JournalTypes.h b/src/librbd/JournalTypes.h new file mode 100644 index 000000000000..c631964e45eb --- /dev/null +++ b/src/librbd/JournalTypes.h @@ -0,0 +1,105 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_JOURNAL_TYPES_H +#define CEPH_LIBRBD_JOURNAL_TYPES_H + +#include "include/int_types.h" +#include "include/buffer.h" +#include "include/encoding.h" +#include +#include + +namespace ceph { +class Formatter; +} + +namespace librbd { +namespace journal { + +enum EventType { + EVENT_TYPE_AIO_DISCARD = 0, + EVENT_TYPE_AIO_WRITE = 1, + EVENT_TYPE_AIO_FLUSH = 2 +}; + +struct AioDiscardEvent { + static const EventType EVENT_TYPE = EVENT_TYPE_AIO_DISCARD; + + uint64_t offset; + size_t length; + + AioDiscardEvent() : offset(0), length(0) { + } + AioDiscardEvent(uint64_t _offset, size_t _length) + : offset(_offset), length(_length) { + } + + void encode(bufferlist& bl) const; + void decode(__u8 version, bufferlist::iterator& it); + void dump(Formatter *f) const; +}; + +struct AioWriteEvent { + static const EventType EVENT_TYPE = EVENT_TYPE_AIO_WRITE; + + uint64_t offset; + size_t length; + bufferlist data; + + AioWriteEvent() : offset(0), length(0) { + } + AioWriteEvent(uint64_t _offset, size_t _length, const bufferlist &_data) + : offset(_offset), length(_length), data(_data) { + } + + void encode(bufferlist& bl) const; + void decode(__u8 version, bufferlist::iterator& it); + void dump(Formatter *f) const; +}; + +struct UnknownEvent { + static const EventType EVENT_TYPE = static_cast(-1); + + void encode(bufferlist& bl) const; + void decode(__u8 version, bufferlist::iterator& it); + void dump(Formatter *f) const; +}; + +struct AioFlushEvent { + static const EventType EVENT_TYPE = EVENT_TYPE_AIO_FLUSH; + + void encode(bufferlist& bl) const; + void decode(__u8 version, bufferlist::iterator& it); + void dump(Formatter *f) const; +}; + +typedef boost::variant Event; + +struct EventEntry { + EventEntry() : event(UnknownEvent()) { + } + EventEntry(const Event &_event) : event(_event) { + } + + Event event; + + void encode(bufferlist& bl) const; + void decode(bufferlist::iterator& it); + void dump(Formatter *f) const; + + static void generate_test_instances(std::list &o); +}; + +} // namespace journal +} // namespace librbd + +std::ostream &operator<<(std::ostream &out, + const librbd::journal::EventType &type); + +WRITE_CLASS_ENCODER(librbd::journal::EventEntry); + +#endif // CEPH_LIBRBD_JOURNAL_TYPES_H diff --git a/src/librbd/Makefile.am b/src/librbd/Makefile.am index f8691124415f..84fed189ffc1 100644 --- a/src/librbd/Makefile.am +++ b/src/librbd/Makefile.am @@ -1,4 +1,5 @@ librbd_types_la_SOURCES = \ + librbd/JournalTypes.cc \ librbd/WatchNotifyTypes.cc noinst_LTLIBRARIES += librbd_types.la @@ -65,6 +66,7 @@ noinst_HEADERS += \ librbd/ImageCtx.h \ librbd/ImageWatcher.h \ librbd/internal.h \ + librbd/JournalTypes.h \ librbd/LibrbdAdminSocketHook.h \ librbd/LibrbdWriteback.h \ librbd/ObjectMap.h \