]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: initial journal entry structures
authorJason Dillaman <dillaman@redhat.com>
Wed, 8 Jul 2015 18:58:38 +0000 (14:58 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 13 Nov 2015 01:17:53 +0000 (20:17 -0500)
New journal entries to cover AIO write/discard/flush operations.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/JournalTypes.cc [new file with mode: 0644]
src/librbd/JournalTypes.h [new file with mode: 0644]
src/librbd/Makefile.am

diff --git a/src/librbd/JournalTypes.cc b/src/librbd/JournalTypes.cc
new file mode 100644 (file)
index 0000000..01b8501
--- /dev/null
@@ -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<void> {
+public:
+  EncodeEventVisitor(bufferlist &bl) : m_bl(bl) {
+  }
+
+  template <typename Event>
+  inline void operator()(const Event &event) const {
+    ::encode(static_cast<uint32_t>(Event::EVENT_TYPE), m_bl);
+    event.encode(m_bl);
+  }
+private:
+  bufferlist &m_bl;
+};
+
+class DecodeEventVisitor : public boost::static_visitor<void> {
+public:
+  DecodeEventVisitor(__u8 version, bufferlist::iterator &iter)
+    : m_version(version), m_iter(iter) {
+  }
+
+  template <typename Event>
+  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<void> {
+public:
+  DumpEventVisitor(Formatter *formatter) : m_formatter(formatter) {}
+
+  template <typename Event>
+  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<EventEntry *> &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<uint32_t>(type) << ")";
+    break;
+  }
+  return out;
+}
+
diff --git a/src/librbd/JournalTypes.h b/src/librbd/JournalTypes.h
new file mode 100644 (file)
index 0000000..c631964
--- /dev/null
@@ -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 <iosfwd>
+#include <boost/variant.hpp>
+
+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<EventType>(-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<AioDiscardEvent,
+                       AioWriteEvent,
+                       AioFlushEvent,
+                       UnknownEvent> 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<EventEntry *> &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
index f8691124415f14393e13d254afcd76e63361849b..84fed189ffc1b259bc92890ee256f35f3a62fb6b 100644 (file)
@@ -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 \