]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/librbd/io/ImageDispatchSpec.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / librbd / io / ImageDispatchSpec.h
index bb326374a8451f1ff7ce4430db8ff932e8aab3e5..ee95f21be63f75cfce67eb529afcddf8501220b5 100644 (file)
@@ -6,11 +6,13 @@
 
 #include "include/int_types.h"
 #include "include/buffer.h"
+#include "include/Context.h"
 #include "common/zipkin_trace.h"
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/Types.h"
 #include "librbd/io/ReadResult.h"
 #include <boost/variant/variant.hpp>
+#include <atomic>
 
 namespace librbd {
 
@@ -18,13 +20,29 @@ class ImageCtx;
 
 namespace io {
 
-template <typename ImageCtxT = ImageCtx>
+struct ImageDispatcherInterface;
+
 class ImageDispatchSpec {
+private:
+  // helper to avoid extra heap allocation per object IO
+  struct C_Dispatcher : public Context {
+    ImageDispatchSpec* image_dispatch_spec;
+
+    C_Dispatcher(ImageDispatchSpec* image_dispatch_spec)
+      : image_dispatch_spec(image_dispatch_spec) {
+    }
+
+    void complete(int r) override;
+    void finish(int r) override;
+  };
+
 public:
   struct Read {
     ReadResult read_result;
+    int read_flags;
 
-    Read(ReadResult &&read_result) : read_result(std::move(read_result)) {
+    Read(ReadResult &&read_result, int read_flags)
+      : read_result(std::move(read_result)), read_flags(read_flags) {
     }
   };
 
@@ -69,128 +87,157 @@ public:
     }
   };
 
-  static ImageDispatchSpec* create_read_request(
-      ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents,
-      ReadResult &&read_result, int op_flags,
-      const ZTracer::Trace &parent_trace) {
-    return new ImageDispatchSpec(image_ctx, aio_comp,
+  struct ListSnaps {
+    SnapIds snap_ids;
+    int list_snaps_flags;
+    SnapshotDelta* snapshot_delta;
+
+    ListSnaps(SnapIds&& snap_ids, int list_snaps_flags,
+              SnapshotDelta* snapshot_delta)
+      : snap_ids(std::move(snap_ids)), list_snaps_flags(list_snaps_flags),
+        snapshot_delta(snapshot_delta) {
+    }
+  };
+
+  typedef boost::variant<Read,
+                         Discard,
+                         Write,
+                         WriteSame,
+                         CompareAndWrite,
+                         Flush,
+                         ListSnaps> Request;
+
+  C_Dispatcher dispatcher_ctx;
+
+  ImageDispatcherInterface* image_dispatcher;
+  ImageDispatchLayer dispatch_layer;
+  std::atomic<uint32_t> image_dispatch_flags = 0;
+  DispatchResult dispatch_result = DISPATCH_RESULT_INVALID;
+
+  AioCompletion* aio_comp;
+  Extents image_extents;
+  Request request;
+  IOContext io_context;
+  int op_flags;
+  ZTracer::Trace parent_trace;
+  uint64_t tid = 0;
+
+  template <typename ImageCtxT = ImageCtx>
+  static ImageDispatchSpec* create_read(
+      ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
+      AioCompletion *aio_comp, Extents &&image_extents,
+      ReadResult &&read_result, IOContext io_context, int op_flags,
+      int read_flags, const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+                                 image_dispatch_layer, aio_comp,
                                  std::move(image_extents),
-                                 Read{std::move(read_result)},
-                                 op_flags, parent_trace, 0);
+                                 Read{std::move(read_result), read_flags},
+                                 io_context, op_flags, parent_trace);
   }
 
-  static ImageDispatchSpec* create_discard_request(
-      ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len,
-      uint32_t discard_granularity_bytes, const ZTracer::Trace &parent_trace, uint64_t tid) {
-    return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
+  template <typename ImageCtxT = ImageCtx>
+  static ImageDispatchSpec* create_discard(
+      ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
+      AioCompletion *aio_comp, uint64_t off, uint64_t len,
+      uint32_t discard_granularity_bytes, IOContext io_context,
+      const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+                                 image_dispatch_layer, aio_comp, {{off, len}},
                                  Discard{discard_granularity_bytes},
-                                 0, parent_trace, tid);
+                                 io_context, 0, parent_trace);
   }
 
-  static ImageDispatchSpec* create_write_request(
-      ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents,
-      bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid) {
-    return new ImageDispatchSpec(image_ctx, aio_comp, std::move(image_extents),
-                                 Write{std::move(bl)}, op_flags, parent_trace, tid);
+  template <typename ImageCtxT = ImageCtx>
+  static ImageDispatchSpec* create_write(
+      ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
+      AioCompletion *aio_comp, Extents &&image_extents,
+      bufferlist &&bl, IOContext io_context, int op_flags,
+      const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+                                 image_dispatch_layer, aio_comp,
+                                 std::move(image_extents), Write{std::move(bl)},
+                                 io_context, op_flags, parent_trace);
   }
 
-  static ImageDispatchSpec* create_write_same_request(
-      ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len,
-      bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid) {
-    return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
-                                 WriteSame{std::move(bl)}, op_flags,
-                                 parent_trace, tid);
+  template <typename ImageCtxT = ImageCtx>
+  static ImageDispatchSpec* create_write_same(
+      ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
+      AioCompletion *aio_comp, uint64_t off, uint64_t len,
+      bufferlist &&bl, IOContext io_context, int op_flags,
+      const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+                                 image_dispatch_layer, aio_comp,
+                                 {{off, len}}, WriteSame{std::move(bl)},
+                                 io_context, op_flags, parent_trace);
   }
 
-  static ImageDispatchSpec* create_compare_and_write_request(
-      ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents,
+  template <typename ImageCtxT = ImageCtx>
+  static ImageDispatchSpec* create_compare_and_write(
+      ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
+      AioCompletion *aio_comp, Extents &&image_extents,
       bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset,
-      int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid) {
-    return new ImageDispatchSpec(image_ctx, aio_comp,
+      IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+                                 image_dispatch_layer, aio_comp,
                                  std::move(image_extents),
                                  CompareAndWrite{std::move(cmp_bl),
                                                  std::move(bl),
                                                  mismatch_offset},
-                                 op_flags, parent_trace, tid);
+                                 io_context, op_flags, parent_trace);
   }
 
-  static ImageDispatchSpec* create_flush_request(
-      ImageCtxT &image_ctx, AioCompletion *aio_comp,
-      FlushSource flush_source, const ZTracer::Trace &parent_trace) {
-    return new ImageDispatchSpec(image_ctx, aio_comp, {}, Flush{flush_source},
-                                 0, parent_trace, 0);
+  template <typename ImageCtxT = ImageCtx>
+  static ImageDispatchSpec* create_flush(
+      ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
+      AioCompletion *aio_comp, FlushSource flush_source,
+      const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+                                 image_dispatch_layer, aio_comp, {},
+                                 Flush{flush_source}, {}, 0, parent_trace);
+  }
+
+  template <typename ImageCtxT = ImageCtx>
+  static ImageDispatchSpec* create_list_snaps(
+      ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
+      AioCompletion *aio_comp, Extents &&image_extents, SnapIds&& snap_ids,
+      int list_snaps_flags, SnapshotDelta* snapshot_delta,
+      const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+                                 image_dispatch_layer, aio_comp,
+                                 std::move(image_extents),
+                                 ListSnaps{std::move(snap_ids),
+                                           list_snaps_flags, snapshot_delta},
+                                 {}, 0, parent_trace);
   }
 
   ~ImageDispatchSpec() {
-    m_aio_comp->put();
+    aio_comp->put();
   }
 
   void send();
   void fail(int r);
 
-  bool is_write_op() const;
-
-  void start_op();
-
-  bool tokens_requested(uint64_t flag, uint64_t *tokens);
-
-  bool was_throttled(uint64_t flag) {
-    return m_throttled_flag & flag;
-  }
-
-  void set_throttled(uint64_t flag) {
-    m_throttled_flag |= flag;
-  }
-
-  bool were_all_throttled() {
-    return (m_throttled_flag & RBD_QOS_MASK) == RBD_QOS_MASK;
-  }
-
-  const Extents& get_image_extents() const;
-
-  AioCompletion* get_aio_completion() const {
-    return m_aio_comp;
-  }
-
-  uint64_t get_tid();
-  bool blocked = false;
-
 private:
-  typedef boost::variant<Read,
-                         Discard,
-                         Write,
-                         WriteSame,
-                         CompareAndWrite,
-                         Flush> Request;
-
   struct SendVisitor;
   struct IsWriteOpVisitor;
   struct TokenRequestedVisitor;
 
-  ImageDispatchSpec(ImageCtxT& image_ctx, AioCompletion* aio_comp,
-                     Extents&& image_extents, Request&& request,
-                     int op_flags, const ZTracer::Trace& parent_trace, uint64_t tid)
-    : m_image_ctx(image_ctx), m_aio_comp(aio_comp),
-      m_image_extents(std::move(image_extents)), m_request(std::move(request)),
-      m_op_flags(op_flags), m_parent_trace(parent_trace), m_tid(tid) {
-    m_aio_comp->get();
+  ImageDispatchSpec(ImageDispatcherInterface* image_dispatcher,
+                    ImageDispatchLayer image_dispatch_layer,
+                    AioCompletion* aio_comp, Extents&& image_extents,
+                    Request&& request, IOContext io_context, int op_flags,
+                    const ZTracer::Trace& parent_trace)
+    : dispatcher_ctx(this), image_dispatcher(image_dispatcher),
+      dispatch_layer(image_dispatch_layer), aio_comp(aio_comp),
+      image_extents(std::move(image_extents)), request(std::move(request)),
+      io_context(io_context), op_flags(op_flags), parent_trace(parent_trace) {
+    ceph_assert(aio_comp->image_dispatcher_ctx == nullptr);
+    aio_comp->image_dispatcher_ctx = &dispatcher_ctx;
+    aio_comp->get();
   }
-
-  ImageCtxT& m_image_ctx;
-  AioCompletion* m_aio_comp;
-  Extents m_image_extents;
-  Request m_request;
-  int m_op_flags;
-  ZTracer::Trace m_parent_trace;
-  uint64_t m_tid;
-  std::atomic<uint64_t> m_throttled_flag = 0;
-
-  uint64_t extents_length();
 };
 
 } // namespace io
 } // namespace librbd
 
-extern template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;
-
 #endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H