]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: handle compare_and_write imagerequest in ImageRequestWQ
authorwangzhengyong <wangzhengyong@cmss.chinamobile.com>
Mon, 12 Jun 2017 13:16:14 +0000 (21:16 +0800)
committerJason Dillaman <dillaman@redhat.com>
Wed, 26 Jul 2017 12:00:05 +0000 (08:00 -0400)
Signed-off-by: Zhengyong Wang <wangzhengyong@cmss.chinamobile.com>
src/librbd/io/ImageRequest.cc
src/librbd/io/ImageRequest.h
src/librbd/io/ImageRequestWQ.cc
src/librbd/io/ImageRequestWQ.h
src/librbd/io/Types.h

index 86ea5536adddd21e7f85c5cd2adb5c2440e4a2b3..434c208eefd1b56679988f9f1a1505251d063124 100644 (file)
@@ -150,6 +150,18 @@ ImageRequest<I>* ImageRequest<I>::create_writesame_request(
                                       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,
index 93538f6e3e7239ac8e7d01710ef679c711edd008..9d707a3f8f5f83967d5de46d33eaff54ab2e9a5c 100644 (file)
@@ -57,6 +57,10 @@ public:
                                                 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,
index e80e90088d2a7fd759c1415bc43c21e68a305382..4cc8e0148dd19ab1d57825abb0df9c000b602c7b 100644 (file)
@@ -163,6 +163,37 @@ ssize_t ImageRequestWQ<I>::writesame(uint64_t off, uint64_t len,
   return len;
 }
 
+template <typename I>
+ssize_t ImageRequestWQ<I>::compare_and_write(uint64_t off, uint64_t len,
+                                             bufferlist &&cmp_bl,
+                                             bufferlist &&bl,
+                                             uint64_t *mismatch_off,
+                                             int op_flags){
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << "compare_and_write ictx=" << &m_image_ctx << ", off="
+                 << off << ", " << "len = " << len << dendl;
+
+  m_image_ctx.snap_lock.get_read();
+  int r = clip_io(util::get_image_ctx(&m_image_ctx), off, &len);
+  m_image_ctx.snap_lock.put_read();
+  if (r < 0) {
+    lderr(cct) << "invalid IO request: " << cpp_strerror(r) << dendl;
+    return r;
+  }
+
+  C_SaferCond cond;
+  AioCompletion *c = AioCompletion::create(&cond);
+  aio_compare_and_write(c, off, len, std::move(cmp_bl), std::move(bl),
+                        mismatch_off, op_flags, false);
+
+  r = cond.wait();
+  if (r < 0) {
+    return r;
+  }
+
+  return len;
+}
+
 template <typename I>
 void ImageRequestWQ<I>::aio_read(AioCompletion *c, uint64_t off, uint64_t len,
                                 ReadResult &&read_result, int op_flags,
@@ -347,6 +378,48 @@ void ImageRequestWQ<I>::aio_writesame(AioCompletion *c, uint64_t off,
   trace.event("finish");
 }
 
+template <typename I>
+void ImageRequestWQ<I>::aio_compare_and_write(AioCompletion *c,
+                                              uint64_t off, uint64_t len,
+                                              bufferlist &&cmp_bl,
+                                              bufferlist &&bl,
+                                              uint64_t *mismatch_off,
+                                              int op_flags, bool native_async) {
+  CephContext *cct = m_image_ctx.cct;
+  ZTracer::Trace trace;
+  if (cct->_conf->rbd_blkin_trace_all) {
+    trace.init("wq: compare_and_write", &m_image_ctx.trace_endpoint);
+    trace.event("init");
+  }
+
+  c->init_time(util::get_image_ctx(&m_image_ctx), AIO_TYPE_COMPARE_AND_WRITE);
+  ldout(cct, 20) << "ictx=" << &m_image_ctx << ", "
+                 << "completion=" << c << ", off=" << off << ", "
+                 << "len=" << len << dendl;
+
+  if (native_async && m_image_ctx.event_socket.is_valid()) {
+    c->set_event_notify(true);
+  }
+
+  if (!start_in_flight_io(c)) {
+    return;
+  }
+
+  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(
+            m_image_ctx, c, {{off, len}}, std::move(cmp_bl), std::move(bl),
+            mismatch_off, op_flags, trace));
+  } else {
+    c->start_op();
+    ImageRequest<I>::aio_compare_and_write(&m_image_ctx, c, {{off, len}},
+                                           std::move(cmp_bl), std::move(bl),
+                                           mismatch_off, op_flags, trace);
+    finish_in_flight_io();
+  }
+  trace.event("finish");
+}
+
 template <typename I>
 void ImageRequestWQ<I>::shut_down(Context *on_shutdown) {
   assert(m_image_ctx.owner_lock.is_locked());
index 64f1790f752776df08ee8918430e87940ed82881..ad51b0f2c9f64628cdfac9ab753004a1f82f0088 100644 (file)
@@ -34,6 +34,9 @@ public:
   ssize_t write(uint64_t off, uint64_t len, bufferlist &&bl, int op_flags);
   ssize_t discard(uint64_t off, uint64_t len, bool skip_partial_discard);
   ssize_t writesame(uint64_t off, uint64_t len, bufferlist &&bl, int op_flags);
+  ssize_t compare_and_write(uint64_t off, uint64_t len,
+                            bufferlist &&cmp_bl, bufferlist &&bl,
+                            uint64_t *mismatch_off, int op_flags);
 
   void aio_read(AioCompletion *c, uint64_t off, uint64_t len,
                 ReadResult &&read_result, int op_flags, bool native_async=true);
@@ -44,6 +47,10 @@ public:
   void aio_flush(AioCompletion *c, bool native_async=true);
   void aio_writesame(AioCompletion *c, uint64_t off, uint64_t len,
                      bufferlist &&bl, int op_flags, bool native_async=true);
+  void aio_compare_and_write(AioCompletion *c, uint64_t off,
+                             uint64_t len, bufferlist &&cmp_bl,
+                             bufferlist &&bl, uint64_t *mismatch_off,
+                             int op_flags, bool native_async=true);
 
   using ThreadPool::PointerWQ<ImageRequest<ImageCtxT> >::drain;
 
index 006b222984230fe6229c8ca92a83117dae64b85c..2b69d7bbcf032128e833885050e3cd75791829d9 100644 (file)
@@ -21,6 +21,7 @@ typedef enum {
   AIO_TYPE_DISCARD,
   AIO_TYPE_FLUSH,
   AIO_TYPE_WRITESAME,
+  AIO_TYPE_COMPARE_AND_WRITE,
 } aio_type_t;
 
 enum Direction {