]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: separated queued image IO requests from state machine
authorJason Dillaman <dillaman@redhat.com>
Thu, 15 Feb 2018 15:44:38 +0000 (10:44 -0500)
committerJason Dillaman <dillaman@redhat.com>
Mon, 26 Feb 2018 17:28:25 +0000 (12:28 -0500)
This breaks the tight coupling between the IO work queue and
the actual dispatch of IO requests.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
12 files changed:
src/librbd/CMakeLists.txt
src/librbd/cache/ImageWriteback.cc
src/librbd/io/ImageDispatchSpec.cc [new file with mode: 0644]
src/librbd/io/ImageDispatchSpec.h [new file with mode: 0644]
src/librbd/io/ImageRequest.cc
src/librbd/io/ImageRequest.h
src/librbd/io/ImageRequestWQ.cc
src/librbd/io/ImageRequestWQ.h
src/librbd/journal/Replay.cc
src/test/librbd/io/test_mock_ImageRequest.cc
src/test/librbd/io/test_mock_ImageRequestWQ.cc
src/test/librbd/journal/test_mock_Replay.cc

index 230b7240d3989c7756d1e5e2ae4e75b3ea06d0d7..141f53cd5e5b255aca093e30eb280a34e76e28b4 100644 (file)
@@ -57,6 +57,7 @@ set(librbd_internal_srcs
   io/AioCompletion.cc
   io/AsyncOperation.cc
   io/CopyupRequest.cc
+  io/ImageDispatchSpec.cc
   io/ImageRequest.cc
   io/ImageRequestWQ.cc
   io/ObjectRequest.cc
index d5c9c759c850614b77544bf0b1211eb91ba68629..be366935b36fdf02f9a2c5aa5753d170b69374fb 100644 (file)
@@ -62,7 +62,7 @@ void ImageWriteback<I>::aio_discard(uint64_t offset, uint64_t length,
 
   auto aio_comp = io::AioCompletion::create_and_start(on_finish, &m_image_ctx,
                                                       io::AIO_TYPE_DISCARD);
-  io::ImageDiscardRequest<I> req(m_image_ctx, aio_comp, offset, length,
+  io::ImageDiscardRequest<I> req(m_image_ctx, aio_comp, {{offset, length}},
                                  skip_partial_discard, {});
   req.set_bypass_image_cache();
   req.send();
@@ -92,7 +92,7 @@ void ImageWriteback<I>::aio_writesame(uint64_t offset, uint64_t length,
 
   auto aio_comp = io::AioCompletion::create_and_start(on_finish, &m_image_ctx,
                                                       io::AIO_TYPE_WRITESAME);
-  io::ImageWriteSameRequest<I> req(m_image_ctx, aio_comp, offset, length,
+  io::ImageWriteSameRequest<I> req(m_image_ctx, aio_comp, {{offset, length}},
                                    std::move(bl), fadvise_flags, {});
   req.set_bypass_image_cache();
   req.send();
diff --git a/src/librbd/io/ImageDispatchSpec.cc b/src/librbd/io/ImageDispatchSpec.cc
new file mode 100644 (file)
index 0000000..897617d
--- /dev/null
@@ -0,0 +1,98 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/io/ImageDispatchSpec.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/io/AioCompletion.h"
+#include "librbd/io/ImageRequest.h"
+#include <boost/variant.hpp>
+
+namespace librbd {
+namespace io {
+
+template <typename I>
+struct ImageDispatchSpec<I>::SendVisitor
+  : public boost::static_visitor<void> {
+  ImageDispatchSpec* spec;
+
+  SendVisitor(ImageDispatchSpec* spec)
+    : spec(spec) {
+  }
+
+  void operator()(Read& read) const {
+    ImageRequest<I>::aio_read(
+      &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
+      std::move(read.read_result), spec->m_op_flags, spec->m_parent_trace);
+  }
+
+  void operator()(Discard& discard) const {
+    ImageRequest<I>::aio_discard(
+      &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
+      discard.skip_partial_discard, spec->m_parent_trace);
+  }
+
+  void operator()(Write& write) const {
+    ImageRequest<I>::aio_write(
+      &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
+      std::move(write.bl), spec->m_op_flags, spec->m_parent_trace);
+  }
+
+  void operator()(WriteSame& write_same) const {
+    ImageRequest<I>::aio_writesame(
+      &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
+      std::move(write_same.bl), spec->m_op_flags, spec->m_parent_trace);
+  }
+
+  void operator()(CompareAndWrite& compare_and_write) const {
+    ImageRequest<I>::aio_compare_and_write(
+      &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
+      std::move(compare_and_write.cmp_bl), std::move(compare_and_write.bl),
+      compare_and_write.mismatch_offset, spec->m_op_flags,
+      spec->m_parent_trace);
+  }
+
+  void operator()(Flush& flush) const {
+    ImageRequest<I>::aio_flush(
+      &spec->m_image_ctx, spec->m_aio_comp,
+      spec->m_parent_trace);
+  }
+};
+
+template <typename I>
+struct ImageDispatchSpec<I>::IsWriteOpVisitor
+  : public boost::static_visitor<bool> {
+  bool operator()(const Read&) const {
+    return false;
+  }
+
+  template <typename T>
+  bool operator()(const T&) const {
+    return true;
+  }
+};
+
+template <typename I>
+void ImageDispatchSpec<I>::send() {
+  boost::apply_visitor(SendVisitor{this}, m_request);
+}
+
+template <typename I>
+void ImageDispatchSpec<I>::fail(int r) {
+  m_aio_comp->get();
+  m_aio_comp->fail(r);
+}
+
+template <typename I>
+bool ImageDispatchSpec<I>::is_write_op() const {
+  return boost::apply_visitor(IsWriteOpVisitor{}, m_request);
+}
+
+template <typename I>
+void ImageDispatchSpec<I>::start_op() {
+  m_aio_comp->start_op();
+}
+
+} // namespace io
+} // namespace librbd
+
+template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;
diff --git a/src/librbd/io/ImageDispatchSpec.h b/src/librbd/io/ImageDispatchSpec.h
new file mode 100644 (file)
index 0000000..b8f2319
--- /dev/null
@@ -0,0 +1,170 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H
+#define CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H
+
+#include "include/int_types.h"
+#include "include/buffer.h"
+#include "common/zipkin_trace.h"
+#include "librbd/io/Types.h"
+#include "librbd/io/ReadResult.h"
+#include <boost/variant/variant.hpp>
+
+namespace librbd {
+
+class ImageCtx;
+
+namespace io {
+
+class AioCompletion;
+
+template <typename ImageCtxT = ImageCtx>
+class ImageDispatchSpec {
+public:
+  struct Read {
+    ReadResult read_result;
+
+    Read(ReadResult &&read_result) : read_result(std::move(read_result)) {
+    }
+  };
+
+  struct Discard {
+    bool skip_partial_discard;
+
+    Discard(bool skip_partial_discard)
+      : skip_partial_discard(skip_partial_discard) {
+    }
+  };
+
+  struct Write {
+    bufferlist bl;
+
+    Write(bufferlist&& bl) : bl(std::move(bl)) {
+    }
+  };
+
+  struct WriteSame {
+    bufferlist bl;
+
+    WriteSame(bufferlist&& bl) : bl(std::move(bl)) {
+    }
+  };
+
+  struct CompareAndWrite {
+    bufferlist cmp_bl;
+    bufferlist bl;
+    uint64_t *mismatch_offset;
+
+    CompareAndWrite(bufferlist&& cmp_bl, bufferlist&& bl,
+                    uint64_t *mismatch_offset)
+      : cmp_bl(std::move(cmp_bl)), bl(std::move(bl)),
+        mismatch_offset(mismatch_offset) {
+    }
+  };
+
+  struct Flush {
+  };
+
+  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,
+                                  std::move(image_extents),
+                                  Read{std::move(read_result)},
+                                  op_flags, parent_trace);
+  }
+
+  static ImageDispatchSpec* create_discard_request(
+      ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len,
+      bool skip_partial_discard, const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
+                                  Discard{skip_partial_discard}, 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) {
+    return new ImageDispatchSpec(image_ctx, aio_comp, std::move(image_extents),
+                                  Write{std::move(bl)}, 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) {
+    return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
+                                  WriteSame{std::move(bl)}, op_flags,
+                                  parent_trace);
+  }
+
+  static ImageDispatchSpec* create_compare_and_write_request(
+      ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents,
+      bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset,
+      int op_flags, const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx, aio_comp,
+                                  std::move(image_extents),
+                                  CompareAndWrite{std::move(cmp_bl),
+                                                  std::move(bl),
+                                                  mismatch_offset},
+                                  op_flags, parent_trace);
+  }
+
+  static ImageDispatchSpec* create_flush_request(
+      ImageCtxT &image_ctx, AioCompletion *aio_comp,
+      const ZTracer::Trace &parent_trace) {
+    return new ImageDispatchSpec(image_ctx, aio_comp, {}, Flush{}, 0,
+                                  parent_trace);
+  }
+
+  void send();
+  void fail(int r);
+
+  bool is_write_op() const;
+
+  void start_op();
+
+  bool was_throttled() {
+    return m_throttled;
+  }
+  void set_throttled() {
+    m_throttled = true;
+  }
+
+private:
+  typedef boost::variant<Read,
+                         Discard,
+                         Write,
+                         WriteSame,
+                         CompareAndWrite,
+                         Flush> Request;
+
+  struct SendVisitor;
+  struct IsWriteOpVisitor;
+
+  ImageDispatchSpec(ImageCtxT& image_ctx, AioCompletion* aio_comp,
+                     Extents&& image_extents, Request&& request,
+                     int op_flags, const ZTracer::Trace& parent_trace)
+    : 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) {
+  }
+
+  ImageCtxT& m_image_ctx;
+  AioCompletion* m_aio_comp;
+  Extents m_image_extents;
+  Request m_request;
+  int m_op_flags;
+  ZTracer::Trace m_parent_trace;
+
+  bool m_throttled = false;
+
+};
+
+} // namespace io
+} // namespace librbd
+
+extern template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;
+
+#endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H
index 4b9f540851793505b24bab886aa4e2de4553af3c..0cfc786cbdb36542713f944bacb33daa9a263658 100644 (file)
@@ -81,60 +81,6 @@ struct C_FlushJournalCommit : public Context {
 
 } // anonymous namespace
 
-template <typename I>
-ImageRequest<I>* ImageRequest<I>::create_read_request(
-    I &image_ctx, AioCompletion *aio_comp, Extents &&image_extents,
-    ReadResult &&read_result, int op_flags,
-    const ZTracer::Trace &parent_trace) {
-  return new ImageReadRequest<I>(image_ctx, aio_comp,
-                                 std::move(image_extents),
-                                 std::move(read_result), op_flags,
-                                 parent_trace);
-}
-
-template <typename I>
-ImageRequest<I>* ImageRequest<I>::create_write_request(
-    I &image_ctx, AioCompletion *aio_comp, Extents &&image_extents,
-    bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace) {
-  return new ImageWriteRequest<I>(image_ctx, aio_comp, std::move(image_extents),
-                                  std::move(bl), op_flags, parent_trace);
-}
-
-template <typename I>
-ImageRequest<I>* ImageRequest<I>::create_discard_request(
-    I &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len,
-    bool skip_partial_discard, const ZTracer::Trace &parent_trace) {
-  return new ImageDiscardRequest<I>(image_ctx, aio_comp, off, len,
-                                    skip_partial_discard, parent_trace);
-}
-
-template <typename I>
-ImageRequest<I>* ImageRequest<I>::create_flush_request(
-    I &image_ctx, AioCompletion *aio_comp,
-    const ZTracer::Trace &parent_trace) {
-  return new ImageFlushRequest<I>(image_ctx, aio_comp, parent_trace);
-}
-
-template <typename I>
-ImageRequest<I>* ImageRequest<I>::create_writesame_request(
-    I &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len,
-    bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace) {
-  return new ImageWriteSameRequest<I>(image_ctx, aio_comp, off, len,
-                                      std::move(bl), op_flags, parent_trace);
-}
-
-template <typename I>
-ImageRequest<I>* ImageRequest<I>::create_compare_and_write_request(
-    I &image_ctx, AioCompletion *c, Extents &&image_extents,
-    bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset,
-    int op_flags, const ZTracer::Trace &parent_trace) {
-  return new ImageCompareAndWriteRequest<I>(image_ctx, c,
-                                            std::move(image_extents),
-                                            std::move(cmp_bl),
-                                            std::move(bl), mismatch_offset,
-                                            op_flags, parent_trace);
-}
-
 template <typename I>
 void ImageRequest<I>::aio_read(I *ictx, AioCompletion *c,
                                Extents &&image_extents,
@@ -157,11 +103,11 @@ void ImageRequest<I>::aio_write(I *ictx, AioCompletion *c,
 
 template <typename I>
 void ImageRequest<I>::aio_discard(I *ictx, AioCompletion *c,
-                                  uint64_t off, uint64_t len,
+                                  Extents &&image_extents,
                                   bool skip_partial_discard,
                                  const ZTracer::Trace &parent_trace) {
-  ImageDiscardRequest<I> req(*ictx, c, off, len, skip_partial_discard,
-                            parent_trace);
+  ImageDiscardRequest<I> req(*ictx, c, std::move(image_extents),
+                             skip_partial_discard, parent_trace);
   req.send();
 }
 
@@ -174,11 +120,11 @@ void ImageRequest<I>::aio_flush(I *ictx, AioCompletion *c,
 
 template <typename I>
 void ImageRequest<I>::aio_writesame(I *ictx, AioCompletion *c,
-                                    uint64_t off, uint64_t len,
+                                    Extents &&image_extents,
                                     bufferlist &&bl, int op_flags,
                                    const ZTracer::Trace &parent_trace) {
-  ImageWriteSameRequest<I> req(*ictx, c, off, len, std::move(bl), op_flags,
-                              parent_trace);
+  ImageWriteSameRequest<I> req(*ictx, c, std::move(image_extents),
+                               std::move(bl), op_flags, parent_trace);
   req.send();
 }
 
@@ -237,18 +183,6 @@ int ImageRequest<I>::clip_request() {
   return 0;
 }
 
-template <typename I>
-void ImageRequest<I>::start_op() {
-  m_aio_comp->start_op();
-}
-
-template <typename I>
-void ImageRequest<I>::fail(int r) {
-  AioCompletion *aio_comp = this->m_aio_comp;
-  aio_comp->get();
-  aio_comp->fail(r);
-}
-
 template <typename I>
 ImageReadRequest<I>::ImageReadRequest(I &image_ctx, AioCompletion *aio_comp,
                                       Extents &&image_extents,
index 1abada16b5844a3be7723f3276b8980dfc984a79..a24f566c2303b5bb0b2364a9dc26bfff4ce88f6b 100644 (file)
@@ -33,63 +33,27 @@ public:
     m_trace.event("finish");
   }
 
-  static ImageRequest* create_read_request(ImageCtxT &image_ctx,
-                                           AioCompletion *aio_comp,
-                                           Extents &&image_extents,
-                                           ReadResult &&read_result,
-                                           int op_flags,
-                                           const ZTracer::Trace &parent_trace);
-  static ImageRequest* create_write_request(ImageCtxT &image_ctx,
-                                            AioCompletion *aio_comp,
-                                            Extents &&image_extents,
-                                            bufferlist &&bl, int op_flags,
-                                            const ZTracer::Trace &parent_trace);
-  static ImageRequest* create_discard_request(ImageCtxT &image_ctx,
-                                              AioCompletion *aio_comp,
-                                              uint64_t off, uint64_t len,
-                                              bool skip_partial_discard,
-                                              const ZTracer::Trace &parent_trace);
-  static ImageRequest* create_flush_request(ImageCtxT &image_ctx,
-                                            AioCompletion *aio_comp,
-                                            const ZTracer::Trace &parent_trace);
-  static ImageRequest* create_writesame_request(ImageCtxT &image_ctx,
-                                                AioCompletion *aio_comp,
-                                                uint64_t off, uint64_t len,
-                                                bufferlist &&bl, int op_flags,
-                                                const ZTracer::Trace &parent_trace);
-  static ImageRequest* create_compare_and_write_request(
-      ImageCtxT &image_ctx, AioCompletion *c, Extents &&image_extents,
-      bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset,
-      int op_flags, const ZTracer::Trace &parent_trace);
-
   static void aio_read(ImageCtxT *ictx, AioCompletion *c,
                        Extents &&image_extents, ReadResult &&read_result,
                        int op_flags, const ZTracer::Trace &parent_trace);
   static void aio_write(ImageCtxT *ictx, AioCompletion *c,
                         Extents &&image_extents, bufferlist &&bl, int op_flags,
                        const ZTracer::Trace &parent_trace);
-  static void aio_discard(ImageCtxT *ictx, AioCompletion *c, uint64_t off,
-                          uint64_t len, bool skip_partial_discard,
+  static void aio_discard(ImageCtxT *ictx, AioCompletion *c,
+                          Extents &&image_extents, bool skip_partial_discard,
                          const ZTracer::Trace &parent_trace);
   static void aio_flush(ImageCtxT *ictx, AioCompletion *c,
                        const ZTracer::Trace &parent_trace);
-  static void aio_writesame(ImageCtxT *ictx, AioCompletion *c, uint64_t off,
-                            uint64_t len, bufferlist &&bl, int op_flags,
-                           const ZTracer::Trace &parent_trace);
+  static void aio_writesame(ImageCtxT *ictx, AioCompletion *c,
+                            Extents &&image_extents, bufferlist &&bl,
+                            int op_flags, const ZTracer::Trace &parent_trace);
 
   static void aio_compare_and_write(ImageCtxT *ictx, AioCompletion *c,
                                     Extents &&image_extents, bufferlist &&cmp_bl,
                                     bufferlist &&bl, uint64_t *mismatch_offset,
                                     int op_flags, const ZTracer::Trace &parent_trace);
 
-  virtual bool is_write_op() const {
-    return false;
-  }
-
-  void start_op();
-
   void send();
-  void fail(int r);
 
   void set_bypass_image_cache() {
     m_bypass_image_cache = true;
@@ -99,14 +63,6 @@ public:
     return m_trace;
   }
 
-  bool was_throttled() {
-    return m_throttled;
-  }
-
-  void set_throttled() {
-    m_throttled = true;
-  }
-
 protected:
   typedef std::list<ObjectRequestHandle *> ObjectRequests;
 
@@ -115,7 +71,6 @@ protected:
   Extents m_image_extents;
   ZTracer::Trace m_trace;
   bool m_bypass_image_cache = false;
-  bool m_throttled = false;
 
   ImageRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
                Extents &&image_extents, const char *trace_name,
@@ -125,7 +80,7 @@ protected:
       m_trace(util::create_trace(image_ctx, trace_name, parent_trace)) {
     m_trace.event("start");
   }
-  
+
 
   virtual int clip_request();
   virtual void send_request() = 0;
@@ -163,10 +118,6 @@ private:
 template <typename ImageCtxT = ImageCtx>
 class AbstractImageWriteRequest : public ImageRequest<ImageCtxT> {
 public:
-  bool is_write_op() const override {
-    return true;
-  }
-
   inline void flag_synchronous() {
     m_synchronous = true;
   }
@@ -263,10 +214,10 @@ template <typename ImageCtxT = ImageCtx>
 class ImageDiscardRequest : public AbstractImageWriteRequest<ImageCtxT> {
 public:
   ImageDiscardRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
-                      uint64_t off, uint64_t len, bool skip_partial_discard,
+                      Extents&& image_extents, bool skip_partial_discard,
                      const ZTracer::Trace &parent_trace)
     : AbstractImageWriteRequest<ImageCtxT>(
-       image_ctx, aio_comp, {{off, len}}, "discard", parent_trace),
+       image_ctx, aio_comp, std::move(image_extents), "discard", parent_trace),
       m_skip_partial_discard(skip_partial_discard) {
   }
 
@@ -308,10 +259,6 @@ public:
     : ImageRequest<ImageCtxT>(image_ctx, aio_comp, {}, "flush", parent_trace) {
   }
 
-  bool is_write_op() const override {
-    return true;
-  }
-
 protected:
   using typename ImageRequest<ImageCtxT>::ObjectRequests;
 
@@ -333,10 +280,11 @@ template <typename ImageCtxT = ImageCtx>
 class ImageWriteSameRequest : public AbstractImageWriteRequest<ImageCtxT> {
 public:
   ImageWriteSameRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
-                        uint64_t off, uint64_t len, bufferlist &&bl,
+                        Extents&& image_extents, bufferlist &&bl,
                         int op_flags, const ZTracer::Trace &parent_trace)
     : AbstractImageWriteRequest<ImageCtxT>(
-       image_ctx, aio_comp, {{off, len}}, "writesame", parent_trace),
+       image_ctx, aio_comp, std::move(image_extents), "writesame",
+        parent_trace),
       m_data_bl(std::move(bl)), m_op_flags(op_flags) {
   }
 
index a5a498643fe85096af7060081e45f473cf84f565..0ce9171e59f4a10a104b3d3227ffd5b78f666f54 100644 (file)
@@ -12,6 +12,7 @@
 #include "librbd/exclusive_lock/Policy.h"
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/ImageRequest.h"
+#include "librbd/io/ImageDispatchSpec.h"
 #include "common/EventTrace.h"
 
 #define dout_subsys ceph_subsys_rbd
@@ -25,9 +26,9 @@ namespace io {
 template <typename I>
 struct ImageRequestWQ<I>::C_AcquireLock : public Context {
   ImageRequestWQ *work_queue;
-  ImageRequest<I> *image_request;
+  ImageDispatchSpec<I> *image_request;
 
-  C_AcquireLock(ImageRequestWQ *work_queue, ImageRequest<I> *image_request)
+  C_AcquireLock(ImageRequestWQ *work_queue, ImageDispatchSpec<I> *image_request)
     : work_queue(work_queue), image_request(image_request) {
   }
 
@@ -51,10 +52,10 @@ struct ImageRequestWQ<I>::C_BlockedWrites : public Context {
 template <typename I>
 struct ImageRequestWQ<I>::C_RefreshFinish : public Context {
   ImageRequestWQ *work_queue;
-  ImageRequest<I> *image_request;
+  ImageDispatchSpec<I> *image_request;
 
   C_RefreshFinish(ImageRequestWQ *work_queue,
-                  ImageRequest<I> *image_request)
+                  ImageDispatchSpec<I> *image_request)
     : work_queue(work_queue), image_request(image_request) {
   }
   void finish(int r) override {
@@ -65,7 +66,7 @@ struct ImageRequestWQ<I>::C_RefreshFinish : public Context {
 template <typename I>
 ImageRequestWQ<I>::ImageRequestWQ(I *image_ctx, const string &name,
                                  time_t ti, ThreadPool *tp)
-  : ThreadPool::PointerWQ<ImageRequest<I> >(name, ti, 0, tp),
+  : ThreadPool::PointerWQ<ImageDispatchSpec<I> >(name, ti, 0, tp),
     m_image_ctx(*image_ctx),
     m_lock(util::unique_lock_name("ImageRequestWQ<I>::m_lock", this)) {
   CephContext *cct = m_image_ctx.cct;
@@ -254,7 +255,7 @@ void ImageRequestWQ<I>::aio_read(AioCompletion *c, uint64_t off, uint64_t len,
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
   if (m_image_ctx.non_blocking_aio || writes_blocked() || !writes_empty() ||
       require_lock_on_read()) {
-    queue(ImageRequest<I>::create_read_request(
+    queue(ImageDispatchSpec<I>::create_read_request(
             m_image_ctx, c, {{off, len}}, std::move(read_result), op_flags,
             trace));
   } else {
@@ -293,7 +294,7 @@ void ImageRequestWQ<I>::aio_write(AioCompletion *c, uint64_t off, uint64_t len,
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
   if (m_image_ctx.non_blocking_aio || writes_blocked()) {
-    queue(ImageRequest<I>::create_write_request(
+    queue(ImageDispatchSpec<I>::create_write_request(
             m_image_ctx, c, {{off, len}}, std::move(bl), op_flags, trace));
   } else {
     c->start_op();
@@ -331,11 +332,11 @@ void ImageRequestWQ<I>::aio_discard(AioCompletion *c, uint64_t off,
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
   if (m_image_ctx.non_blocking_aio || writes_blocked()) {
-    queue(ImageRequest<I>::create_discard_request(
+    queue(ImageDispatchSpec<I>::create_discard_request(
             m_image_ctx, c, off, len, skip_partial_discard, trace));
   } else {
     c->start_op();
-    ImageRequest<I>::aio_discard(&m_image_ctx, c, off, len,
+    ImageRequest<I>::aio_discard(&m_image_ctx, c, {{off, len}},
                                 skip_partial_discard, trace);
     finish_in_flight_io();
   }
@@ -366,7 +367,7 @@ void ImageRequestWQ<I>::aio_flush(AioCompletion *c, bool native_async) {
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
   if (m_image_ctx.non_blocking_aio || writes_blocked() || !writes_empty()) {
-    queue(ImageRequest<I>::create_flush_request(m_image_ctx, c, trace));
+    queue(ImageDispatchSpec<I>::create_flush_request(m_image_ctx, c, trace));
   } else {
     ImageRequest<I>::aio_flush(&m_image_ctx, c, trace);
     finish_in_flight_io();
@@ -402,11 +403,11 @@ void ImageRequestWQ<I>::aio_writesame(AioCompletion *c, uint64_t off,
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
   if (m_image_ctx.non_blocking_aio || writes_blocked()) {
-    queue(ImageRequest<I>::create_writesame_request(
+    queue(ImageDispatchSpec<I>::create_write_same_request(
             m_image_ctx, c, off, len, std::move(bl), op_flags, trace));
   } else {
     c->start_op();
-    ImageRequest<I>::aio_writesame(&m_image_ctx, c, off, len, std::move(bl),
+    ImageRequest<I>::aio_writesame(&m_image_ctx, c, {{off, len}}, std::move(bl),
                                   op_flags, trace);
     finish_in_flight_io();
   }
@@ -443,7 +444,7 @@ void ImageRequestWQ<I>::aio_compare_and_write(AioCompletion *c,
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
   if (m_image_ctx.non_blocking_aio || writes_blocked()) {
-    queue(ImageRequest<I>::create_compare_and_write_request(
+    queue(ImageDispatchSpec<I>::create_compare_and_write_request(
             m_image_ctx, c, {{off, len}}, std::move(cmp_bl), std::move(bl),
             mismatch_off, op_flags, trace));
   } else {
@@ -567,8 +568,8 @@ void ImageRequestWQ<I>::apply_qos_iops_limit(uint64_t limit) {
 }
 
 template <typename I>
-void ImageRequestWQ<I>::handle_iops_throttle_ready(int r,
-                                                   ImageRequest<I> *item) {
+void ImageRequestWQ<I>::handle_iops_throttle_ready(
+    int r, ImageDispatchSpec<I> *item) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 15) << "r=" << r << ", " << "req=" << item << dendl;
 
@@ -582,7 +583,7 @@ void ImageRequestWQ<I>::handle_iops_throttle_ready(int r,
 template <typename I>
 void *ImageRequestWQ<I>::_void_dequeue() {
   CephContext *cct = m_image_ctx.cct;
-  ImageRequest<I> *peek_item = this->front();
+  ImageDispatchSpec<I> *peek_item = this->front();
 
   // no queued IO requests or all IO is blocked/stalled
   if (peek_item == nullptr || m_io_blockers.load() > 0) {
@@ -591,12 +592,12 @@ void *ImageRequestWQ<I>::_void_dequeue() {
 
   if (!peek_item->was_throttled() &&
       iops_throttle->get<
-        ImageRequestWQ<I>, ImageRequest<I>,
+        ImageRequestWQ<I>, ImageDispatchSpec<I>,
         &ImageRequestWQ<I>::handle_iops_throttle_ready>(1, this, peek_item)) {
     ldout(cct, 15) << "throttling IO " << peek_item << dendl;
 
     // dequeue the throttled item and block future IO
-    ThreadPool::PointerWQ<ImageRequest<I> >::_void_dequeue();
+    ThreadPool::PointerWQ<ImageDispatchSpec<I> >::_void_dequeue();
     ++m_io_blockers;
     return nullptr;
   }
@@ -620,8 +621,8 @@ void *ImageRequestWQ<I>::_void_dequeue() {
     }
   }
 
-  ImageRequest<I> *item = reinterpret_cast<ImageRequest<I> *>(
-    ThreadPool::PointerWQ<ImageRequest<I> >::_void_dequeue());
+  auto item = reinterpret_cast<ImageDispatchSpec<I> *>(
+    ThreadPool::PointerWQ<ImageDispatchSpec<I> >::_void_dequeue());
   assert(peek_item == item);
 
   if (lock_required) {
@@ -669,7 +670,7 @@ void *ImageRequestWQ<I>::_void_dequeue() {
 }
 
 template <typename I>
-void ImageRequestWQ<I>::process(ImageRequest<I> *req) {
+void ImageRequestWQ<I>::process(ImageDispatchSpec<I> *req) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << "ictx=" << &m_image_ctx << ", "
                  << "req=" << req << dendl;
@@ -686,7 +687,7 @@ void ImageRequestWQ<I>::process(ImageRequest<I> *req) {
 }
 
 template <typename I>
-void ImageRequestWQ<I>::finish_queued_io(ImageRequest<I> *req) {
+void ImageRequestWQ<I>::finish_queued_io(ImageDispatchSpec<I> *req) {
   RWLock::RLocker locker(m_lock);
   if (req->is_write_op()) {
     assert(m_queued_writes > 0);
@@ -750,7 +751,8 @@ void ImageRequestWQ<I>::finish_in_flight_io() {
 }
 
 template <typename I>
-void ImageRequestWQ<I>::fail_in_flight_io(int r, ImageRequest<I> *req) {
+void ImageRequestWQ<I>::fail_in_flight_io(
+    int r, ImageDispatchSpec<I> *req) {
   this->process_finish();
   req->fail(r);
   finish_queued_io(req);
@@ -766,7 +768,7 @@ bool ImageRequestWQ<I>::is_lock_required(bool write_op) const {
 }
 
 template <typename I>
-void ImageRequestWQ<I>::queue(ImageRequest<I> *req) {
+void ImageRequestWQ<I>::queue(ImageDispatchSpec<I> *req) {
   assert(m_image_ctx.owner_lock.is_locked());
 
   CephContext *cct = m_image_ctx.cct;
@@ -779,11 +781,12 @@ void ImageRequestWQ<I>::queue(ImageRequest<I> *req) {
     m_queued_reads++;
   }
 
-  ThreadPool::PointerWQ<ImageRequest<I> >::queue(req);
+  ThreadPool::PointerWQ<ImageDispatchSpec<I> >::queue(req);
 }
 
 template <typename I>
-void ImageRequestWQ<I>::handle_acquire_lock(int r, ImageRequest<I> *req) {
+void ImageRequestWQ<I>::handle_acquire_lock(
+    int r, ImageDispatchSpec<I> *req) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 5) << "r=" << r << ", " << "req=" << req << dendl;
 
@@ -801,7 +804,8 @@ void ImageRequestWQ<I>::handle_acquire_lock(int r, ImageRequest<I> *req) {
 }
 
 template <typename I>
-void ImageRequestWQ<I>::handle_refreshed(int r, ImageRequest<I> *req) {
+void ImageRequestWQ<I>::handle_refreshed(
+    int r, ImageDispatchSpec<I> *req) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 5) << "resuming IO after image refresh: r=" << r << ", "
                 << "req=" << req << dendl;
index fd6bec30dcd8b3992fb48707f38f27b969348067..0d24be182793d8c2cd12257f509d5186b4e28288 100644 (file)
@@ -20,12 +20,12 @@ class ImageCtx;
 namespace io {
 
 class AioCompletion;
-template <typename> class ImageRequest;
+template <typename> class ImageDispatchSpec;
 class ReadResult;
 
 template <typename ImageCtxT = librbd::ImageCtx>
 class ImageRequestWQ
-  : public ThreadPool::PointerWQ<ImageRequest<ImageCtxT> > {
+  : public ThreadPool::PointerWQ<ImageDispatchSpec<ImageCtxT> > {
 public:
   ImageRequestWQ(ImageCtxT *image_ctx, const string &name, time_t ti,
                  ThreadPool *tp);
@@ -55,9 +55,8 @@ public:
                              bufferlist &&bl, uint64_t *mismatch_off,
                              int op_flags, bool native_async=true);
 
-  using ThreadPool::PointerWQ<ImageRequest<ImageCtxT> >::drain;
-
-  using ThreadPool::PointerWQ<ImageRequest<ImageCtxT> >::empty;
+  using ThreadPool::PointerWQ<ImageDispatchSpec<ImageCtxT> >::drain;
+  using ThreadPool::PointerWQ<ImageDispatchSpec<ImageCtxT> >::empty;
 
   void shut_down(Context *on_shutdown);
 
@@ -76,7 +75,7 @@ public:
 
 protected:
   void *_void_dequeue() override;
-  void process(ImageRequest<ImageCtxT> *req) override;
+  void process(ImageDispatchSpec<ImageCtxT> *req) override;
 
 private:
   typedef std::list<Context *> Contexts;
@@ -113,20 +112,20 @@ private:
     return (m_queued_writes == 0);
   }
 
-  void finish_queued_io(ImageRequest<ImageCtxT> *req);
+  void finish_queued_io(ImageDispatchSpec<ImageCtxT> *req);
   void finish_in_flight_write();
 
   int start_in_flight_io(AioCompletion *c);
   void finish_in_flight_io();
-  void fail_in_flight_io(int r, ImageRequest<ImageCtxT> *req);
+  void fail_in_flight_io(int r, ImageDispatchSpec<ImageCtxT> *req);
 
-  void queue(ImageRequest<ImageCtxT> *req);
+  void queue(ImageDispatchSpec<ImageCtxT> *req);
 
-  void handle_acquire_lock(int r, ImageRequest<ImageCtxT> *req);
-  void handle_refreshed(int r, ImageRequest<ImageCtxT> *req);
+  void handle_acquire_lock(int r, ImageDispatchSpec<ImageCtxT> *req);
+  void handle_refreshed(int r, ImageDispatchSpec<ImageCtxT> *req);
   void handle_blocked_writes(int r);
 
-  void handle_iops_throttle_ready(int r, ImageRequest<ImageCtxT> *item);
+  void handle_iops_throttle_ready(int r, ImageDispatchSpec<ImageCtxT> *item);
 };
 
 } // namespace io
index e71b37c58b45b2a0b650fc1fd409d5faba40ef3b..993d6f230b85b995c3db9c6270f5903a5b4e72b5 100644 (file)
@@ -348,9 +348,9 @@ void Replay<I>::handle_event(const journal::AioDiscardEvent &event,
     return;
   }
 
-  io::ImageRequest<I>::aio_discard(&m_image_ctx, aio_comp, event.offset,
-                                   event.length, event.skip_partial_discard,
-                                  {});
+  io::ImageRequest<I>::aio_discard(&m_image_ctx, aio_comp,
+                                   {{event.offset, event.length}},
+                                   event.skip_partial_discard, {});
   if (flush_required) {
     m_lock.Lock();
     auto flush_comp = create_aio_flush_completion(nullptr);
@@ -426,8 +426,9 @@ void Replay<I>::handle_event(const journal::AioWriteSameEvent &event,
     return;
   }
 
-  io::ImageRequest<I>::aio_writesame(&m_image_ctx, aio_comp, event.offset,
-                                     event.length, std::move(data), 0, {});
+  io::ImageRequest<I>::aio_writesame(&m_image_ctx, aio_comp,
+                                     {{event.offset, event.length}},
+                                     std::move(data), 0, {});
   if (flush_required) {
     m_lock.Lock();
     auto flush_comp = create_aio_flush_completion(nullptr);
index e85ae259cd0210a2ff0c81790fb145ac73438c2d..bfea417ef24c82b6f8aaf68df60f2783b2307b88 100644 (file)
@@ -258,7 +258,7 @@ TEST_F(TestMockIoImageRequest, AioDiscardJournalAppendDisabled) {
   AioCompletion *aio_comp = AioCompletion::create_and_start(
     &aio_comp_ctx, ictx, AIO_TYPE_DISCARD);
   MockImageDiscardRequest mock_aio_image_discard(mock_image_ctx, aio_comp,
-                                                 0, 1,
+                                                 {{0, 1}},
                                                  ictx->skip_partial_discard,
                                                  {});
   {
@@ -322,7 +322,7 @@ TEST_F(TestMockIoImageRequest, AioWriteSameJournalAppendDisabled) {
   bufferlist bl;
   bl.append("1");
   MockImageWriteSameRequest mock_aio_image_writesame(mock_image_ctx, aio_comp,
-                                                     0, 1, std::move(bl), 0,
+                                                     {{0, 1}}, std::move(bl), 0,
                                                      {});
   {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
index 47f2182b980fbf4224c7b7aa197913916c424144..77a321dc041b16045f820c493ebb208ddc76d86f 100644 (file)
@@ -5,6 +5,7 @@
 #include "test/librbd/test_support.h"
 #include "test/librbd/mock/MockImageCtx.h"
 #include "test/librbd/mock/exclusive_lock/MockPolicy.h"
+#include "librbd/io/ImageDispatchSpec.h"
 #include "librbd/io/ImageRequestWQ.h"
 #include "librbd/io/ImageRequest.h"
 
@@ -25,20 +26,29 @@ struct ImageRequest<librbd::MockTestImageCtx> {
   static ImageRequest* s_instance;
   AioCompletion *aio_comp = nullptr;
 
-  static ImageRequest* create_write_request(librbd::MockTestImageCtx &image_ctx,
-                                            AioCompletion *aio_comp,
-                                            Extents &&image_extents,
-                                            bufferlist &&bl, int op_flags,
-                                            const ZTracer::Trace &parent_trace) {
-    assert(s_instance != nullptr);
-    s_instance->aio_comp = aio_comp;
-    return s_instance;
-  }
   static void aio_write(librbd::MockTestImageCtx *ictx, AioCompletion *c,
                         Extents &&image_extents, bufferlist &&bl, int op_flags,
                         const ZTracer::Trace &parent_trace) {
   }
 
+  ImageRequest() {
+    s_instance = this;
+  }
+};
+
+template <>
+struct ImageDispatchSpec<librbd::MockTestImageCtx> {
+  static ImageDispatchSpec* s_instance;
+  AioCompletion *aio_comp = nullptr;
+
+  static ImageDispatchSpec* create_write_request(
+      librbd::MockTestImageCtx &image_ctx, AioCompletion *aio_comp,
+      Extents &&image_extents, bufferlist &&bl, int op_flags,
+      const ZTracer::Trace &parent_trace) {
+    assert(s_instance != nullptr);
+    s_instance->aio_comp = aio_comp;
+    return s_instance;
+  }
 
   MOCK_CONST_METHOD0(is_write_op, bool());
   MOCK_CONST_METHOD0(start_op, void());
@@ -47,11 +57,10 @@ struct ImageRequest<librbd::MockTestImageCtx> {
   MOCK_CONST_METHOD0(was_throttled, bool());
   MOCK_CONST_METHOD0(set_throttled, void());
 
-  ImageRequest() {
+  ImageDispatchSpec() {
     s_instance = this;
   }
 };
-
 } // namespace io
 
 namespace util {
@@ -65,8 +74,8 @@ inline ImageCtx *get_image_ctx(MockTestImageCtx *image_ctx) {
 } // namespace librbd
 
 template <>
-struct ThreadPool::PointerWQ<librbd::io::ImageRequest<librbd::MockTestImageCtx>> {
-  typedef librbd::io::ImageRequest<librbd::MockTestImageCtx> ImageRequest;
+struct ThreadPool::PointerWQ<librbd::io::ImageDispatchSpec<librbd::MockTestImageCtx>> {
+  typedef librbd::io::ImageDispatchSpec<librbd::MockTestImageCtx> ImageDispatchSpec;
   static PointerWQ* s_instance;
 
   Mutex m_lock;
@@ -83,11 +92,11 @@ struct ThreadPool::PointerWQ<librbd::io::ImageRequest<librbd::MockTestImageCtx>>
   MOCK_METHOD0(signal, void());
   MOCK_METHOD0(process_finish, void());
 
-  MOCK_METHOD0(front, ImageRequest*());
-  MOCK_METHOD1(requeue, void(ImageRequest*));
+  MOCK_METHOD0(front, ImageDispatchSpec*());
+  MOCK_METHOD1(requeue, void(ImageDispatchSpec*));
 
   MOCK_METHOD0(dequeue, void*());
-  MOCK_METHOD1(queue, void(ImageRequest*));
+  MOCK_METHOD1(queue, void(ImageDispatchSpec*));
 
   void register_work_queue() {
     // no-op
@@ -100,21 +109,23 @@ struct ThreadPool::PointerWQ<librbd::io::ImageRequest<librbd::MockTestImageCtx>>
     Mutex::Locker locker(m_lock);
     return _void_dequeue();
   }
-  void invoke_process(ImageRequest *image_request) {
+  void invoke_process(ImageDispatchSpec *image_request) {
     process(image_request);
   }
 
   virtual void *_void_dequeue() {
     return dequeue();
   }
-  virtual void process(ImageRequest *req) = 0;
+  virtual void process(ImageDispatchSpec *req) = 0;
 
 };
 
-ThreadPool::PointerWQ<librbd::io::ImageRequest<librbd::MockTestImageCtx>>*
-  ThreadPool::PointerWQ<librbd::io::ImageRequest<librbd::MockTestImageCtx>>::s_instance = nullptr;
+ThreadPool::PointerWQ<librbd::io::ImageDispatchSpec<librbd::MockTestImageCtx>>*
+  ThreadPool::PointerWQ<librbd::io::ImageDispatchSpec<librbd::MockTestImageCtx>>::s_instance = nullptr;
 librbd::io::ImageRequest<librbd::MockTestImageCtx>*
   librbd::io::ImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
+librbd::io::ImageDispatchSpec<librbd::MockTestImageCtx>*
+  librbd::io::ImageDispatchSpec<librbd::MockTestImageCtx>::s_instance = nullptr;
 
 #include "librbd/io/ImageRequestWQ.cc"
 
@@ -130,8 +141,10 @@ using ::testing::WithArg;
 struct TestMockIoImageRequestWQ : public TestMockFixture {
   typedef ImageRequestWQ<librbd::MockTestImageCtx> MockImageRequestWQ;
   typedef ImageRequest<librbd::MockTestImageCtx> MockImageRequest;
+  typedef ImageDispatchSpec<librbd::MockTestImageCtx> MockImageDispatchSpec;
 
-  void expect_is_write_op(MockImageRequest &image_request, bool write_op) {
+  void expect_is_write_op(MockImageDispatchSpec &image_request,
+                          bool write_op) {
     EXPECT_CALL(image_request, is_write_op()).WillOnce(Return(write_op));
   }
 
@@ -144,7 +157,7 @@ struct TestMockIoImageRequestWQ : public TestMockFixture {
   }
 
   void expect_front(MockImageRequestWQ &image_request_wq,
-                    MockImageRequest *image_request) {
+                    MockImageDispatchSpec *image_request) {
     EXPECT_CALL(image_request_wq, front()).WillOnce(Return(image_request));
   }
 
@@ -155,7 +168,7 @@ struct TestMockIoImageRequestWQ : public TestMockFixture {
   }
 
   void expect_dequeue(MockImageRequestWQ &image_request_wq,
-                      MockImageRequest *image_request) {
+                      MockImageDispatchSpec *image_request) {
     EXPECT_CALL(image_request_wq, dequeue()).WillOnce(Return(image_request));
   }
 
@@ -182,7 +195,7 @@ struct TestMockIoImageRequestWQ : public TestMockFixture {
     EXPECT_CALL(mock_image_request_wq, process_finish()).Times(1);
   }
 
-  void expect_fail(MockImageRequest &mock_image_request, int r) {
+  void expect_fail(MockImageDispatchSpec &mock_image_request, int r) {
     EXPECT_CALL(mock_image_request, fail(r))
       .WillOnce(Invoke([&mock_image_request](int r) {
                     mock_image_request.aio_comp->get();
@@ -197,7 +210,7 @@ struct TestMockIoImageRequestWQ : public TestMockFixture {
                   }));
   }
 
-  void expect_was_throttled(MockImageRequest &mock_image_request,
+  void expect_was_throttled(MockImageDispatchSpec &mock_image_request,
                             bool throttled) {
     EXPECT_CALL(mock_image_request, was_throttled())
       .WillOnce(Return(throttled));
@@ -219,18 +232,18 @@ TEST_F(TestMockIoImageRequestWQ, AcquireLockError) {
   expect_signal(mock_image_request_wq);
   mock_image_request_wq.set_require_lock(DIRECTION_WRITE, true);
 
-  auto mock_image_request = new MockImageRequest();
-  expect_is_write_op(*mock_image_request, true);
+  auto mock_queued_image_request = new MockImageDispatchSpec();
+  expect_is_write_op(*mock_queued_image_request, true);
   expect_queue(mock_image_request_wq);
   auto *aio_comp = new librbd::io::AioCompletion();
   mock_image_request_wq.aio_write(aio_comp, 0, 0, {}, 0);
 
   librbd::exclusive_lock::MockPolicy mock_exclusive_lock_policy;
-  expect_front(mock_image_request_wq, mock_image_request);
-  expect_was_throttled(*mock_image_request, false);
+  expect_front(mock_image_request_wq, mock_queued_image_request);
+  expect_was_throttled(*mock_queued_image_request, false);
   expect_is_refresh_request(mock_image_ctx, false);
-  expect_is_write_op(*mock_image_request, true);
-  expect_dequeue(mock_image_request_wq, mock_image_request);
+  expect_is_write_op(*mock_queued_image_request, true);
+  expect_dequeue(mock_image_request_wq, mock_queued_image_request);
   expect_get_exclusive_lock_policy(mock_image_ctx, mock_exclusive_lock_policy);
   expect_may_auto_request_lock(mock_exclusive_lock_policy, true);
   Context *on_acquire = nullptr;
@@ -239,8 +252,8 @@ TEST_F(TestMockIoImageRequestWQ, AcquireLockError) {
   ASSERT_TRUE(on_acquire != nullptr);
 
   expect_process_finish(mock_image_request_wq);
-  expect_fail(*mock_image_request, -EPERM);
-  expect_is_write_op(*mock_image_request, true);
+  expect_fail(*mock_queued_image_request, -EPERM);
+  expect_is_write_op(*mock_queued_image_request, true);
   expect_signal(mock_image_request_wq);
   on_acquire->complete(-EPERM);
 
@@ -258,25 +271,25 @@ TEST_F(TestMockIoImageRequestWQ, RefreshError) {
   InSequence seq;
   MockImageRequestWQ mock_image_request_wq(&mock_image_ctx, "io", 60, nullptr);
 
-  auto mock_image_request = new MockImageRequest();
-  expect_is_write_op(*mock_image_request, true);
+  auto mock_queued_image_request = new MockImageDispatchSpec();
+  expect_is_write_op(*mock_queued_image_request, true);
   expect_queue(mock_image_request_wq);
   auto *aio_comp = new librbd::io::AioCompletion();
   mock_image_request_wq.aio_write(aio_comp, 0, 0, {}, 0);
 
-  expect_front(mock_image_request_wq, mock_image_request);
-  expect_was_throttled(*mock_image_request, false);
+  expect_front(mock_image_request_wq, mock_queued_image_request);
+  expect_was_throttled(*mock_queued_image_request, false);
   expect_is_refresh_request(mock_image_ctx, true);
-  expect_is_write_op(*mock_image_request, true);
-  expect_dequeue(mock_image_request_wq, mock_image_request);
+  expect_is_write_op(*mock_queued_image_request, true);
+  expect_dequeue(mock_image_request_wq, mock_queued_image_request);
   Context *on_refresh = nullptr;
   expect_refresh(mock_image_ctx, &on_refresh);
   ASSERT_TRUE(mock_image_request_wq.invoke_dequeue() == nullptr);
   ASSERT_TRUE(on_refresh != nullptr);
 
   expect_process_finish(mock_image_request_wq);
-  expect_fail(*mock_image_request, -EPERM);
-  expect_is_write_op(*mock_image_request, true);
+  expect_fail(*mock_queued_image_request, -EPERM);
+  expect_is_write_op(*mock_queued_image_request, true);
   expect_signal(mock_image_request_wq);
   on_refresh->complete(-EPERM);
 
index 914f4552a0f8a4b0a38db1995175f1adeee287dd..4e91bb564b797fdc635f9a0eaafa4a82c888485c 100644 (file)
@@ -37,14 +37,13 @@ struct ImageRequest<MockReplayImageCtx> {
     s_instance->aio_write(c, image_extents, bl, op_flags);
   }
 
-  MOCK_METHOD4(aio_discard, void(AioCompletion *c, uint64_t off, uint64_t len,
+  MOCK_METHOD3(aio_discard, void(AioCompletion *c, const Extents& image_extents,
                                  bool skip_partial_discard));
   static void aio_discard(MockReplayImageCtx *ictx, AioCompletion *c,
-                          uint64_t off, uint64_t len,
-                          bool skip_partial_discard,
+                          Extents&& image_extents, bool skip_partial_discard,
                           const ZTracer::Trace &parent_trace) {
     assert(s_instance != nullptr);
-    s_instance->aio_discard(c, off, len, skip_partial_discard);
+    s_instance->aio_discard(c, image_extents, skip_partial_discard);
   }
 
   MOCK_METHOD1(aio_flush, void(AioCompletion *c));
@@ -54,13 +53,14 @@ struct ImageRequest<MockReplayImageCtx> {
     s_instance->aio_flush(c);
   }
 
-  MOCK_METHOD5(aio_writesame, void(AioCompletion *c, uint64_t off, uint64_t len,
+  MOCK_METHOD4(aio_writesame, void(AioCompletion *c,
+                                   const Extents& image_extents,
                                    const bufferlist &bl, int op_flags));
   static void aio_writesame(MockReplayImageCtx *ictx, AioCompletion *c,
-                            uint64_t off, uint64_t len, bufferlist &&bl,
+                            Extents&& image_extents, bufferlist &&bl,
                             int op_flags, const ZTracer::Trace &parent_trace) {
     assert(s_instance != nullptr);
-    s_instance->aio_writesame(c, off, len, bl, op_flags);
+    s_instance->aio_writesame(c, image_extents, bl, op_flags);
   }
 
   MOCK_METHOD6(aio_compare_and_write, void(AioCompletion *c, const Extents &image_extents,
@@ -148,7 +148,8 @@ public:
   void expect_aio_discard(MockIoImageRequest &mock_io_image_request,
                           io::AioCompletion **aio_comp, uint64_t off,
                           uint64_t len, bool skip_partial_discard) {
-    EXPECT_CALL(mock_io_image_request, aio_discard(_, off, len, skip_partial_discard))
+    EXPECT_CALL(mock_io_image_request, aio_discard(_, io::Extents{{off, len}},
+                                                   skip_partial_discard))
                   .WillOnce(SaveArg<0>(aio_comp));
   }
 
@@ -176,17 +177,21 @@ public:
                             io::AioCompletion **aio_comp, uint64_t off,
                             uint64_t len, const char *data) {
     EXPECT_CALL(mock_io_image_request,
-                aio_writesame(_, off, len, BufferlistEqual(data), _))
+                aio_writesame(_, io::Extents{{off, len}},
+                              BufferlistEqual(data), _))
                   .WillOnce(SaveArg<0>(aio_comp));
   }
 
   void expect_aio_compare_and_write(MockIoImageRequest &mock_io_image_request,
                                     io::AioCompletion **aio_comp, uint64_t off,
-                                    uint64_t len, const char *cmp_data, const char *data,
+                                    uint64_t len, const char *cmp_data,
+                                    const char *data,
                                     uint64_t *mismatch_offset) {
     EXPECT_CALL(mock_io_image_request,
                 aio_compare_and_write(_, io::Extents{{off, len}},
-                  BufferlistEqual(cmp_data), BufferlistEqual(data), mismatch_offset, _))
+                                      BufferlistEqual(cmp_data),
+                                      BufferlistEqual(data),
+                                      mismatch_offset, _))
                   .WillOnce(SaveArg<0>(aio_comp));
   }