]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/journal: handle compare_and_write event
authorwangzhengyong <wangzhengyong@cmss.chinamobile.com>
Mon, 12 Jun 2017 13:23:04 +0000 (21:23 +0800)
committerJason Dillaman <dillaman@redhat.com>
Wed, 26 Jul 2017 12:00:06 +0000 (08:00 -0400)
Signed-off-by: Zhengyong Wang <wangzhengyong@cmss.chinamobile.com>
src/include/int_types.h
src/librbd/journal/Replay.cc
src/librbd/journal/Replay.h
src/librbd/journal/Types.cc
src/librbd/journal/Types.h

index 61ad79713924781f107738d6f87e584dba2f1151..56b2723f3a5c0077af552b14f60613db43033f41 100644 (file)
@@ -50,4 +50,16 @@ typedef __u32 __bitwise__ __be32;
 typedef __u64 __bitwise__ __le64;
 typedef __u64 __bitwise__ __be64;
 
+#ifndef BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif
+
+#ifndef BOOST_MPL_LIMIT_VECTOR_SIZE
+#define BOOST_MPL_LIMIT_VECTOR_SIZE 30 // or whatever you need
+#endif
+
+#ifndef BOOST_MPL_LIMIT_MAP_SIZE
+#define BOOST_MPL_LIMIT_MAP_SIZE 30 // or whatever you need
+#endif
+
 #endif
index 29289ac580a4885ca53e0355ba652e145df5ef2b..92accbc1382aaf91cc25982ab0253f5a64412a63 100644 (file)
@@ -341,7 +341,8 @@ void Replay<I>::handle_event(const journal::AioDiscardEvent &event,
   bool flush_required;
   auto aio_comp = create_aio_modify_completion(on_ready, on_safe,
                                                io::AIO_TYPE_DISCARD,
-                                               &flush_required);
+                                               &flush_required,
+                                               {});
   if (aio_comp == nullptr) {
     return;
   }
@@ -370,7 +371,8 @@ void Replay<I>::handle_event(const journal::AioWriteEvent &event,
   bool flush_required;
   auto aio_comp = create_aio_modify_completion(on_ready, on_safe,
                                                io::AIO_TYPE_WRITE,
-                                               &flush_required);
+                                               &flush_required,
+                                               {});
   if (aio_comp == nullptr) {
     return;
   }
@@ -417,7 +419,8 @@ void Replay<I>::handle_event(const journal::AioWriteSameEvent &event,
   bool flush_required;
   auto aio_comp = create_aio_modify_completion(on_ready, on_safe,
                                                io::AIO_TYPE_WRITESAME,
-                                               &flush_required);
+                                               &flush_required,
+                                               {});
   if (aio_comp == nullptr) {
     return;
   }
@@ -435,6 +438,33 @@ void Replay<I>::handle_event(const journal::AioWriteSameEvent &event,
   }
 }
 
+ template <typename I>
+ void Replay<I>::handle_event(const journal::AioCompareAndWriteEvent &event,
+                              Context *on_ready, Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << ": AIO CompareAndWrite event" << dendl;
+
+  bufferlist cmp_data = event.cmp_data;
+  bufferlist write_data = event.write_data;
+  bool flush_required;
+  auto aio_comp = create_aio_modify_completion(on_ready, on_safe,
+                                               io::AIO_TYPE_COMPARE_AND_WRITE,
+                                               &flush_required,
+                                               {-EILSEQ});
+  io::ImageRequest<I>::aio_compare_and_write(&m_image_ctx, aio_comp,
+                                             {{event.offset, event.length}},
+                                             std::move(cmp_data),
+                                             std::move(write_data),
+                                             nullptr, 0, {});
+  if (flush_required) {
+    m_lock.Lock();
+    auto flush_comp = create_aio_flush_completion(nullptr);
+    m_lock.Unlock();
+
+    io::ImageRequest<I>::aio_flush(&m_image_ctx, flush_comp, {});
+  }
+}
+
 template <typename I>
 void Replay<I>::handle_event(const journal::OpFinishEvent &event,
                              Context *on_ready, Context *on_safe) {
@@ -826,7 +856,7 @@ void Replay<I>::handle_event(const journal::UnknownEvent &event,
 
 template <typename I>
 void Replay<I>::handle_aio_modify_complete(Context *on_ready, Context *on_safe,
-                                           int r) {
+                                           int r, std::set<int> &filters) {
   Mutex::Locker locker(m_lock);
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << ": on_ready=" << on_ready << ", "
@@ -835,6 +865,10 @@ void Replay<I>::handle_aio_modify_complete(Context *on_ready, Context *on_safe,
   if (on_ready != nullptr) {
     on_ready->complete(0);
   }
+
+  if (filters.find(r) != filters.end())
+    r = 0;
+
   if (r < 0) {
     lderr(cct) << ": AIO modify op failed: " << cpp_strerror(r) << dendl;
     on_safe->complete(r);
@@ -1004,9 +1038,11 @@ void Replay<I>::handle_op_complete(uint64_t op_tid, int r) {
 
 template <typename I>
 io::AioCompletion *
-Replay<I>::create_aio_modify_completion(Context *on_ready, Context *on_safe,
+Replay<I>::create_aio_modify_completion(Context *on_ready,
+                                        Context *on_safe,
                                         io::aio_type_t aio_type,
-                                        bool *flush_required) {
+                                        bool *flush_required,
+                                        std::set<int> &&filters) {
   Mutex::Locker locker(m_lock);
   CephContext *cct = m_image_ctx.cct;
   assert(m_on_aio_ready == nullptr);
@@ -1048,7 +1084,7 @@ Replay<I>::create_aio_modify_completion(Context *on_ready, Context *on_safe,
   // event. when flushed, the completion of the next flush will fire the
   // on_safe callback
   auto aio_comp = io::AioCompletion::create_and_start<Context>(
-    new C_AioModifyComplete(this, on_ready, on_safe),
+    new C_AioModifyComplete(this, on_ready, on_safe, std::move(filters)),
     util::get_image_ctx(&m_image_ctx), aio_type);
   return aio_comp;
 }
index 5b2219851371f70ee341be40a8bbef2c1f48dc3f..4a4260cb9f00d8d30c5b464bb2c5620fa444f9cd 100644 (file)
@@ -77,11 +77,14 @@ private:
     Replay *replay;
     Context *on_ready;
     Context *on_safe;
-    C_AioModifyComplete(Replay *replay, Context *on_ready, Context *on_safe)
-      : replay(replay), on_ready(on_ready), on_safe(on_safe) {
+    std::set<int> filters;
+    C_AioModifyComplete(Replay *replay, Context *on_ready,
+                        Context *on_safe, std::set<int> &&filters)
+      : replay(replay), on_ready(on_ready), on_safe(on_safe),
+        filters(std::move(filters)) {
     }
     void finish(int r) override {
-      replay->handle_aio_modify_complete(on_ready, on_safe, r);
+      replay->handle_aio_modify_complete(on_ready, on_safe, r, filters);
     }
   };
 
@@ -136,6 +139,8 @@ private:
                     Context *on_safe);
   void handle_event(const AioWriteSameEvent &event, Context *on_ready,
                     Context *on_safe);
+  void handle_event(const AioCompareAndWriteEvent &event, Context *on_ready,
+                    Context *on_safe);
   void handle_event(const AioFlushEvent &event, Context *on_ready,
                     Context *on_safe);
   void handle_event(const OpFinishEvent &event, Context *on_ready,
@@ -171,7 +176,8 @@ private:
   void handle_event(const UnknownEvent &event, Context *on_ready,
                     Context *on_safe);
 
-  void handle_aio_modify_complete(Context *on_ready, Context *on_safe, int r);
+  void handle_aio_modify_complete(Context *on_ready, Context *on_safe,
+                                  int r, std::set<int> &filters);
   void handle_aio_flush_complete(Context *on_flush_safe, Contexts &on_safe_ctxs,
                                  int r);
 
@@ -182,7 +188,8 @@ private:
   io::AioCompletion *create_aio_modify_completion(Context *on_ready,
                                                   Context *on_safe,
                                                   io::aio_type_t aio_type,
-                                                  bool *flush_required);
+                                                  bool *flush_required,
+                                                  std::set<int> &&filters);
   io::AioCompletion *create_aio_flush_completion(Context *on_safe);
   void handle_aio_completion(io::AioCompletion *aio_comp);
 
index 857542bd74b11b8878929fe12c02421e780af4ca..83e80766f0061aa27f2fc53fd28c73dbce2c1d65 100644 (file)
@@ -126,6 +126,29 @@ void AioWriteSameEvent::dump(Formatter *f) const {
   f->dump_unsigned("length", length);
 }
 
+uint32_t AioCompareAndWriteEvent::get_fixed_size() {
+  return EventEntry::get_fixed_size() + 32 /* offset, length */;
+}
+
+void AioCompareAndWriteEvent::encode(bufferlist& bl) const {
+  ::encode(offset, bl);
+  ::encode(length, bl);
+  ::encode(cmp_data, bl);
+  ::encode(write_data, bl);
+}
+
+void AioCompareAndWriteEvent::decode(__u8 version, bufferlist::iterator& it) {
+  ::decode(offset, it);
+  ::decode(length, it);
+  ::decode(cmp_data, it);
+  ::decode(write_data, it);
+}
+
+void AioCompareAndWriteEvent::dump(Formatter *f) const {
+  f->dump_unsigned("offset", offset);
+  f->dump_unsigned("length", length);
+}
+
 void AioFlushEvent::encode(bufferlist& bl) const {
 }
 
@@ -415,6 +438,9 @@ void EventEntry::decode(bufferlist::iterator& it) {
   case EVENT_TYPE_AIO_WRITESAME:
     event = AioWriteSameEvent();
     break;
+  case EVENT_TYPE_AIO_COMPARE_AND_WRITE:
+    event = AioCompareAndWriteEvent();
+    break;
   default:
     event = UnknownEvent();
     break;
@@ -764,6 +790,9 @@ std::ostream &operator<<(std::ostream &out, const EventType &type) {
   case EVENT_TYPE_AIO_WRITESAME:
     out << "AioWriteSame";
     break;
+  case EVENT_TYPE_AIO_COMPARE_AND_WRITE:
+    out << "AioCompareAndWrite";
+    break;
   default:
     out << "Unknown (" << static_cast<uint32_t>(type) << ")";
     break;
index adc6f29557520d156848078e7750d254ede13ae4..085ec023f7ef761b3ad36b7cab7aae1c0f045149 100644 (file)
@@ -15,6 +15,7 @@
 #include <boost/none.hpp>
 #include <boost/optional.hpp>
 #include <boost/variant.hpp>
+#include <boost/mpl/vector.hpp>
 
 namespace ceph {
 class Formatter;
@@ -24,25 +25,26 @@ namespace librbd {
 namespace journal {
 
 enum EventType {
-  EVENT_TYPE_AIO_DISCARD     = 0,
-  EVENT_TYPE_AIO_WRITE       = 1,
-  EVENT_TYPE_AIO_FLUSH       = 2,
-  EVENT_TYPE_OP_FINISH       = 3,
-  EVENT_TYPE_SNAP_CREATE     = 4,
-  EVENT_TYPE_SNAP_REMOVE     = 5,
-  EVENT_TYPE_SNAP_RENAME     = 6,
-  EVENT_TYPE_SNAP_PROTECT    = 7,
-  EVENT_TYPE_SNAP_UNPROTECT  = 8,
-  EVENT_TYPE_SNAP_ROLLBACK   = 9,
-  EVENT_TYPE_RENAME          = 10,
-  EVENT_TYPE_RESIZE          = 11,
-  EVENT_TYPE_FLATTEN         = 12,
-  EVENT_TYPE_DEMOTE_PROMOTE  = 13,
-  EVENT_TYPE_SNAP_LIMIT      = 14,
-  EVENT_TYPE_UPDATE_FEATURES = 15,
-  EVENT_TYPE_METADATA_SET    = 16,
-  EVENT_TYPE_METADATA_REMOVE = 17,
-  EVENT_TYPE_AIO_WRITESAME   = 18,
+  EVENT_TYPE_AIO_DISCARD           = 0,
+  EVENT_TYPE_AIO_WRITE             = 1,
+  EVENT_TYPE_AIO_FLUSH             = 2,
+  EVENT_TYPE_OP_FINISH             = 3,
+  EVENT_TYPE_SNAP_CREATE           = 4,
+  EVENT_TYPE_SNAP_REMOVE           = 5,
+  EVENT_TYPE_SNAP_RENAME           = 6,
+  EVENT_TYPE_SNAP_PROTECT          = 7,
+  EVENT_TYPE_SNAP_UNPROTECT        = 8,
+  EVENT_TYPE_SNAP_ROLLBACK         = 9,
+  EVENT_TYPE_RENAME                = 10,
+  EVENT_TYPE_RESIZE                = 11,
+  EVENT_TYPE_FLATTEN               = 12,
+  EVENT_TYPE_DEMOTE_PROMOTE        = 13,
+  EVENT_TYPE_SNAP_LIMIT            = 14,
+  EVENT_TYPE_UPDATE_FEATURES       = 15,
+  EVENT_TYPE_METADATA_SET          = 16,
+  EVENT_TYPE_METADATA_REMOVE       = 17,
+  EVENT_TYPE_AIO_WRITESAME         = 18,
+  EVENT_TYPE_AIO_COMPARE_AND_WRITE = 19,
 };
 
 struct AioDiscardEvent {
@@ -102,6 +104,28 @@ struct AioWriteSameEvent {
   void dump(Formatter *f) const;
 };
 
+struct AioCompareAndWriteEvent {
+  static const EventType TYPE = EVENT_TYPE_AIO_COMPARE_AND_WRITE;
+
+  uint64_t offset;
+  uint64_t length;
+  bufferlist cmp_data;
+  bufferlist write_data;
+
+  static uint32_t get_fixed_size();
+
+  AioCompareAndWriteEvent() : offset(0), length(0) {
+  }
+  AioCompareAndWriteEvent(uint64_t _offset, uint64_t _length,
+                          const bufferlist &_cmp_data, const bufferlist &_write_data)
+    : offset(_offset), length(_length), cmp_data(_cmp_data), write_data(_write_data) {
+  }
+
+  void encode(bufferlist& bl) const;
+  void decode(__u8 version, bufferlist::iterator& it);
+  void dump(Formatter *f) const;
+};
+
 struct AioFlushEvent {
   static const EventType TYPE = EVENT_TYPE_AIO_FLUSH;
 
@@ -383,26 +407,28 @@ struct UnknownEvent {
   void dump(Formatter *f) const;
 };
 
-typedef boost::variant<AioDiscardEvent,
-                       AioWriteEvent,
-                       AioFlushEvent,
-                       OpFinishEvent,
-                       SnapCreateEvent,
-                       SnapRemoveEvent,
-                       SnapRenameEvent,
-                       SnapProtectEvent,
-                       SnapUnprotectEvent,
-                       SnapRollbackEvent,
-                       RenameEvent,
-                       ResizeEvent,
-                       FlattenEvent,
-                       DemotePromoteEvent,
-                      SnapLimitEvent,
-                       UpdateFeaturesEvent,
-                       MetadataSetEvent,
-                       MetadataRemoveEvent,
-                       AioWriteSameEvent,
-                       UnknownEvent> Event;
+typedef boost::mpl::vector<AioDiscardEvent,
+                           AioWriteEvent,
+                           AioFlushEvent,
+                           OpFinishEvent,
+                           SnapCreateEvent,
+                           SnapRemoveEvent,
+                           SnapRenameEvent,
+                           SnapProtectEvent,
+                           SnapUnprotectEvent,
+                           SnapRollbackEvent,
+                           RenameEvent,
+                           ResizeEvent,
+                           FlattenEvent,
+                           DemotePromoteEvent,
+                           SnapLimitEvent,
+                           UpdateFeaturesEvent,
+                           MetadataSetEvent,
+                           MetadataRemoveEvent,
+                           AioWriteSameEvent,
+                           AioCompareAndWriteEvent,
+                           UnknownEvent> EventVector;
+typedef boost::make_variant_over<EventVector>::type Event;
 
 struct EventEntry {
   static uint32_t get_fixed_size() {